From f71cc26c15fb08193f36d88baa0498dce4e53487 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 7 Nov 2015 15:35:03 +0100 Subject: [PATCH 001/511] Add a filename arg to PEImage byte[] ctors --- src/PE/PEImage.cs | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index 10a4ab1c0..495c6b4bf 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -192,6 +192,17 @@ public PEImage(string fileName) : this(fileName, true) { } + /// + /// Constructor + /// + /// The PE file data + /// Filename or null + /// Image layout + /// Verify PE file data + public PEImage(byte[] data, string filename, ImageLayout imageLayout, bool verify) + : this(new MemoryStreamCreator(data) { FileName = filename }, imageLayout, verify) { + } + /// /// Constructor /// @@ -199,7 +210,7 @@ public PEImage(string fileName) /// Image layout /// Verify PE file data public PEImage(byte[] data, ImageLayout imageLayout, bool verify) - : this(new MemoryStreamCreator(data), imageLayout, verify) { + : this(data, null, imageLayout, verify) { } /// @@ -208,7 +219,17 @@ public PEImage(byte[] data, ImageLayout imageLayout, bool verify) /// The PE file data /// Verify PE file data public PEImage(byte[] data, bool verify) - : this(data, ImageLayout.File, verify) { + : this(data, null, ImageLayout.File, verify) { + } + + /// + /// Constructor + /// + /// The PE file data + /// Filename or null + /// Verify PE file data + public PEImage(byte[] data, string filename, bool verify) + : this(data, filename, ImageLayout.File, verify) { } /// @@ -216,7 +237,16 @@ public PEImage(byte[] data, bool verify) /// /// The PE file data public PEImage(byte[] data) - : this(data, true) { + : this(data, null, true) { + } + + /// + /// Constructor + /// + /// The PE file data + /// Filename or null + public PEImage(byte[] data, string filename) + : this(data, filename, true) { } /// From fafbdf5e9d62ea2d1cdee827b529a9da96a9aa8d Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 3 Dec 2015 23:54:48 +0100 Subject: [PATCH 002/511] Update asm resolver: include culture, update paths --- src/DotNet/AssemblyResolver.cs | 36 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index b46c70c78..aa465a194 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -45,16 +45,16 @@ public class AssemblyResolver : IAssemblyResolver { #endif sealed class GacInfo { - public readonly int version; - public readonly string path; - public readonly string prefix; - public readonly IList subDirs; + public readonly int Version; + public readonly string Path; + public readonly string Prefix; + public readonly IList SubDirs; public GacInfo(int version, string prefix, string path, IList subDirs) { - this.version = version; - this.prefix = prefix; - this.path = path; - this.subDirs = subDirs; + this.Version = version; + this.Prefix = prefix; + this.Path = path; + this.SubDirs = subDirs; } } @@ -528,11 +528,11 @@ IEnumerable GetGacInfos(ModuleDef sourceModule) { int version = sourceModule == null ? int.MinValue : sourceModule.IsClr40 ? 4 : 2; // Try the correct GAC first (eg. GAC4 if it's a .NET 4 assembly) foreach (var gacInfo in gacInfos) { - if (gacInfo.version == version) + if (gacInfo.Version == version) yield return gacInfo; } foreach (var gacInfo in gacInfos) { - if (gacInfo.version != version) + if (gacInfo.Version != version) yield return gacInfo; } } @@ -563,11 +563,14 @@ IEnumerable FindAssembliesGacExactly(GacInfo gacInfo, IAssembly assembly if (gacInfo != null && pkt != null) { string pktString = pkt.ToString(); string verString = Utils.CreateVersionWithNoUndefinedValues(assembly.Version).ToString(); + var cultureString = UTF8String.ToSystemStringOrEmpty(assembly.Culture); + if (cultureString.Equals("neutral", StringComparison.OrdinalIgnoreCase)) + cultureString = string.Empty; var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); - foreach (var subDir in gacInfo.subDirs) { - var baseDir = Path.Combine(gacInfo.path, subDir); + foreach (var subDir in gacInfo.SubDirs) { + var baseDir = Path.Combine(gacInfo.Path, subDir); baseDir = Path.Combine(baseDir, asmSimpleName); - baseDir = Path.Combine(baseDir, string.Format("{0}{1}__{2}", gacInfo.prefix, verString, pktString)); + baseDir = Path.Combine(baseDir, string.Format("{0}{1}_{2}_{3}", gacInfo.Prefix, verString, cultureString, pktString)); var pathName = Path.Combine(baseDir, asmSimpleName + ".dll"); if (File.Exists(pathName)) yield return pathName; @@ -589,8 +592,8 @@ IEnumerable FindAssembliesGacAny(IAssembly assembly, ModuleDef sourceMod IEnumerable FindAssembliesGacAny(GacInfo gacInfo, IAssembly assembly, ModuleDef sourceModule) { if (gacInfo != null) { var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); - foreach (var subDir in gacInfo.subDirs) { - var baseDir = Path.Combine(gacInfo.path, subDir); + foreach (var subDir in gacInfo.SubDirs) { + var baseDir = Path.Combine(gacInfo.Path, subDir); baseDir = Path.Combine(baseDir, asmSimpleName); foreach (var dir in GetDirs(baseDir)) { var pathName = Path.Combine(dir, asmSimpleName + ".dll"); @@ -761,6 +764,7 @@ static void AddOtherAssemblySearchPaths(IList paths, string path) { AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v5.0\Libraries\Server"); AddIfExists(paths, path, @"Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE"); AddIfExists(paths, path, @"Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE"); + AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1"); @@ -768,6 +772,7 @@ static void AddOtherAssemblySearchPaths(IList paths, string path) { AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client"); + AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETCore\v5.0"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.1"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETMicroFramework\v3.0"); @@ -778,6 +783,7 @@ static void AddOtherAssemblySearchPaths(IList paths, string path) { AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v4.6"); + AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v5.0"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\v3.0"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\v3.5"); AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v3.0"); From 99d3a16f2ac5d5a3658572b23e8ea2d5509af8e4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 12 Jan 2016 17:39:17 +0100 Subject: [PATCH 003/511] Pass in TypeRef's module to Resolve() if sourceModule is null --- src/DotNet/TypeRef.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index 9d9bffeb9..893eb70c6 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -308,7 +308,7 @@ public TypeDef Resolve() { public TypeDef Resolve(ModuleDef sourceModule) { if (module == null) return null; - return module.Context.Resolver.Resolve(this, sourceModule); + return module.Context.Resolver.Resolve(this, sourceModule ?? module); } /// From 7db319ae9ce14160f4484e810f58ed6a814cdb2a Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 12 Jan 2016 17:39:49 +0100 Subject: [PATCH 004/511] Move ResolveToken(int) to base class --- src/DotNet/ModuleDef.cs | 19 +++++++++++++++++++ src/DotNet/ModuleDefMD.cs | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index b8837a04f..b071c64ea 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1402,6 +1402,25 @@ public IMDTokenProvider ResolveToken(MDToken mdToken, GenericParamContext gpCont return ResolveToken(mdToken.Raw, gpContext); } + /// + /// Resolves a token + /// + /// The metadata token + /// A or null if is invalid + public IMDTokenProvider ResolveToken(int token) { + return ResolveToken((uint)token, new GenericParamContext()); + } + + /// + /// Resolves a token + /// + /// The metadata token + /// Generic parameter context + /// A or null if is invalid + public IMDTokenProvider ResolveToken(int token, GenericParamContext gpContext) { + return ResolveToken((uint)token, gpContext); + } + /// /// Resolves a token /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 79334ad6a..0273c2bbd 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -702,25 +702,6 @@ protected override void Dispose(bool disposing) { } } - /// - /// Resolves a token - /// - /// The metadata token - /// A or null if is invalid - public IMDTokenProvider ResolveToken(int token) { - return ResolveToken((uint)token, new GenericParamContext()); - } - - /// - /// Resolves a token - /// - /// The metadata token - /// Generic parameter context - /// A or null if is invalid - public IMDTokenProvider ResolveToken(int token, GenericParamContext gpContext) { - return ResolveToken((uint)token, gpContext); - } - /// /// Resolves a token /// From 87eb9708db7d3cb0b895104c7b0a19a6034ded6b Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 12 Jan 2016 17:40:08 +0100 Subject: [PATCH 005/511] Add UseGAC to AssemblyResolver --- src/DotNet/AssemblyResolver.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index aa465a194..6e26490a6 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -40,6 +40,7 @@ public class AssemblyResolver : IAssemblyResolver { bool findExactMatch; bool enableFrameworkRedirect; bool enableTypeDefCache; + bool useGac = true; #if THREAD_SAFE readonly Lock theLock = Lock.Create(); #endif @@ -173,6 +174,14 @@ public bool EnableTypeDefCache { set { enableTypeDefCache = value; } } + /// + /// true to search the Global Assembly Cache. Default value is true. + /// + public bool UseGAC { + get { return useGac; } + set { useGac = value; } + } + /// /// Gets paths searched before trying the standard locations /// @@ -511,8 +520,10 @@ protected virtual IEnumerable FindAssemblies(IAssembly assembly, ModuleD yield return path; } else { - foreach (var path in FindAssembliesGac(assembly, sourceModule, matchExactly)) - yield return path; + if (UseGAC) { + foreach (var path in FindAssembliesGac(assembly, sourceModule, matchExactly)) + yield return path; + } } foreach (var path in FindAssembliesModuleSearchPaths(assembly, sourceModule, matchExactly)) yield return path; From a01a2207cacf1d86343db94bcfd3fee3c97636dc Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 13 Jan 2016 05:48:19 +0100 Subject: [PATCH 006/511] Don't add dupe prop/evt defs --- src/DotNet/Writer/PreserveTokensMetaData.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/PreserveTokensMetaData.cs b/src/DotNet/Writer/PreserveTokensMetaData.cs index f9e0904a0..99c3b129f 100644 --- a/src/DotNet/Writer/PreserveTokensMetaData.cs +++ b/src/DotNet/Writer/PreserveTokensMetaData.cs @@ -883,6 +883,7 @@ uint CreateDummyPtrTableType() { uint dummyPtrTableTypeRid; void FindMemberDefs() { + var added = new Dictionary(); int pos; foreach (var type in allTypeDefs) { if (type == null) @@ -904,15 +905,17 @@ void FindMemberDefs() { pos = 0; foreach (var evt in type.Events) { - if (evt == null) + if (evt == null || added.ContainsKey(evt)) continue; + added[evt] = true; eventDefInfos.Add(evt, pos++); } pos = 0; foreach (var prop in type.Properties) { - if (prop == null) + if (prop == null || added.ContainsKey(prop)) continue; + added[prop] = true; propertyDefInfos.Add(prop, pos++); } } From b73318e016c317fef431c6b353c6d7fe7342d494 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 13 Jan 2016 05:48:32 +0100 Subject: [PATCH 007/511] Add DelaySign writer option --- src/DotNet/Writer/ModuleWriterBase.cs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 2163a78c3..49f625471 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using dnlib.IO; @@ -8,6 +8,7 @@ using dnlib.PE; using dnlib.W32Resources; using dnlib.DotNet.MD; +using System.Diagnostics; namespace dnlib.DotNet.Writer { /// @@ -23,6 +24,7 @@ public class ModuleWriterOptionsBase { Win32Resources win32Resources; StrongNameKey strongNameKey; StrongNamePublicKey strongNamePublicKey; + bool delaySign; /// /// Gets/sets the listener @@ -84,6 +86,16 @@ public Win32Resources Win32Resources { set { win32Resources = value; } } + /// + /// true to delay sign the assembly. Initialize to the + /// public key to use, and don't initialize . To generate the + /// public key from your strong name key file, execute sn -p mykey.snk mypublickey.snk + /// + public bool DelaySign { + get { return delaySign; } + set { delaySign = value; } + } + /// /// Gets/sets the strong name key. When you enhance strong name sign an assembly, /// this instance's HashAlgorithm must be initialized to its public key's HashAlgorithm. @@ -492,7 +504,12 @@ static void DeleteFileNoThrow(string fileName) { /// /// Destination stream public void Write(Stream dest) { - if (TheOptions.StrongNameKey != null || TheOptions.StrongNamePublicKey != null) + if (TheOptions.DelaySign) { + Debug.Assert(TheOptions.StrongNamePublicKey != null, "Options.StrongNamePublicKey must be initialized when delay signing the assembly"); + Debug.Assert(TheOptions.StrongNameKey == null, "Options.StrongNameKey must be null when delay signing the assembly"); + TheOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.StrongNameSigned; + } + else if (TheOptions.StrongNameKey != null || TheOptions.StrongNamePublicKey != null) TheOptions.Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; Listener = TheOptions.Listener ?? DummyModuleWriterListener.Instance; @@ -521,7 +538,11 @@ public void Write(Stream dest) { /// set or wants to sign the assembly. /// protected void CreateStrongNameSignature() { - if (TheOptions.StrongNameKey != null) + if (TheOptions.DelaySign && TheOptions.StrongNamePublicKey != null) { + int len = TheOptions.StrongNamePublicKey.CreatePublicKey().Length - 0x20; + strongNameSignature = new StrongNameSignature(len > 0 ? len : 0x80); + } + else if (TheOptions.StrongNameKey != null) strongNameSignature = new StrongNameSignature(TheOptions.StrongNameKey.SignatureSize); else if (Module.Assembly != null && !PublicKeyBase.IsNullOrEmpty2(Module.Assembly.PublicKey)) { int len = Module.Assembly.PublicKey.Data.Length - 0x20; From b1644907757f9d0523e4ca80e9512e11312477bc Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 13 Jan 2016 05:50:05 +0100 Subject: [PATCH 008/511] Add more Local ctors --- src/DotNet/Emit/LocalList.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/DotNet/Emit/LocalList.cs b/src/DotNet/Emit/LocalList.cs index 14d237cb8..9290833d9 100644 --- a/src/DotNet/Emit/LocalList.cs +++ b/src/DotNet/Emit/LocalList.cs @@ -271,6 +271,28 @@ public Local(TypeSig typeSig) { this.typeSig = typeSig; } + /// + /// Constructor + /// + /// The type + /// Name of local + public Local(TypeSig typeSig, string name) { + this.typeSig = typeSig; + this.name = name; + } + + /// + /// Constructor + /// + /// The type + /// Name of local + /// Index, should only be used if you don't add it to the locals list + public Local(TypeSig typeSig, string name, int index) { + this.typeSig = typeSig; + this.name = name; + this.index = index; + } + /// public override string ToString() { var n = name; From 525cbb5350cbf89d1cdc9d9da34b985dfbeccef6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 14 Jan 2016 02:22:20 +0100 Subject: [PATCH 009/511] AssemblyResolver.EnableTypeDefCache is now enabled by default --- src/DotNet/AssemblyResolver.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 6e26490a6..c5ea343e3 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -39,7 +39,7 @@ public class AssemblyResolver : IAssemblyResolver { readonly ThreadSafe.IList postSearchPaths = ThreadSafeListCreator.Create(); bool findExactMatch; bool enableFrameworkRedirect; - bool enableTypeDefCache; + bool enableTypeDefCache = true; bool useGac = true; #if THREAD_SAFE readonly Lock theLock = Lock.Create(); @@ -167,7 +167,8 @@ public bool EnableFrameworkRedirect { /// /// If true, all modules in newly resolved assemblies will have their - /// property set to true. + /// property set to true. This is + /// enabled by default since these modules shouldn't be modified by the user. /// public bool EnableTypeDefCache { get { return enableTypeDefCache; } From b00b605b62d3ab1ebe527f135a3983b1db08e7d9 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 29 Feb 2016 21:53:14 +0100 Subject: [PATCH 010/511] Allow passing in StringBuilder to FullNameCreator methods --- src/DotNet/CallingConventionSig.cs | 6 +- src/DotNet/Emit/InstructionPrinter.cs | 2 +- src/DotNet/EventDef.cs | 2 +- src/DotNet/ExportedType.cs | 14 +- src/DotNet/FieldDef.cs | 2 +- src/DotNet/FullNameCreator.cs | 917 +++++++++++++++++++++++--- src/DotNet/ICodedToken.cs | 39 +- src/DotNet/MemberRef.cs | 4 +- src/DotNet/MethodDef.cs | 2 +- src/DotNet/MethodSpec.cs | 4 +- src/DotNet/PropertyDef.cs | 2 +- src/DotNet/TypeDef.cs | 82 ++- src/DotNet/TypeDefFinder.cs | 30 +- src/DotNet/TypeRef.cs | 14 +- src/DotNet/TypeSig.cs | 16 +- src/DotNet/TypeSpec.cs | 14 +- src/DotNet/UTF8String.cs | 2 +- 17 files changed, 975 insertions(+), 177 deletions(-) diff --git a/src/DotNet/CallingConventionSig.cs b/src/DotNet/CallingConventionSig.cs index 7f825f6a1..b78e8f2d3 100644 --- a/src/DotNet/CallingConventionSig.cs +++ b/src/DotNet/CallingConventionSig.cs @@ -263,7 +263,7 @@ public FieldSig Clone() { /// public override string ToString() { - return FullNameCreator.FullName(type == null ? null : type, false); + return FullNameCreator.FullName(type == null ? null : type, false, null, null, null, null); } } @@ -672,7 +672,7 @@ public MethodSig Clone() { /// public override string ToString() { - return FullNameCreator.MethodSigFullName(this); + return FullNameCreator.MethodBaseSigFullName(this, null); } } @@ -887,7 +887,7 @@ public PropertySig Clone() { /// public override string ToString() { - return FullNameCreator.PropertySigFullName(this); + return FullNameCreator.MethodBaseSigFullName(this, null); } } diff --git a/src/DotNet/Emit/InstructionPrinter.cs b/src/DotNet/Emit/InstructionPrinter.cs index ddeb722a3..00163a1fc 100644 --- a/src/DotNet/Emit/InstructionPrinter.cs +++ b/src/DotNet/Emit/InstructionPrinter.cs @@ -86,7 +86,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string case OperandType.InlineSig: sb.Append(extra); - sb.Append(FullNameCreator.MethodFullName(null, (UTF8String)null, op as MethodSig)); + sb.Append(FullNameCreator.MethodFullName(null, (UTF8String)null, op as MethodSig, null, null, null, null)); break; case OperandType.InlineString: diff --git a/src/DotNet/EventDef.cs b/src/DotNet/EventDef.cs index 45b65afec..65712adba 100644 --- a/src/DotNet/EventDef.cs +++ b/src/DotNet/EventDef.cs @@ -257,7 +257,7 @@ public ModuleDef Module { public string FullName { get { var dt = declaringType2; - return FullNameCreator.EventFullName(dt == null ? null : dt.FullName, name, eventType); + return FullNameCreator.EventFullName(dt == null ? null : dt.FullName, name, eventType, null, null); } } diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index b812a709d..1c4b4a11c 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -82,7 +82,7 @@ public bool IsPrimitive { /// string IType.TypeName { - get { return FullNameCreator.Name(this, false); } + get { return FullNameCreator.Name(this, false, null); } } /// @@ -93,32 +93,32 @@ public UTF8String Name { /// public string ReflectionName { - get { return FullNameCreator.Name(this, true); } + get { return FullNameCreator.Name(this, true, null); } } /// public string Namespace { - get { return FullNameCreator.Namespace(this, false); } + get { return FullNameCreator.Namespace(this, false, null); } } /// public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true); } + get { return FullNameCreator.Namespace(this, true, null); } } /// public string FullName { - get { return FullNameCreator.FullName(this, false); } + get { return FullNameCreator.FullName(this, false, null, null); } } /// public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true); } + get { return FullNameCreator.FullName(this, true, null, null); } } /// public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this); } + get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } } /// diff --git a/src/DotNet/FieldDef.cs b/src/DotNet/FieldDef.cs index 358126a26..4596d34f3 100644 --- a/src/DotNet/FieldDef.cs +++ b/src/DotNet/FieldDef.cs @@ -717,7 +717,7 @@ public bool HasFieldRVA { public string FullName { get { var dt = declaringType2; - return FullNameCreator.FieldFullName(dt == null ? null : dt.FullName, name, FieldSig); + return FullNameCreator.FieldFullName(dt == null ? null : dt.FullName, name, FieldSig, null, null); } } diff --git a/src/DotNet/FullNameCreator.cs b/src/DotNet/FullNameCreator.cs index a2fa73245..93c00feea 100644 --- a/src/DotNet/FullNameCreator.cs +++ b/src/DotNet/FullNameCreator.cs @@ -58,13 +58,126 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type) { return module.Find(tr) != null; } + /// + /// Returns the full name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static string FullName(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + return FullNameSB(type, isReflection, helper, sb).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static StringBuilder FullNameSB(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + var td = type as TypeDef; + if (td != null) + return FullNameSB(td, isReflection, helper, sb); + var tr = type as TypeRef; + if (tr != null) + return FullNameSB(tr, isReflection, helper, sb); + var ts = type as TypeSpec; + if (ts != null) + return FullNameSB(ts, isReflection, helper, sb); + var sig = type as TypeSig; + if (sig != null) + return FullNameSB(sig, isReflection, helper, null, null, sb); + var et = type as ExportedType; + if (et != null) + return FullNameSB(et, isReflection, helper, sb); + return sb ?? new StringBuilder(); + } + + /// + /// Returns the name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The full name + public static string Name(IType type, bool isReflection, StringBuilder sb) { + return NameSB(type, isReflection, sb).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The full name + public static StringBuilder NameSB(IType type, bool isReflection, StringBuilder sb) { + var td = type as TypeDef; + if (td != null) + return NameSB(td, isReflection, sb); + var tr = type as TypeRef; + if (tr != null) + return NameSB(tr, isReflection, sb); + var ts = type as TypeSpec; + if (ts != null) + return NameSB(ts, isReflection, sb); + var sig = type as TypeSig; + if (sig != null) + return NameSB(sig, false, sb); + var et = type as ExportedType; + if (et != null) + return NameSB(et, isReflection, sb); + return sb ?? new StringBuilder(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The full name + public static string Namespace(IType type, bool isReflection, StringBuilder sb) { + return NamespaceSB(type, isReflection, sb).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The full name + public static StringBuilder NamespaceSB(IType type, bool isReflection, StringBuilder sb) { + var td = type as TypeDef; + if (td != null) + return NamespaceSB(td, isReflection, sb); + var tr = type as TypeRef; + if (tr != null) + return NamespaceSB(tr, isReflection, sb); + var ts = type as TypeSpec; + if (ts != null) + return NamespaceSB(ts, isReflection, sb); + var sig = type as TypeSig; + if (sig != null) + return NamespaceSB(sig, false, sb); + var et = type as ExportedType; + if (et != null) + return NamespaceSB(et, isReflection, sb); + return sb ?? new StringBuilder(); + } + /// /// Returns the assembly qualified full name of a /// /// The IType /// The assembly qualified full name public static string AssemblyQualifiedName(IType type) { - return AssemblyQualifiedName(type, null); + return AssemblyQualifiedNameSB(type, null, null).ToString(); } /// @@ -74,27 +187,49 @@ public static string AssemblyQualifiedName(IType type) { /// Helps print the name /// The assembly qualified full name public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper) { + return AssemblyQualifiedNameSB(type, helper, null).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The IType + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper, StringBuilder sb) { + return AssemblyQualifiedNameSB(type, helper, sb).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The IType + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static StringBuilder AssemblyQualifiedNameSB(IType type, IFullNameCreatorHelper helper, StringBuilder sb) { var td = type as TypeDef; if (td != null) - return AssemblyQualifiedName(td, helper); + return AssemblyQualifiedNameSB(td, helper, sb); var tr = type as TypeRef; if (tr != null) - return AssemblyQualifiedName(tr, helper); + return AssemblyQualifiedNameSB(tr, helper, sb); var ts = type as TypeSpec; if (ts != null) - return AssemblyQualifiedName(ts, helper); + return AssemblyQualifiedNameSB(ts, helper, sb); var sig = type as TypeSig; if (sig != null) - return AssemblyQualifiedName(sig, helper); + return AssemblyQualifiedNameSB(sig, helper, sb); var et = type as ExportedType; if (et != null) - return AssemblyQualifiedName(et, helper); + return AssemblyQualifiedNameSB(et, helper, sb); - return string.Empty; + return sb ?? new StringBuilder(); } /// @@ -105,7 +240,7 @@ public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper he /// Property signature /// Property full name public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig) { - return PropertyFullName(declaringType, name, propertySig, null); + return PropertyFullNameSB(declaringType, name, propertySig, null, null).ToString(); } /// @@ -117,14 +252,40 @@ public static string PropertyFullName(string declaringType, UTF8String name, Cal /// Type generic arguments or null if none /// Property full name public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs) { - var fnc = new FullNameCreator(false, null); + return PropertyFullNameSB(declaringType, name, propertySig, typeGenArgs, null).ToString(); + } + + /// + /// Returns the full name of a property + /// + /// Declaring type full name or null if none + /// Name of property + /// Property signature + /// Type generic arguments or null if none + /// String builder to use or null + /// Property full name + public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs, StringBuilder sb) { + return PropertyFullNameSB(declaringType, name, propertySig, typeGenArgs, sb).ToString(); + } + + /// + /// Returns the full name of a property + /// + /// Declaring type full name or null if none + /// Name of property + /// Property signature + /// Type generic arguments or null if none + /// String builder to use or null + /// Property full name + public static StringBuilder PropertyFullNameSB(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs, StringBuilder sb) { + var fnc = new FullNameCreator(false, null, sb); if (typeGenArgs != null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } fnc.CreatePropertyFullName(declaringType, name, propertySig); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -135,7 +296,7 @@ public static string PropertyFullName(string declaringType, UTF8String name, Cal /// Event type /// Event full name public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef) { - return EventFullName(declaringType, name, typeDefOrRef, null); + return EventFullNameSB(declaringType, name, typeDefOrRef, null, null).ToString(); } /// @@ -147,14 +308,40 @@ public static string EventFullName(string declaringType, UTF8String name, ITypeD /// Type generic arguments or null if none /// Property full name public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs) { - var fnc = new FullNameCreator(false, null); + return EventFullNameSB(declaringType, name, typeDefOrRef, typeGenArgs, null).ToString(); + } + + /// + /// Returns the full name of a property + /// + /// Declaring type full name or null if none + /// Name of property + /// Event type + /// Type generic arguments or null if none + /// String builder to use or null + /// Property full name + public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs, StringBuilder sb) { + return EventFullNameSB(declaringType, name, typeDefOrRef, typeGenArgs, sb).ToString(); + } + + /// + /// Returns the full name of a property + /// + /// Declaring type full name or null if none + /// Name of property + /// Event type + /// Type generic arguments or null if none + /// String builder to use or null + /// Property full name + public static StringBuilder EventFullNameSB(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs, StringBuilder sb) { + var fnc = new FullNameCreator(false, null, sb); if (typeGenArgs != null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } fnc.CreateEventFullName(declaringType, name, typeDefOrRef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -165,7 +352,7 @@ public static string EventFullName(string declaringType, UTF8String name, ITypeD /// Field signature /// Field full name public static string FieldFullName(string declaringType, UTF8String name, FieldSig fieldSig) { - return FieldFullName(declaringType, UTF8String.ToSystemString(name), fieldSig, null); + return FieldFullNameSB(declaringType, UTF8String.ToSystemString(name), fieldSig, null, null).ToString(); } /// @@ -177,7 +364,7 @@ public static string FieldFullName(string declaringType, UTF8String name, FieldS /// Type generic arguments or null if none /// Field full name public static string FieldFullName(string declaringType, UTF8String name, FieldSig fieldSig, IList typeGenArgs) { - return FieldFullName(declaringType, UTF8String.ToSystemString(name), fieldSig, typeGenArgs); + return FieldFullNameSB(declaringType, UTF8String.ToSystemString(name), fieldSig, typeGenArgs, null).ToString(); } /// @@ -188,7 +375,7 @@ public static string FieldFullName(string declaringType, UTF8String name, FieldS /// Field signature /// Field full name public static string FieldFullName(string declaringType, string name, FieldSig fieldSig) { - return FieldFullName(declaringType, name, fieldSig, null); + return FieldFullNameSB(declaringType, name, fieldSig, null, null).ToString(); } /// @@ -200,14 +387,40 @@ public static string FieldFullName(string declaringType, string name, FieldSig f /// Type generic arguments or null if none /// Field full name public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs) { - var fnc = new FullNameCreator(false, null); + return FieldFullNameSB(declaringType, name, fieldSig, typeGenArgs, null).ToString(); + } + + /// + /// Returns the full name of a field + /// + /// Declaring type full name or null if none + /// Name of field + /// Field signature + /// Type generic arguments or null if none + /// String builder to use or null + /// Field full name + public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs, StringBuilder sb) { + return FieldFullNameSB(declaringType, name, fieldSig, typeGenArgs, sb).ToString(); + } + + /// + /// Returns the full name of a field + /// + /// Declaring type full name or null if none + /// Name of field + /// Field signature + /// Type generic arguments or null if none + /// String builder to use or null + /// Field full name + public static StringBuilder FieldFullNameSB(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs, StringBuilder sb) { + var fnc = new FullNameCreator(false, null, sb); if (typeGenArgs != null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } fnc.CreateFieldFullName(declaringType, name, fieldSig); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -218,7 +431,7 @@ public static string FieldFullName(string declaringType, string name, FieldSig f /// Method signature /// Method full name public static string MethodFullName(string declaringType, UTF8String name, MethodSig methodSig) { - return MethodFullName(declaringType, UTF8String.ToSystemString(name), methodSig, null, null, null); + return MethodFullNameSB(declaringType, UTF8String.ToSystemString(name), methodSig, null, null, null, null).ToString(); } /// @@ -230,7 +443,7 @@ public static string MethodFullName(string declaringType, UTF8String name, Metho /// Type generic arguments or null if none /// Method full name public static string MethodFullName(string declaringType, UTF8String name, MethodSig methodSig, IList typeGenArgs) { - return MethodFullName(declaringType, UTF8String.ToSystemString(name), methodSig, typeGenArgs, null, null); + return MethodFullNameSB(declaringType, UTF8String.ToSystemString(name), methodSig, typeGenArgs, null, null, null).ToString(); } /// @@ -243,7 +456,7 @@ public static string MethodFullName(string declaringType, UTF8String name, Metho /// Method generic arguments or null if none /// Method full name public static string MethodFullName(string declaringType, UTF8String name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs) { - return MethodFullName(declaringType, UTF8String.ToSystemString(name), methodSig, typeGenArgs, methodGenArgs, null); + return MethodFullNameSB(declaringType, UTF8String.ToSystemString(name), methodSig, typeGenArgs, methodGenArgs, null, null).ToString(); } /// @@ -254,7 +467,7 @@ public static string MethodFullName(string declaringType, UTF8String name, Metho /// Method signature /// Method full name public static string MethodFullName(string declaringType, string name, MethodSig methodSig) { - return MethodFullName(declaringType, name, methodSig, null, null, null); + return MethodFullNameSB(declaringType, name, methodSig, null, null, null, null).ToString(); } /// @@ -266,7 +479,7 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Type generic arguments or null if none /// Method full name public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs) { - return MethodFullName(declaringType, name, methodSig, typeGenArgs, null, null); + return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, null, null, null).ToString(); } /// @@ -279,7 +492,7 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Method generic arguments or null if none /// Method full name public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs) { - return MethodFullName(declaringType, name, methodSig, typeGenArgs, methodGenArgs, null); + return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, null, null).ToString(); } /// @@ -293,7 +506,37 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Generic parameter owner method or null /// Method full name public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod) { - var fnc = new FullNameCreator(false, null); + return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, gppMethod, null).ToString(); + } + + /// + /// Returns the full name of a method + /// + /// Declaring type full name or null if none + /// Name of method or null if none + /// Method signature + /// Type generic arguments or null if none + /// Method generic arguments or null if none + /// Generic parameter owner method or null + /// String builder to use or null + /// Method full name + public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod, StringBuilder sb) { + return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, gppMethod, sb).ToString(); + } + + /// + /// Returns the full name of a method + /// + /// Declaring type full name or null if none + /// Name of method or null if none + /// Method signature + /// Type generic arguments or null if none + /// Method generic arguments or null if none + /// Generic parameter owner method or null + /// String builder to use or null + /// Method full name + public static StringBuilder MethodFullNameSB(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod, StringBuilder sb) { + var fnc = new FullNameCreator(false, null, sb); if (typeGenArgs != null || methodGenArgs != null) fnc.genericArguments = new GenericArguments(); if (typeGenArgs != null) @@ -301,7 +544,7 @@ public static string MethodFullName(string declaringType, string name, MethodSig if (methodGenArgs != null) fnc.genericArguments.PushMethodArgs(methodGenArgs); fnc.CreateMethodFullName(declaringType, name, methodSig, gppMethod); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -310,7 +553,7 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Method sig /// Method sig full name public static string MethodSigFullName(MethodSig methodSig) { - return MethodBaseSigFullName(methodSig); + return MethodBaseSigFullNameSB(methodSig, null).ToString(); } /// @@ -319,7 +562,7 @@ public static string MethodSigFullName(MethodSig methodSig) { /// Property sig /// Property sig full name public static string PropertySigFullName(PropertySig propertySig) { - return MethodBaseSigFullName(propertySig); + return MethodBaseSigFullNameSB(propertySig, null).ToString(); } /// @@ -328,9 +571,29 @@ public static string PropertySigFullName(PropertySig propertySig) { /// Property sig /// Property sig full name public static string MethodBaseSigFullName(MethodBaseSig sig) { - var fnc = new FullNameCreator(false, null); + return MethodBaseSigFullNameSB(sig, null).ToString(); + } + + /// + /// Returns the full name of a property sig + /// + /// Property sig + /// String builder to use or null + /// Property sig full name + public static string MethodBaseSigFullName(MethodBaseSig sig, StringBuilder sb) { + return MethodBaseSigFullNameSB(sig, sb).ToString(); + } + + /// + /// Returns the full name of a property sig + /// + /// Property sig + /// String builder to use or null + /// Property sig full name + public static StringBuilder MethodBaseSigFullNameSB(MethodBaseSig sig, StringBuilder sb) { + var fnc = new FullNameCreator(false, null, sb); fnc.CreateMethodFullName(null, null, sig, null); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -342,9 +605,35 @@ public static string MethodBaseSigFullName(MethodBaseSig sig) { /// Owner method or null /// Sig full name public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod) { - var fnc = new FullNameCreator(false, null); + return MethodBaseSigFullNameSB(declType, name, sig, gppMethod, null).ToString(); + } + + /// + /// Returns the full name of a sig + /// + /// Declaring type or null + /// Name or null + /// Method sig + /// Owner method or null + /// String builder to use or null + /// Sig full name + public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb) { + return MethodBaseSigFullNameSB(declType, name, sig, gppMethod, sb).ToString(); + } + + /// + /// Returns the full name of a sig + /// + /// Declaring type or null + /// Name or null + /// Method sig + /// Owner method or null + /// String builder to use or null + /// Sig full name + public static StringBuilder MethodBaseSigFullNameSB(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb) { + var fnc = new FullNameCreator(false, null, sb); fnc.CreateMethodFullName(declType, name, sig, gppMethod); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -354,9 +643,31 @@ public static string MethodBaseSigFullName(string declType, string name, MethodB /// Set if output should be compatible with reflection /// The namespace public static string Namespace(TypeRef typeRef, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NamespaceSB(typeRef, isReflection, null).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder sb) { + return NamespaceSB(typeRef, isReflection, sb).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static StringBuilder NamespaceSB(TypeRef typeRef, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateNamespace(typeRef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -366,9 +677,31 @@ public static string Namespace(TypeRef typeRef, bool isReflection) { /// Set if output should be compatible with reflection /// The name public static string Name(TypeRef typeRef, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NameSB(typeRef, isReflection, null).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb) { + return NameSB(typeRef, isReflection, sb).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static StringBuilder NameSB(TypeRef typeRef, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateName(typeRef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -378,7 +711,7 @@ public static string Name(TypeRef typeRef, bool isReflection) { /// Set if output should be compatible with reflection /// The full name public static string FullName(TypeRef typeRef, bool isReflection) { - return FullName(typeRef, isReflection, null); + return FullNameSB(typeRef, isReflection, null, null).ToString(); } /// @@ -389,9 +722,33 @@ public static string FullName(TypeRef typeRef, bool isReflection) { /// Helps print the name /// The full name public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(isReflection, helper); + return FullNameSB(typeRef, isReflection, helper, null).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + return FullNameSB(typeRef, isReflection, helper, sb).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeRef + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static StringBuilder FullNameSB(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, helper, sb); fnc.CreateFullName(typeRef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -400,7 +757,7 @@ public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreat /// The TypeRef /// The assembly qualified full name public static string AssemblyQualifiedName(TypeRef typeRef) { - return AssemblyQualifiedName(typeRef, null); + return AssemblyQualifiedNameSB(typeRef, null, null).ToString(); } /// @@ -410,9 +767,31 @@ public static string AssemblyQualifiedName(TypeRef typeRef) { /// Helps print the name /// The assembly qualified full name public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(true, helper); + return AssemblyQualifiedNameSB(typeRef, helper, null).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeRef + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper, StringBuilder sb) { + return AssemblyQualifiedNameSB(typeRef, helper, sb).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeRef + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static StringBuilder AssemblyQualifiedNameSB(TypeRef typeRef, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeRef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -448,10 +827,32 @@ public static ModuleDef OwnerModule(TypeRef typeRef) { /// The TypeDef /// Set if output should be compatible with reflection /// The namespace - public static string Namespace(TypeDef typeDef, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + public static string Namespace(TypeDef typeDef, bool isReflection) { + return NamespaceSB(typeDef, isReflection, null).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeDef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder sb) { + return NamespaceSB(typeDef, isReflection, sb).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeDef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static StringBuilder NamespaceSB(TypeDef typeDef, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateNamespace(typeDef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -461,9 +862,31 @@ public static string Namespace(TypeDef typeDef, bool isReflection) { /// Set if output should be compatible with reflection /// The name public static string Name(TypeDef typeDef, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NameSB(typeDef, isReflection, null).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeDef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static string Name(TypeDef typeDef, bool isReflection, StringBuilder sb) { + return NameSB(typeDef, isReflection, sb).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeDef + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static StringBuilder NameSB(TypeDef typeDef, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateName(typeDef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -473,7 +896,7 @@ public static string Name(TypeDef typeDef, bool isReflection) { /// Set if output should be compatible with reflection /// The full name public static string FullName(TypeDef typeDef, bool isReflection) { - return FullName(typeDef, isReflection, null); + return FullNameSB(typeDef, isReflection, null, null).ToString(); } /// @@ -484,9 +907,33 @@ public static string FullName(TypeDef typeDef, bool isReflection) { /// Helps print the name /// The full name public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(isReflection, helper); + return FullNameSB(typeDef, isReflection, helper, null).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeDef + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + return FullNameSB(typeDef, isReflection, helper, sb).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeDef + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static StringBuilder FullNameSB(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, helper, sb); fnc.CreateFullName(typeDef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -495,7 +942,7 @@ public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreat /// The TypeDef /// The assembly qualified full name public static string AssemblyQualifiedName(TypeDef typeDef) { - return AssemblyQualifiedName(typeDef, null); + return AssemblyQualifiedNameSB(typeDef, null, null).ToString(); } /// @@ -505,9 +952,31 @@ public static string AssemblyQualifiedName(TypeDef typeDef) { /// Helps print the name /// The assembly qualified full name public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(true, helper); + return AssemblyQualifiedNameSB(typeDef, helper, null).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeDef + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper, StringBuilder sb) { + return AssemblyQualifiedNameSB(typeDef, helper, sb).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeDef + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static StringBuilder AssemblyQualifiedNameSB(TypeDef typeDef, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeDef); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -535,9 +1004,31 @@ public static ModuleDef OwnerModule(TypeDef typeDef) { /// Set if output should be compatible with reflection /// The namespace public static string Namespace(TypeSpec typeSpec, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NamespaceSB(typeSpec, isReflection, null).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeSpec + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { + return NamespaceSB(typeSpec, isReflection, sb).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The TypeSpec + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static StringBuilder NamespaceSB(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateNamespace(typeSpec); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -547,9 +1038,31 @@ public static string Namespace(TypeSpec typeSpec, bool isReflection) { /// Set if output should be compatible with reflection /// The name public static string Name(TypeSpec typeSpec, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NameSB(typeSpec, isReflection, null).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeSpec + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static string Name(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { + return NameSB(typeSpec, isReflection, sb).ToString(); + } + + /// + /// Returns the name of a + /// + /// The TypeSpec + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static StringBuilder NameSB(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateName(typeSpec); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -559,7 +1072,7 @@ public static string Name(TypeSpec typeSpec, bool isReflection) { /// Set if output should be compatible with reflection /// The full name public static string FullName(TypeSpec typeSpec, bool isReflection) { - return FullName(typeSpec, isReflection, null); + return FullNameSB(typeSpec, isReflection, null, null).ToString(); } /// @@ -570,9 +1083,33 @@ public static string FullName(TypeSpec typeSpec, bool isReflection) { /// Helps print the name /// The full name public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(isReflection, helper); + return FullNameSB(typeSpec, isReflection, helper, null).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeSpec + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + return FullNameSB(typeSpec, isReflection, helper, sb).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The TypeSpec + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static StringBuilder FullNameSB(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, helper, sb); fnc.CreateFullName(typeSpec); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -581,7 +1118,7 @@ public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCre /// The TypeSpec /// The assembly qualified full name public static string AssemblyQualifiedName(TypeSpec typeSpec) { - return AssemblyQualifiedName(typeSpec, null); + return AssemblyQualifiedNameSB(typeSpec, null, null).ToString(); } /// @@ -591,9 +1128,31 @@ public static string AssemblyQualifiedName(TypeSpec typeSpec) { /// Helps print the name /// The assembly qualified full name public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(true, helper); + return AssemblyQualifiedNameSB(typeSpec, helper, null).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeSpec + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper, StringBuilder sb) { + return AssemblyQualifiedNameSB(typeSpec, helper, sb).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeSpec + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static StringBuilder AssemblyQualifiedNameSB(TypeSpec typeSpec, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeSpec); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -639,9 +1198,31 @@ public static ModuleDef OwnerModule(TypeSpec typeSpec) { /// Set if output should be compatible with reflection /// The namespace public static string Namespace(TypeSig typeSig, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NamespaceSB(typeSig, isReflection, null).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The type sig + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder sb) { + return NamespaceSB(typeSig, isReflection, sb).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The type sig + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static StringBuilder NamespaceSB(TypeSig typeSig, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateNamespace(typeSig); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -651,9 +1232,31 @@ public static string Namespace(TypeSig typeSig, bool isReflection) { /// Set if output should be compatible with reflection /// The name public static string Name(TypeSig typeSig, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NameSB(typeSig, isReflection, null).ToString(); + } + + /// + /// Returns the name of a + /// + /// The type sig + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static string Name(TypeSig typeSig, bool isReflection, StringBuilder sb) { + return NameSB(typeSig, isReflection, sb).ToString(); + } + + /// + /// Returns the name of a + /// + /// The type sig + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static StringBuilder NameSB(TypeSig typeSig, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateName(typeSig); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -663,7 +1266,7 @@ public static string Name(TypeSig typeSig, bool isReflection) { /// Set if output should be compatible with reflection /// The full name public static string FullName(TypeSig typeSig, bool isReflection) { - return FullName(typeSig, isReflection, null, null, null); + return FullNameSB(typeSig, isReflection, null, null, null, null).ToString(); } /// @@ -674,7 +1277,7 @@ public static string FullName(TypeSig typeSig, bool isReflection) { /// Helps print the name /// The full name public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper) { - return FullName(typeSig, isReflection, helper, null, null); + return FullNameSB(typeSig, isReflection, helper, null, null, null).ToString(); } /// @@ -686,7 +1289,7 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreat /// Method generic args or null if none /// The full name public static string FullName(TypeSig typeSig, bool isReflection, IList typeGenArgs, IList methodGenArgs) { - return FullName(typeSig, isReflection, null, typeGenArgs, methodGenArgs); + return FullNameSB(typeSig, isReflection, null, typeGenArgs, methodGenArgs, null).ToString(); } /// @@ -699,7 +1302,35 @@ public static string FullName(TypeSig typeSig, bool isReflection, IList /// Method generic args or null if none /// The full name public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper, IList typeGenArgs, IList methodGenArgs) { - var fnc = new FullNameCreator(isReflection, helper); + return FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, null).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The type sig + /// Set if output should be compatible with reflection + /// Helps print the name + /// Type generic args or null if none + /// Method generic args or null if none + /// String builder to use or null + /// The full name + public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { + return FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, sb).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The type sig + /// Set if output should be compatible with reflection + /// Helps print the name + /// Type generic args or null if none + /// Method generic args or null if none + /// String builder to use or null + /// The full name + public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, helper, sb); if (typeGenArgs != null || methodGenArgs != null) fnc.genericArguments = new GenericArguments(); if (typeGenArgs != null) @@ -707,7 +1338,7 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreat if (methodGenArgs != null) fnc.genericArguments.PushMethodArgs(methodGenArgs); fnc.CreateFullName(typeSig); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -716,7 +1347,7 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreat /// The TypeSig /// The assembly qualified full name public static string AssemblyQualifiedName(TypeSig typeSig) { - return AssemblyQualifiedName(typeSig, null); + return AssemblyQualifiedNameSB(typeSig, null, null).ToString(); } /// @@ -726,9 +1357,31 @@ public static string AssemblyQualifiedName(TypeSig typeSig) { /// Helps print the name /// The assembly qualified full name public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(true, helper); + return AssemblyQualifiedNameSB(typeSig, helper, null).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeSig + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper, StringBuilder sb) { + return AssemblyQualifiedNameSB(typeSig, helper, sb).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The TypeSig + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static StringBuilder AssemblyQualifiedNameSB(TypeSig typeSig, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeSig); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -774,9 +1427,31 @@ public static ModuleDef OwnerModule(TypeSig typeSig) { /// Set if output should be compatible with reflection /// The namespace public static string Namespace(ExportedType exportedType, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NamespaceSB(exportedType, isReflection, null).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The ExportedType + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static string Namespace(ExportedType exportedType, bool isReflection, StringBuilder sb) { + return NamespaceSB(exportedType, isReflection, sb).ToString(); + } + + /// + /// Returns the namespace of a + /// + /// The ExportedType + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The namespace + public static StringBuilder NamespaceSB(ExportedType exportedType, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateNamespace(exportedType); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -786,9 +1461,31 @@ public static string Namespace(ExportedType exportedType, bool isReflection) { /// Set if output should be compatible with reflection /// The name public static string Name(ExportedType exportedType, bool isReflection) { - var fnc = new FullNameCreator(isReflection, null); + return NameSB(exportedType, isReflection, null).ToString(); + } + + /// + /// Returns the name of a + /// + /// The ExportedType + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static string Name(ExportedType exportedType, bool isReflection, StringBuilder sb) { + return NameSB(exportedType, isReflection, sb).ToString(); + } + + /// + /// Returns the name of a + /// + /// The ExportedType + /// Set if output should be compatible with reflection + /// String builder to use or null + /// The name + public static StringBuilder NameSB(ExportedType exportedType, bool isReflection, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, null, sb); fnc.CreateName(exportedType); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -798,7 +1495,7 @@ public static string Name(ExportedType exportedType, bool isReflection) { /// Set if output should be compatible with reflection /// The full name public static string FullName(ExportedType exportedType, bool isReflection) { - return FullName(exportedType, isReflection, null); + return FullNameSB(exportedType, isReflection, null, null).ToString(); } /// @@ -809,9 +1506,33 @@ public static string FullName(ExportedType exportedType, bool isReflection) { /// Helps print the name /// The full name public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(isReflection, helper); + return FullNameSB(exportedType, isReflection, helper, null).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The ExportedType + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + return FullNameSB(exportedType, isReflection, helper, sb).ToString(); + } + + /// + /// Returns the full name of a + /// + /// The ExportedType + /// Set if output should be compatible with reflection + /// Helps print the name + /// String builder to use or null + /// The full name + public static StringBuilder FullNameSB(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(isReflection, helper, sb); fnc.CreateFullName(exportedType); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -820,7 +1541,7 @@ public static string FullName(ExportedType exportedType, bool isReflection, IFul /// The ExportedType /// The assembly qualified full name public static string AssemblyQualifiedName(ExportedType exportedType) { - return AssemblyQualifiedName(exportedType, null); + return AssemblyQualifiedNameSB(exportedType, null, null).ToString(); } /// @@ -830,9 +1551,31 @@ public static string AssemblyQualifiedName(ExportedType exportedType) { /// Helps print the name /// The assembly qualified full name public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper) { - var fnc = new FullNameCreator(true, helper); + return AssemblyQualifiedNameSB(exportedType, helper, null).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The ExportedType + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper, StringBuilder sb) { + return AssemblyQualifiedNameSB(exportedType, helper, sb).ToString(); + } + + /// + /// Returns the assembly qualified full name of a + /// + /// The ExportedType + /// Helps print the name + /// String builder to use or null + /// The assembly qualified full name + public static StringBuilder AssemblyQualifiedNameSB(ExportedType exportedType, IFullNameCreatorHelper helper, StringBuilder sb) { + var fnc = new FullNameCreator(true, helper, sb); fnc.CreateAssemblyQualifiedName(exportedType); - return fnc.Result; + return fnc.sb ?? new StringBuilder(); } /// @@ -875,8 +1618,8 @@ string Result { get { return sb == null ? null : sb.ToString(); } } - FullNameCreator(bool isReflection, IFullNameCreatorHelper helper) { - this.sb = new StringBuilder(); + FullNameCreator(bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + this.sb = sb ?? new StringBuilder(); this.isReflection = isReflection; this.helper = helper; this.genericArguments = null; diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index 921d742ef..e84ae43e9 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -1048,31 +1048,28 @@ public static ITypeDefOrRef ToTypeDefOrRef(this TypeSig sig) { internal static bool IsPrimitive(this IType tdr) { if (tdr == null) return false; + if (!tdr.DefinitionAssembly.IsCorLib()) + return false; - switch (tdr.Name) { - case "Boolean": - case "Char": - case "SByte": - case "Byte": - case "Int16": - case "UInt16": - case "Int32": - case "UInt32": - case "Int64": - case "UInt64": - case "Single": - case "Double": - case "IntPtr": - case "UIntPtr": - break; + switch (tdr.FullName) { + case "System.Boolean": + case "System.Char": + case "System.SByte": + case "System.Byte": + case "System.Int16": + case "System.UInt16": + case "System.Int32": + case "System.UInt32": + case "System.Int64": + case "System.UInt64": + case "System.Single": + case "System.Double": + case "System.IntPtr": + case "System.UIntPtr": + return true; default: return false; } - - if (tdr.Namespace != "System") - return false; - - return tdr.DefinitionAssembly.IsCorLib(); } } } diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index 9b5d371d3..97e820a1f 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -302,10 +302,10 @@ public string FullName { } var methodSig = MethodSig; if (methodSig != null) - return FullNameCreator.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null); + return FullNameCreator.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null, null, null); var fieldSig = FieldSig; if (fieldSig != null) - return FullNameCreator.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs); + return FullNameCreator.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs, null); return string.Empty; } } diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 52e47f5c2..707cbe06a 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -496,7 +496,7 @@ public bool HasImplMap { public string FullName { get { var dt = declaringType2; - return FullNameCreator.MethodFullName(dt == null ? null : dt.FullName, name, MethodSig, null, null, this); + return FullNameCreator.MethodFullName(dt == null ? null : dt.FullName, name, MethodSig, null, null, this, null); } } diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index 5e1903b7a..2dcac36b9 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -141,7 +141,7 @@ public string FullName { var methodDef = m as MethodDef; if (methodDef != null) { var declaringType = methodDef.DeclaringType; - return FullNameCreator.MethodFullName(declaringType == null ? null : declaringType.FullName, methodDef.Name, methodDef.MethodSig, null, methodGenArgs); + return FullNameCreator.MethodFullName(declaringType == null ? null : declaringType.FullName, methodDef.Name, methodDef.MethodSig, null, methodGenArgs, null, null); } var memberRef = m as MemberRef; @@ -151,7 +151,7 @@ public string FullName { var tsOwner = memberRef.Class as TypeSpec; var gis = tsOwner == null ? null : tsOwner.TypeSig as GenericInstSig; var typeGenArgs = gis == null ? null : gis.GenericArguments; - return FullNameCreator.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs); + return FullNameCreator.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs, null, null); } } diff --git a/src/DotNet/PropertyDef.cs b/src/DotNet/PropertyDef.cs index cf0f68940..6bc33c5f4 100644 --- a/src/DotNet/PropertyDef.cs +++ b/src/DotNet/PropertyDef.cs @@ -348,7 +348,7 @@ public ModuleDef Module { public string FullName { get { var dt = declaringType2; - return FullNameCreator.PropertyFullName(dt == null ? null : dt.FullName, name, type); + return FullNameCreator.PropertyFullName(dt == null ? null : dt.FullName, name, type, null, null); } } diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index df1146c60..f77498a2b 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -1,12 +1,13 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.Threading; using dnlib.Utils; using dnlib.DotNet.MD; using dnlib.DotNet.Emit; using dnlib.Threading; +using System.Text; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -71,37 +72,37 @@ int IGenericParameterProvider.NumberOfGenericParameters { /// string IType.TypeName { - get { return FullNameCreator.Name(this, false); } + get { return FullNameCreator.Name(this, false, null); } } /// public string ReflectionName { - get { return FullNameCreator.Name(this, true); } + get { return FullNameCreator.Name(this, true, null); } } /// string IType.Namespace { - get { return FullNameCreator.Namespace(this, false); } + get { return FullNameCreator.Namespace(this, false, null); } } /// public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true); } + get { return FullNameCreator.Namespace(this, true, null); } } /// public string FullName { - get { return FullNameCreator.FullName(this, false); } + get { return FullNameCreator.FullName(this, false, null, null); } } /// public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true); } + get { return FullNameCreator.FullName(this, true, null, null); } } /// public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this); } + get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } } /// @@ -678,32 +679,65 @@ public uint ClassSize { /// public bool IsValueType { get { + if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + return false; var baseType = BaseType; if (baseType == null) return false; - if (baseType.Namespace != "System") + if (!baseType.DefinitionAssembly.IsCorLib()) return false; - if (baseType.TypeName != "ValueType" && baseType.TypeName != "Enum") + + // PERF: Don't allocate a System.String by calling FullName etc. + UTF8String baseName, baseNamespace; + var baseTr = baseType as TypeRef; + if (baseTr != null) { + baseName = baseTr.Name; + baseNamespace = baseTr.Namespace; + } + else { + var baseTd = baseType as TypeDef; + if (baseTd == null) + return false; + baseName = baseTd.Name; + baseNamespace = baseTd.Namespace; + } + + if (baseNamespace != systemString) return false; - if (!baseType.DefinitionAssembly.IsCorLib()) + if (baseName != valueTypeString && baseName != enumString) return false; - return !(FullName == "System.Enum" && DefinitionAssembly.IsCorLib()); + + if (!DefinitionAssembly.IsCorLib()) + return true; + return !(Name == enumString && Namespace == systemString); } } + static readonly UTF8String systemString = new UTF8String("System"); + static readonly UTF8String enumString = new UTF8String("Enum"); + static readonly UTF8String valueTypeString = new UTF8String("ValueType"); + static readonly UTF8String multicastDelegateString = new UTF8String("MulticastDelegate"); /// /// true if it's an enum /// public bool IsEnum { get { + if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + return false; var baseType = BaseType; if (baseType == null) return false; - if (baseType.Namespace != "System") - return false; - if (baseType.TypeName != "Enum") + if (!baseType.DefinitionAssembly.IsCorLib()) return false; - return baseType.DefinitionAssembly.IsCorLib(); + + // PERF: Don't allocate a System.String by calling FullName etc. + var baseTr = baseType as TypeRef; + if (baseTr != null) + return baseTr.Namespace == systemString && baseTr.Name == enumString; + var baseTd = baseType as TypeDef; + if (baseTd != null) + return baseTd.Namespace == systemString && baseTd.Name == enumString; + return false; } } @@ -712,14 +746,22 @@ public bool IsEnum { /// public bool IsDelegate { get { + if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + return false; var baseType = BaseType; if (baseType == null) return false; - if (baseType.Namespace != "System") - return false; - if (baseType.TypeName != "MulticastDelegate") + if (!baseType.DefinitionAssembly.IsCorLib()) return false; - return baseType.DefinitionAssembly.IsCorLib(); + + // PERF: Don't allocate a System.String by calling FullName etc. + var baseTr = baseType as TypeRef; + if (baseTr != null) + return baseTr.Namespace == systemString && baseTr.Name == multicastDelegateString; + var baseTd = baseType as TypeDef; + if (baseTd != null) + return baseTd.Namespace == systemString && baseTd.Name == multicastDelegateString; + return false; } } diff --git a/src/DotNet/TypeDefFinder.cs b/src/DotNet/TypeDefFinder.cs index 619af563a..b2aa136bd 100644 --- a/src/DotNet/TypeDefFinder.cs +++ b/src/DotNet/TypeDefFinder.cs @@ -1,7 +1,8 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; +using System.Text; using dnlib.Threading; namespace dnlib.DotNet { @@ -15,6 +16,7 @@ sealed class TypeDefFinder : ITypeDefFinder, IDisposable { Dictionary typeRefCache = new Dictionary(new TypeEqualityComparer(TypeComparerOptions)); Dictionary normalNameCache = new Dictionary(StringComparer.Ordinal); Dictionary reflectionNameCache = new Dictionary(StringComparer.Ordinal); + readonly StringBuilder sb = new StringBuilder(); IEnumerator typeEnumerator; readonly IEnumerable rootTypes; #if THREAD_SAFE @@ -165,7 +167,10 @@ TypeDef FindCacheReflection(string fullName) { // Build the cache lazily while (true) { cachedType = GetNextTypeDefCache(); - if (cachedType == null || cachedType.ReflectionFullName == fullName) + if (cachedType == null) + return cachedType; + sb.Length = 0; + if (FullNameCreator.FullName(cachedType, true, null, sb) == fullName) return cachedType; } } @@ -178,7 +183,10 @@ TypeDef FindCacheNormal(string fullName) { // Build the cache lazily while (true) { cachedType = GetNextTypeDefCache(); - if (cachedType == null || cachedType.FullName == fullName) + if (cachedType == null) + return cachedType; + sb.Length = 0; + if (FullNameCreator.FullName(cachedType, false, null, sb) == fullName) return cachedType; } } @@ -197,7 +205,10 @@ TypeDef FindSlowReflection(string fullName) { InitializeTypeEnumerator(); while (true) { var type = GetNextTypeDef(); - if (type == null || type.ReflectionFullName == fullName) + if (type == null) + return type; + sb.Length = 0; + if (FullNameCreator.FullName(type, true, null, sb) == fullName) return type; } } @@ -206,7 +217,10 @@ TypeDef FindSlowNormal(string fullName) { InitializeTypeEnumerator(); while (true) { var type = GetNextTypeDef(); - if (type == null || type.FullName == fullName) + if (type == null) + return type; + sb.Length = 0; + if (FullNameCreator.FullName(type, false, null, sb) == fullName) return type; } } @@ -241,9 +255,11 @@ TypeDef GetNextTypeDefCache() { if (!typeRefCache.ContainsKey(type)) typeRefCache[type] = type; string fn; - if (!normalNameCache.ContainsKey(fn = type.FullName)) + sb.Length = 0; + if (!normalNameCache.ContainsKey(fn = FullNameCreator.FullName(type, false, null, sb))) normalNameCache[fn] = type; - if (!reflectionNameCache.ContainsKey(fn = type.ReflectionFullName)) + sb.Length = 0; + if (!reflectionNameCache.ContainsKey(fn = FullNameCreator.FullName(type, true, null, sb))) reflectionNameCache[fn] = type; return type; diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index 893eb70c6..b0d7c8141 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -62,37 +62,37 @@ int IGenericParameterProvider.NumberOfGenericParameters { /// string IType.TypeName { - get { return FullNameCreator.Name(this, false); } + get { return FullNameCreator.Name(this, false, null); } } /// public string ReflectionName { - get { return FullNameCreator.Name(this, true); } + get { return FullNameCreator.Name(this, true, null); } } /// string IType.Namespace { - get { return FullNameCreator.Namespace(this, false); } + get { return FullNameCreator.Namespace(this, false, null); } } /// public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true); } + get { return FullNameCreator.Namespace(this, true, null); } } /// public string FullName { - get { return FullNameCreator.FullName(this, false); } + get { return FullNameCreator.FullName(this, false, null, null); } } /// public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true); } + get { return FullNameCreator.FullName(this, true, null, null); } } /// public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this); } + get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } } /// diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index 55f4912d0..d79c03d0b 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -111,43 +111,43 @@ public bool IsPrimitive { /// public string TypeName { - get { return FullNameCreator.Name(this, false); } + get { return FullNameCreator.Name(this, false, null); } } /// UTF8String IFullName.Name { - get { return new UTF8String(FullNameCreator.Name(this, false)); } + get { return new UTF8String(FullNameCreator.Name(this, false, null)); } set { throw new NotSupportedException(); } } /// public string ReflectionName { - get { return FullNameCreator.Name(this, true); } + get { return FullNameCreator.Name(this, true, null); } } /// public string Namespace { - get { return FullNameCreator.Namespace(this, false); } + get { return FullNameCreator.Namespace(this, false, null); } } /// public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true); } + get { return FullNameCreator.Namespace(this, true, null); } } /// public string FullName { - get { return FullNameCreator.FullName(this, false); } + get { return FullNameCreator.FullName(this, false, null, null, null, null); } } /// public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true); } + get { return FullNameCreator.FullName(this, true, null, null, null, null); } } /// public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this); } + get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } } /// diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index 7e6c9635f..39420f7d7 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -156,37 +156,37 @@ public bool IsPrimitive { /// public string TypeName { - get { return FullNameCreator.Name(this, false); } + get { return FullNameCreator.Name(this, false, null); } } /// public string ReflectionName { - get { return FullNameCreator.Name(this, true); } + get { return FullNameCreator.Name(this, true, null); } } /// string IType.Namespace { - get { return FullNameCreator.Namespace(this, false); } + get { return FullNameCreator.Namespace(this, false, null); } } /// public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true); } + get { return FullNameCreator.Namespace(this, true, null); } } /// public string FullName { - get { return FullNameCreator.FullName(this, false); } + get { return FullNameCreator.FullName(this, false, null, null); } } /// public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true); } + get { return FullNameCreator.FullName(this, true, null, null); } } /// public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this); } + get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } } /// diff --git a/src/DotNet/UTF8String.cs b/src/DotNet/UTF8String.cs index 0eebccffc..be3524e67 100644 --- a/src/DotNet/UTF8String.cs +++ b/src/DotNet/UTF8String.cs @@ -173,7 +173,7 @@ public static int CaseInsensitiveCompareTo(UTF8String a, UTF8String b) { return -1; if (sb == null) return 1; - return sa.ToUpperInvariant().CompareTo(sb.ToUpperInvariant()); + return StringComparer.OrdinalIgnoreCase.Compare(sa, sb); } /// From 832b0b2a0fea2facced00cde11d9cd5b37412500 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 19 Mar 2016 16:34:22 +0100 Subject: [PATCH 011/511] Remove VS2008 support, remove useless class (move to de4dot) --- src/DotNet/AccessChecker.cs | 610 -------------------------------- src/DotNet/AssemblyDef.cs | 74 +--- src/DotNet/ElementType.cs | 11 +- src/DotNet/FullNameCreator.cs | 615 ++------------------------------- src/DotNet/ICodedToken.cs | 24 +- src/DotNet/Importer.cs | 36 +- src/DotNet/ModuleDef.cs | 21 +- src/DotNet/ModuleDefMD.cs | 24 +- src/DotNet/UTF8String.cs | 2 +- src/Properties/AssemblyInfo.cs | 4 +- src/dnlib.csproj | 1 - 11 files changed, 47 insertions(+), 1375 deletions(-) delete mode 100644 src/DotNet/AccessChecker.cs diff --git a/src/DotNet/AccessChecker.cs b/src/DotNet/AccessChecker.cs deleted file mode 100644 index 3f3758b71..000000000 --- a/src/DotNet/AccessChecker.cs +++ /dev/null @@ -1,610 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Checks whether a type has access to some other target type, method or field - /// according to the target's visibility. - /// - public struct AccessChecker { - TypeDef userType; - List userTypeEnclosingTypes; - bool enclosingTypesInitialized; - Dictionary baseTypes; - bool baseTypesInitialized; - - [Flags] - enum CheckTypeAccess { - /// - /// Can't access the type - /// - None = 0, - - /// - /// Normal access to the type and its members. Type + member must be public, internal - /// or protected (for sub classes) to access the member. - /// - Normal = 1, - - /// - /// Full access to the type, even if the type is private. If clear, the type - /// must be public, internal or protected (for sub classes). - /// - FullTypeAccess = 2, - - /// - /// Full access to the type's members (types, fields, methods), even if the - /// members are private. If clear, the members must be public, internal - /// or protected (for sub classes) - /// - FullMemberAccess = 4, - - /// - /// Full access to the type and its members - /// - Full = Normal | FullTypeAccess | FullMemberAccess, - } - - /// - /// Gets/sets the user type which is accessing the target type, field or method - /// - public TypeDef UserType { - get { return userType; } - set { - if (userType == value) - return; - userType = value; - enclosingTypesInitialized = false; - baseTypesInitialized = false; - if (userTypeEnclosingTypes != null) - userTypeEnclosingTypes.Clear(); - if (baseTypes != null) - baseTypes.Clear(); - } - } - - /// - /// Constructor - /// - /// The type accessing the target type, field or method - public AccessChecker(TypeDef userType) { - this.userType = userType; - this.userTypeEnclosingTypes = null; - this.baseTypes = null; - this.enclosingTypesInitialized = false; - this.baseTypesInitialized = false; - } - - /// - /// Checks whether it can access a method or a field - /// - /// Operand - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(object op) { - var md = op as MethodDef; - if (md != null) - return CanAccess(md); - - var mr = op as MemberRef; - if (mr != null) - return CanAccess(mr); - - var fd = op as FieldDef; - if (fd != null) - return CanAccess(fd); - - var ms = op as MethodSpec; - if (ms != null) - return CanAccess(ms); - - var tr = op as TypeRef; - if (tr != null) - return CanAccess(tr.Resolve()); - - var td = op as TypeDef; - if (td != null) - return CanAccess(td); - - var ts = op as TypeSpec; - if (ts != null) - return CanAccess(ts); - - return null; - } - - /// - /// Checks whether it can access a - /// - /// The type - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(TypeRef tr) { - if (tr == null) - return null; - return CanAccess(tr.Resolve()); - } - - /// - /// Checks whether it can access a - /// - /// The type - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(TypeDef td) { - var access = GetTypeAccess(td, null); - if (access == null) - return null; - return (access.Value & CheckTypeAccess.Normal) != 0; - } - - /// - /// Returns the access we have to . If is - /// enclosing this type, we have private access to it and all its members. If its - /// declaring type encloses us, we have private access to it, but only normal access - /// to its members. Else, we only have normal access to it and its members. If we inherit - /// it, we have protected access to it and its members. - /// - /// The type - /// Generic instance of or null if none - CheckTypeAccess? GetTypeAccess(TypeDef td, GenericInstSig git) { - if (td == null) - return null; - if (userType == td) - return CheckTypeAccess.Full; - - // If this is our nested type, we have private access to it itself, but normal - // access to its members. - if (td.DeclaringType == userType) - return CheckTypeAccess.Normal | CheckTypeAccess.FullTypeAccess; - - // If we're not a nested type, td can't be our enclosing type - if (userType.DeclaringType == null) - return GetTypeAccess2(td, git); - - // Can't be an enclosing type if they're not in the same module - if (userType.Module != td.Module) - return GetTypeAccess2(td, git); - - var tdEncTypes = GetEnclosingTypes(td, true); - var ourEncTypes = InitializeOurEnclosingTypes(); - int maxChecks = Math.Min(tdEncTypes.Count, ourEncTypes.Count); - int commonIndex; - for (commonIndex = 0; commonIndex < maxChecks; commonIndex++) { - if (tdEncTypes[commonIndex] != ourEncTypes[commonIndex]) - break; - } - - // If td encloses us, then we have access to td and all its members even if - // they're private. - if (commonIndex == tdEncTypes.Count) - return CheckTypeAccess.Full; - - // If there are no common enclosing types, only check the visibility. - if (commonIndex == 0) - return GetTypeAccess2(td, git); - - // If td's declaring type encloses this, then we have full access to td even if - // it's private, but only normal access to its members. - if (commonIndex + 1 == tdEncTypes.Count) - return CheckTypeAccess.Normal | CheckTypeAccess.FullTypeAccess; - - // Normal visibility checks starting from type after common enclosing type. - // Note that we have full access to it so we don't need to check its access, - // so start from the next one. - for (int i = commonIndex + 1; i < tdEncTypes.Count; i++) { - if (!IsVisible(tdEncTypes[i], null)) - return CheckTypeAccess.None; - } - return CheckTypeAccess.Normal; - } - - CheckTypeAccess GetTypeAccess2(TypeDef td, GenericInstSig git) { - while (td != null) { - var declType = td.DeclaringType; - if (userType != declType && !IsVisible(td, git)) - return CheckTypeAccess.None; - td = declType; - git = null; - } - return CheckTypeAccess.Normal; - } - - /// - /// Checks whether is visible to us without checking whether they - /// have any common enclosing types. - /// - /// Type - /// Generic instance of or null if none - bool IsVisible(TypeDef td, GenericInstSig git) { - if (td == null) - return false; - if (td == userType) - return true; - - switch (td.Visibility) { - case TypeAttributes.NotPublic: - return IsSameAssemblyOrFriendAssembly(td.Module); - - case TypeAttributes.Public: - return true; - - case TypeAttributes.NestedPublic: - return true; - - case TypeAttributes.NestedPrivate: - return false; - - case TypeAttributes.NestedFamily: - return CheckFamily(td, git); - - case TypeAttributes.NestedAssembly: - return IsSameAssemblyOrFriendAssembly(td.Module); - - case TypeAttributes.NestedFamANDAssem: - return IsSameAssemblyOrFriendAssembly(td.Module) && - CheckFamily(td, git); - - case TypeAttributes.NestedFamORAssem: - return IsSameAssemblyOrFriendAssembly(td.Module) || - CheckFamily(td, git); - - default: - return false; - } - } - - bool IsSameAssemblyOrFriendAssembly(ModuleDef module) { - if (module == null) - return false; - var userModule = userType.Module; - if (userModule == null) - return false; - if (userModule == module) - return true; - var userAsm = userModule.Assembly; - var modAsm = module.Assembly; - if (IsSameAssembly(userAsm, modAsm)) - return true; - if (userAsm != null && userAsm.IsFriendAssemblyOf(modAsm)) - return true; - - return false; - } - - static bool IsSameAssembly(IAssembly asm1, IAssembly asm2) { - if (asm1 == null || asm2 == null) - return false; - if (asm1 == asm2) - return true; - return new AssemblyNameComparer(AssemblyNameComparerFlags.All).Equals(asm1, asm2); - } - - /// - /// Checks whether has access to . - /// is Family, FamANDAssem, or FamORAssem. - /// - /// Type - /// Generic instance of or null if none - bool CheckFamily(TypeDef td, GenericInstSig git) { - if (td == null) - return false; - InitializeBaseTypes(); - - if (baseTypes.ContainsKey(git == null ? (IType)td : git)) - return true; - - // td is Family, FamANDAssem, or FamORAssem. If we derive from its enclosing type, - // we have access to it. - var td2 = td.DeclaringType; - if (td2 != null && baseTypes.ContainsKey(td2)) - return true; - - // If one of our enclosing types derive from it, we also have access to it - var userDeclType = userType.DeclaringType; - if (userDeclType != null) - return new AccessChecker(userDeclType).CheckFamily(td, git); - - return false; - } - - void InitializeBaseTypes() { - if (baseTypesInitialized) - return; - if (baseTypes == null) - baseTypes = new Dictionary(TypeEqualityComparer.Instance); - baseTypesInitialized = true; - - ITypeDefOrRef baseType = userType; - while (baseType != null) { - baseTypes[baseType] = true; - baseType = baseType.GetBaseType(); - } - } - - List InitializeOurEnclosingTypes() { - if (!enclosingTypesInitialized) { - userTypeEnclosingTypes = GetEnclosingTypes(userType, true); - enclosingTypesInitialized = true; - } - return userTypeEnclosingTypes; - } - - /// - /// Returns a list of all enclosing types, in order of non-enclosed to most enclosed type - /// - /// Type - /// true if should be included - /// A list of all enclosing types - static List GetEnclosingTypes(TypeDef td, bool includeInput) { - var list = new List(); - if (includeInput && td != null) - list.Add(td); - while (td != null) { - var dt = td.DeclaringType; - if (dt == null) - break; - if (list.Contains(dt)) - break; - list.Add(dt); - td = dt; - } - list.Reverse(); - return list; - } - - /// - /// Checks whether it can access a - /// - /// The field - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(FieldDef fd) { - return CanAccess(fd, null); - } - - bool? CanAccess(FieldDef fd, GenericInstSig git) { - if (fd == null) - return null; - var access = GetTypeAccess(fd.DeclaringType, git); - if (access == null) - return null; - var acc = access.Value; - if ((acc & CheckTypeAccess.Normal) == 0) - return false; - if ((acc & CheckTypeAccess.FullMemberAccess) != 0) - return true; - - return IsVisible(fd, git); - } - - bool IsVisible(FieldDef fd, GenericInstSig git) { - if (fd == null) - return false; - var fdDeclaringType = fd.DeclaringType; - if (fdDeclaringType == null) - return false; - if (userType == fdDeclaringType) - return true; - - switch (fd.Access) { - case FieldAttributes.PrivateScope: - // Private scope aka compiler controlled fields/methods can only be accessed - // by a Field/Method token. This means they must be in the same module. - return userType.Module == fdDeclaringType.Module; - - case FieldAttributes.Private: - return false; - - case FieldAttributes.FamANDAssem: - return IsSameAssemblyOrFriendAssembly(fdDeclaringType.Module) && - CheckFamily(fdDeclaringType, git); - - case FieldAttributes.Assembly: - return IsSameAssemblyOrFriendAssembly(fdDeclaringType.Module); - - case FieldAttributes.Family: - return CheckFamily(fdDeclaringType, git); - - case FieldAttributes.FamORAssem: - return IsSameAssemblyOrFriendAssembly(fdDeclaringType.Module) || - CheckFamily(fdDeclaringType, git); - - case FieldAttributes.Public: - return true; - - default: - return false; - } - } - - /// - /// Checks whether it can access a - /// - /// The method - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(MethodDef md) { - return CanAccess(md, (GenericInstSig)null); - } - - bool? CanAccess(MethodDef md, GenericInstSig git) { - if (md == null) - return null; - var access = GetTypeAccess(md.DeclaringType, git); - if (access == null) - return null; - var acc = access.Value; - if ((acc & CheckTypeAccess.Normal) == 0) - return false; - if ((acc & CheckTypeAccess.FullMemberAccess) != 0) - return true; - - return IsVisible(md, git); - } - - bool IsVisible(MethodDef md, GenericInstSig git) { - if (md == null) - return false; - var mdDeclaringType = md.DeclaringType; - if (mdDeclaringType == null) - return false; - if (userType == mdDeclaringType) - return true; - - switch (md.Access) { - case MethodAttributes.PrivateScope: - // Private scope aka compiler controlled fields/methods can only be accessed - // by a Field/Method token. This means they must be in the same module. - return userType.Module == mdDeclaringType.Module; - - case MethodAttributes.Private: - return false; - - case MethodAttributes.FamANDAssem: - return IsSameAssemblyOrFriendAssembly(mdDeclaringType.Module) && - CheckFamily(mdDeclaringType, git); - - case MethodAttributes.Assembly: - return IsSameAssemblyOrFriendAssembly(mdDeclaringType.Module); - - case MethodAttributes.Family: - return CheckFamily(mdDeclaringType, git); - - case MethodAttributes.FamORAssem: - return IsSameAssemblyOrFriendAssembly(mdDeclaringType.Module) || - CheckFamily(mdDeclaringType, git); - - case MethodAttributes.Public: - return true; - - default: - return false; - } - } - - /// - /// Checks whether it can access a - /// - /// The member reference - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(MemberRef mr) { - if (mr == null) - return null; - - var parent = mr.Class; - - var td = parent as TypeDef; - if (td != null) - return CanAccess(td, mr); - - var tr = parent as TypeRef; - if (tr != null) - return CanAccess(tr.Resolve(), mr); - - var ts = parent as TypeSpec; - if (ts != null) - return CanAccess(ts.ResolveTypeDef(), ts.TryGetGenericInstSig(), mr); - - var md = parent as MethodDef; - if (md != null) - return CanAccess(md, mr); - - var mod = parent as ModuleRef; - if (mod != null) - return CanAccess(mod, mr); - - return null; - } - - bool? CanAccess(TypeDef td, MemberRef mr) { - return CanAccess(td, null, mr); - } - - bool? CanAccess(TypeDef td, GenericInstSig git, MemberRef mr) { - if (mr == null || td == null) - return null; - - if (mr.MethodSig != null) { - var md = td.FindMethodCheckBaseType(mr.Name, mr.MethodSig); - if (md == null) { - // Assume that it's an array type if it's one of these methods - if (mr.Name == "Get" || mr.Name == "Set" || mr.Name == "Address" || mr.Name == MethodDef.InstanceConstructorName) - return true; - return null; - } - return CanAccess(md, git); - } - - if (mr.FieldSig != null) - return CanAccess(td.FindFieldCheckBaseType(mr.Name, mr.FieldSig), git); - - return null; - } - - bool? CanAccess(MethodDef md, MemberRef mr) { - if (mr == null || md == null) - return null; - return CanAccess(md); - } - - bool? CanAccess(ModuleRef mod, MemberRef mr) { - if (mr == null || mod == null || mod.Module == null) - return null; - - var userModule = userType.Module; - if (userModule == null) - return null; - var userAsm = userModule.Assembly; - if (!IsSameAssembly(userAsm, mod.Module.Assembly)) - return false; - if (userAsm == null) - return false; - var otherMod = userAsm.FindModule(mod.Name); - if (otherMod == null) - return false; - return CanAccess(otherMod.GlobalType, mr); - } - - /// - /// Checks whether it can access a - /// - /// The type spec - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(TypeSpec ts) { - return CanAccess(ts.ResolveTypeDef()); - } - - /// - /// Checks whether it can access a - /// - /// The method spec - /// true if it has access to it, false if not, and null - /// if we can't determine it (eg. we couldn't resolve a type or input was null) - public bool? CanAccess(MethodSpec ms) { - if (ms == null) - return null; - - var mdr = ms.Method; - - var md = mdr as MethodDef; - if (md != null) - return CanAccess(md); - - var mr = mdr as MemberRef; - if (mr != null) - return CanAccess(mr); - - return null; - } - - /// - public override string ToString() { - return string.Format("{0}", userType); - } - } -} diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index bf7636313..c37ac9569 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -393,17 +393,6 @@ public ModuleDef FindModule(UTF8String name) { return null; } - /// - /// Creates an instance from a file - /// - /// File name of an existing .NET assembly - /// A new instance - /// If is null - /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(string fileName) { - return Load(fileName, (ModuleCreationOptions)null); - } - /// /// Creates an instance from a file /// @@ -424,7 +413,7 @@ public static AssemblyDef Load(string fileName, ModuleContext context) { /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(string fileName, ModuleCreationOptions options) { + public static AssemblyDef Load(string fileName, ModuleCreationOptions options = null) { if (fileName == null) throw new ArgumentNullException("fileName"); ModuleDef module = null; @@ -442,17 +431,6 @@ public static AssemblyDef Load(string fileName, ModuleCreationOptions options) { } } - /// - /// Creates an instance from a byte[] - /// - /// Contents of a .NET assembly - /// A new instance - /// If is null - /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(byte[] data) { - return Load(data, (ModuleCreationOptions)null); - } - /// /// Creates an instance from a byte[] /// @@ -473,7 +451,7 @@ public static AssemblyDef Load(byte[] data, ModuleContext context) { /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(byte[] data, ModuleCreationOptions options) { + public static AssemblyDef Load(byte[] data, ModuleCreationOptions options = null) { if (data == null) throw new ArgumentNullException("data"); ModuleDef module = null; @@ -491,17 +469,6 @@ public static AssemblyDef Load(byte[] data, ModuleCreationOptions options) { } } - /// - /// Creates an instance from a memory location - /// - /// Address of a .NET assembly - /// A new instance - /// If is null - /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(IntPtr addr) { - return Load(addr, (ModuleCreationOptions)null); - } - /// /// Creates an instance from a memory location /// @@ -522,7 +489,7 @@ public static AssemblyDef Load(IntPtr addr, ModuleContext context) { /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options) { + public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options = null) { if (addr == IntPtr.Zero) throw new ArgumentNullException("addr"); ModuleDef module = null; @@ -540,19 +507,6 @@ public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options) { } } - /// - /// Creates an instance from a stream - /// - /// This will read all bytes from the stream and call . - /// It's better to use one of the other Load() methods. - /// The stream - /// A new instance - /// If is null - /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(Stream stream) { - return Load(stream, (ModuleCreationOptions)null); - } - /// /// Creates an instance from a stream /// @@ -577,7 +531,7 @@ public static AssemblyDef Load(Stream stream, ModuleContext context) { /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(Stream stream, ModuleCreationOptions options) { + public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = null) { if (stream == null) throw new ArgumentNullException("stream"); ModuleDef module = null; @@ -651,37 +605,21 @@ public TypeDef Find(TypeRef typeRef) { return null; } - /// - /// Writes the assembly to a file on disk. If the file exists, it will be truncated. - /// - /// Filename - public void Write(string filename) { - Write(filename, null); - } - /// /// Writes the assembly to a file on disk. If the file exists, it will be truncated. /// /// Filename /// Writer options - public void Write(string filename, ModuleWriterOptions options) { + public void Write(string filename, ModuleWriterOptions options = null) { ManifestModule.Write(filename, options); } - /// - /// Writes the assembly to a stream. - /// - /// Destination stream - public void Write(Stream dest) { - Write(dest, null); - } - /// /// Writes the assembly to a stream. /// /// Destination stream /// Writer options - public void Write(Stream dest, ModuleWriterOptions options) { + public void Write(Stream dest, ModuleWriterOptions options = null) { ManifestModule.Write(dest, options); } diff --git a/src/DotNet/ElementType.cs b/src/DotNet/ElementType.cs index 341ca74a8..915974aec 100644 --- a/src/DotNet/ElementType.cs +++ b/src/DotNet/ElementType.cs @@ -111,22 +111,13 @@ public static bool IsPrimitive(this ElementType etype) { } } - /// - /// Returns the size of the element type in bytes or -1 if it's unknown - /// - /// Element type - /// - public static int GetPrimitiveSize(this ElementType etype) { - return GetPrimitiveSize(etype, -1); - } - /// /// Returns the size of the element type in bytes or -1 if it's unknown /// /// Element type /// Size of a pointer /// - public static int GetPrimitiveSize(this ElementType etype, int ptrSize) { + public static int GetPrimitiveSize(this ElementType etype, int ptrSize = -1) { switch (etype) { case ElementType.Boolean: case ElementType.I1: diff --git a/src/DotNet/FullNameCreator.cs b/src/DotNet/FullNameCreator.cs index 93c00feea..e5b12fbc0 100644 --- a/src/DotNet/FullNameCreator.cs +++ b/src/DotNet/FullNameCreator.cs @@ -171,25 +171,6 @@ public static StringBuilder NamespaceSB(IType type, bool isReflection, StringBui return sb ?? new StringBuilder(); } - /// - /// Returns the assembly qualified full name of a - /// - /// The IType - /// The assembly qualified full name - public static string AssemblyQualifiedName(IType type) { - return AssemblyQualifiedNameSB(type, null, null).ToString(); - } - - /// - /// Returns the assembly qualified full name of a - /// - /// The IType - /// Helps print the name - /// The assembly qualified full name - public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper) { - return AssemblyQualifiedNameSB(type, helper, null).ToString(); - } - /// /// Returns the assembly qualified full name of a /// @@ -197,7 +178,7 @@ public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper he /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return AssemblyQualifiedNameSB(type, helper, sb).ToString(); } @@ -232,29 +213,6 @@ public static StringBuilder AssemblyQualifiedNameSB(IType type, IFullNameCreator return sb ?? new StringBuilder(); } - /// - /// Returns the full name of a property - /// - /// Declaring type full name or null if none - /// Name of property - /// Property signature - /// Property full name - public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig) { - return PropertyFullNameSB(declaringType, name, propertySig, null, null).ToString(); - } - - /// - /// Returns the full name of a property - /// - /// Declaring type full name or null if none - /// Name of property - /// Property signature - /// Type generic arguments or null if none - /// Property full name - public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs) { - return PropertyFullNameSB(declaringType, name, propertySig, typeGenArgs, null).ToString(); - } - /// /// Returns the full name of a property /// @@ -264,7 +222,7 @@ public static string PropertyFullName(string declaringType, UTF8String name, Cal /// Type generic arguments or null if none /// String builder to use or null /// Property full name - public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs, StringBuilder sb) { + public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs = null, StringBuilder sb = null) { return PropertyFullNameSB(declaringType, name, propertySig, typeGenArgs, sb).ToString(); } @@ -288,29 +246,6 @@ public static StringBuilder PropertyFullNameSB(string declaringType, UTF8String return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of an event - /// - /// Declaring type full name or null if none - /// Name of event - /// Event type - /// Event full name - public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef) { - return EventFullNameSB(declaringType, name, typeDefOrRef, null, null).ToString(); - } - - /// - /// Returns the full name of a property - /// - /// Declaring type full name or null if none - /// Name of property - /// Event type - /// Type generic arguments or null if none - /// Property full name - public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs) { - return EventFullNameSB(declaringType, name, typeDefOrRef, typeGenArgs, null).ToString(); - } - /// /// Returns the full name of a property /// @@ -320,7 +255,7 @@ public static string EventFullName(string declaringType, UTF8String name, ITypeD /// Type generic arguments or null if none /// String builder to use or null /// Property full name - public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs, StringBuilder sb) { + public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs = null, StringBuilder sb = null) { return EventFullNameSB(declaringType, name, typeDefOrRef, typeGenArgs, sb).ToString(); } @@ -344,52 +279,6 @@ public static StringBuilder EventFullNameSB(string declaringType, UTF8String nam return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a field - /// - /// Declaring type full name or null if none - /// Name of field - /// Field signature - /// Field full name - public static string FieldFullName(string declaringType, UTF8String name, FieldSig fieldSig) { - return FieldFullNameSB(declaringType, UTF8String.ToSystemString(name), fieldSig, null, null).ToString(); - } - - /// - /// Returns the full name of a field - /// - /// Declaring type full name or null if none - /// Name of field - /// Field signature - /// Type generic arguments or null if none - /// Field full name - public static string FieldFullName(string declaringType, UTF8String name, FieldSig fieldSig, IList typeGenArgs) { - return FieldFullNameSB(declaringType, UTF8String.ToSystemString(name), fieldSig, typeGenArgs, null).ToString(); - } - - /// - /// Returns the full name of a field - /// - /// Declaring type full name or null if none - /// Name of field - /// Field signature - /// Field full name - public static string FieldFullName(string declaringType, string name, FieldSig fieldSig) { - return FieldFullNameSB(declaringType, name, fieldSig, null, null).ToString(); - } - - /// - /// Returns the full name of a field - /// - /// Declaring type full name or null if none - /// Name of field - /// Field signature - /// Type generic arguments or null if none - /// Field full name - public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs) { - return FieldFullNameSB(declaringType, name, fieldSig, typeGenArgs, null).ToString(); - } - /// /// Returns the full name of a field /// @@ -399,7 +288,7 @@ public static string FieldFullName(string declaringType, string name, FieldSig f /// Type generic arguments or null if none /// String builder to use or null /// Field full name - public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs, StringBuilder sb) { + public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs = null, StringBuilder sb = null) { return FieldFullNameSB(declaringType, name, fieldSig, typeGenArgs, sb).ToString(); } @@ -423,92 +312,6 @@ public static StringBuilder FieldFullNameSB(string declaringType, string name, F return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Method full name - public static string MethodFullName(string declaringType, UTF8String name, MethodSig methodSig) { - return MethodFullNameSB(declaringType, UTF8String.ToSystemString(name), methodSig, null, null, null, null).ToString(); - } - - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Type generic arguments or null if none - /// Method full name - public static string MethodFullName(string declaringType, UTF8String name, MethodSig methodSig, IList typeGenArgs) { - return MethodFullNameSB(declaringType, UTF8String.ToSystemString(name), methodSig, typeGenArgs, null, null, null).ToString(); - } - - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Type generic arguments or null if none - /// Method generic arguments or null if none - /// Method full name - public static string MethodFullName(string declaringType, UTF8String name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs) { - return MethodFullNameSB(declaringType, UTF8String.ToSystemString(name), methodSig, typeGenArgs, methodGenArgs, null, null).ToString(); - } - - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Method full name - public static string MethodFullName(string declaringType, string name, MethodSig methodSig) { - return MethodFullNameSB(declaringType, name, methodSig, null, null, null, null).ToString(); - } - - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Type generic arguments or null if none - /// Method full name - public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs) { - return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, null, null, null).ToString(); - } - - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Type generic arguments or null if none - /// Method generic arguments or null if none - /// Method full name - public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs) { - return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, null, null).ToString(); - } - - /// - /// Returns the full name of a method - /// - /// Declaring type full name or null if none - /// Name of method or null if none - /// Method signature - /// Type generic arguments or null if none - /// Method generic arguments or null if none - /// Generic parameter owner method or null - /// Method full name - public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod) { - return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, gppMethod, null).ToString(); - } - /// /// Returns the full name of a method /// @@ -520,7 +323,7 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Generic parameter owner method or null /// String builder to use or null /// Method full name - public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod, StringBuilder sb) { + public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs = null, IList methodGenArgs = null, MethodDef gppMethod = null, StringBuilder sb = null) { return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, gppMethod, sb).ToString(); } @@ -547,40 +350,13 @@ public static StringBuilder MethodFullNameSB(string declaringType, string name, return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a method sig - /// - /// Method sig - /// Method sig full name - public static string MethodSigFullName(MethodSig methodSig) { - return MethodBaseSigFullNameSB(methodSig, null).ToString(); - } - - /// - /// Returns the full name of a property sig - /// - /// Property sig - /// Property sig full name - public static string PropertySigFullName(PropertySig propertySig) { - return MethodBaseSigFullNameSB(propertySig, null).ToString(); - } - - /// - /// Returns the full name of a property sig - /// - /// Property sig - /// Property sig full name - public static string MethodBaseSigFullName(MethodBaseSig sig) { - return MethodBaseSigFullNameSB(sig, null).ToString(); - } - /// /// Returns the full name of a property sig /// /// Property sig /// String builder to use or null /// Property sig full name - public static string MethodBaseSigFullName(MethodBaseSig sig, StringBuilder sb) { + public static string MethodBaseSigFullName(MethodBaseSig sig, StringBuilder sb = null) { return MethodBaseSigFullNameSB(sig, sb).ToString(); } @@ -596,18 +372,6 @@ public static StringBuilder MethodBaseSigFullNameSB(MethodBaseSig sig, StringBui return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a sig - /// - /// Declaring type or null - /// Name or null - /// Method sig - /// Owner method or null - /// Sig full name - public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod) { - return MethodBaseSigFullNameSB(declType, name, sig, gppMethod, null).ToString(); - } - /// /// Returns the full name of a sig /// @@ -617,7 +381,7 @@ public static string MethodBaseSigFullName(string declType, string name, MethodB /// Owner method or null /// String builder to use or null /// Sig full name - public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb) { + public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb = null) { return MethodBaseSigFullNameSB(declType, name, sig, gppMethod, sb).ToString(); } @@ -636,16 +400,6 @@ public static StringBuilder MethodBaseSigFullNameSB(string declType, string name return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the namespace of a - /// - /// The TypeRef - /// Set if output should be compatible with reflection - /// The namespace - public static string Namespace(TypeRef typeRef, bool isReflection) { - return NamespaceSB(typeRef, isReflection, null).ToString(); - } - /// /// Returns the namespace of a /// @@ -653,7 +407,7 @@ public static string Namespace(TypeRef typeRef, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder sb) { + public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder sb = null) { return NamespaceSB(typeRef, isReflection, sb).ToString(); } @@ -670,16 +424,6 @@ public static StringBuilder NamespaceSB(TypeRef typeRef, bool isReflection, Stri return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the name of a - /// - /// The TypeRef - /// Set if output should be compatible with reflection - /// The name - public static string Name(TypeRef typeRef, bool isReflection) { - return NameSB(typeRef, isReflection, null).ToString(); - } - /// /// Returns the name of a /// @@ -687,7 +431,7 @@ public static string Name(TypeRef typeRef, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb) { + public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb = null) { return NameSB(typeRef, isReflection, sb).ToString(); } @@ -704,27 +448,6 @@ public static StringBuilder NameSB(TypeRef typeRef, bool isReflection, StringBui return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a - /// - /// The TypeRef - /// Set if output should be compatible with reflection - /// The full name - public static string FullName(TypeRef typeRef, bool isReflection) { - return FullNameSB(typeRef, isReflection, null, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The TypeRef - /// Set if output should be compatible with reflection - /// Helps print the name - /// The full name - public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper) { - return FullNameSB(typeRef, isReflection, helper, null).ToString(); - } - /// /// Returns the full name of a /// @@ -733,7 +456,7 @@ public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreat /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return FullNameSB(typeRef, isReflection, helper, sb).ToString(); } @@ -751,25 +474,6 @@ public static StringBuilder FullNameSB(TypeRef typeRef, bool isReflection, IFull return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeRef - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeRef typeRef) { - return AssemblyQualifiedNameSB(typeRef, null, null).ToString(); - } - - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeRef - /// Helps print the name - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper) { - return AssemblyQualifiedNameSB(typeRef, helper, null).ToString(); - } - /// /// Returns the assembly qualified full name of a /// @@ -777,7 +481,7 @@ public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelp /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return AssemblyQualifiedNameSB(typeRef, helper, sb).ToString(); } @@ -821,16 +525,6 @@ public static ModuleDef OwnerModule(TypeRef typeRef) { return new FullNameCreator().GetOwnerModule(typeRef); } - /// - /// Returns the namespace of a - /// - /// The TypeDef - /// Set if output should be compatible with reflection - /// The namespace - public static string Namespace(TypeDef typeDef, bool isReflection) { - return NamespaceSB(typeDef, isReflection, null).ToString(); - } - /// /// Returns the namespace of a /// @@ -838,7 +532,7 @@ public static string Namespace(TypeDef typeDef, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder sb) { + public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder sb = null) { return NamespaceSB(typeDef, isReflection, sb).ToString(); } @@ -855,16 +549,6 @@ public static StringBuilder NamespaceSB(TypeDef typeDef, bool isReflection, Stri return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the name of a - /// - /// The TypeDef - /// Set if output should be compatible with reflection - /// The name - public static string Name(TypeDef typeDef, bool isReflection) { - return NameSB(typeDef, isReflection, null).ToString(); - } - /// /// Returns the name of a /// @@ -872,7 +556,7 @@ public static string Name(TypeDef typeDef, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeDef typeDef, bool isReflection, StringBuilder sb) { + public static string Name(TypeDef typeDef, bool isReflection, StringBuilder sb = null) { return NameSB(typeDef, isReflection, sb).ToString(); } @@ -889,27 +573,6 @@ public static StringBuilder NameSB(TypeDef typeDef, bool isReflection, StringBui return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a - /// - /// The TypeDef - /// Set if output should be compatible with reflection - /// The full name - public static string FullName(TypeDef typeDef, bool isReflection) { - return FullNameSB(typeDef, isReflection, null, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The TypeDef - /// Set if output should be compatible with reflection - /// Helps print the name - /// The full name - public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper) { - return FullNameSB(typeDef, isReflection, helper, null).ToString(); - } - /// /// Returns the full name of a /// @@ -918,7 +581,7 @@ public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreat /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return FullNameSB(typeDef, isReflection, helper, sb).ToString(); } @@ -936,25 +599,6 @@ public static StringBuilder FullNameSB(TypeDef typeDef, bool isReflection, IFull return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeDef - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeDef typeDef) { - return AssemblyQualifiedNameSB(typeDef, null, null).ToString(); - } - - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeDef - /// Helps print the name - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper) { - return AssemblyQualifiedNameSB(typeDef, helper, null).ToString(); - } - /// /// Returns the assembly qualified full name of a /// @@ -962,7 +606,7 @@ public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelp /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return AssemblyQualifiedNameSB(typeDef, helper, sb).ToString(); } @@ -997,16 +641,6 @@ public static ModuleDef OwnerModule(TypeDef typeDef) { return new FullNameCreator().GetOwnerModule(typeDef); } - /// - /// Returns the namespace of a - /// - /// The TypeSpec - /// Set if output should be compatible with reflection - /// The namespace - public static string Namespace(TypeSpec typeSpec, bool isReflection) { - return NamespaceSB(typeSpec, isReflection, null).ToString(); - } - /// /// Returns the namespace of a /// @@ -1014,7 +648,7 @@ public static string Namespace(TypeSpec typeSpec, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { + public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuilder sb = null) { return NamespaceSB(typeSpec, isReflection, sb).ToString(); } @@ -1031,16 +665,6 @@ public static StringBuilder NamespaceSB(TypeSpec typeSpec, bool isReflection, St return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the name of a - /// - /// The TypeSpec - /// Set if output should be compatible with reflection - /// The name - public static string Name(TypeSpec typeSpec, bool isReflection) { - return NameSB(typeSpec, isReflection, null).ToString(); - } - /// /// Returns the name of a /// @@ -1048,7 +672,7 @@ public static string Name(TypeSpec typeSpec, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { + public static string Name(TypeSpec typeSpec, bool isReflection, StringBuilder sb = null) { return NameSB(typeSpec, isReflection, sb).ToString(); } @@ -1065,27 +689,6 @@ public static StringBuilder NameSB(TypeSpec typeSpec, bool isReflection, StringB return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a - /// - /// The TypeSpec - /// Set if output should be compatible with reflection - /// The full name - public static string FullName(TypeSpec typeSpec, bool isReflection) { - return FullNameSB(typeSpec, isReflection, null, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The TypeSpec - /// Set if output should be compatible with reflection - /// Helps print the name - /// The full name - public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper) { - return FullNameSB(typeSpec, isReflection, helper, null).ToString(); - } - /// /// Returns the full name of a /// @@ -1094,7 +697,7 @@ public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCre /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return FullNameSB(typeSpec, isReflection, helper, sb).ToString(); } @@ -1112,25 +715,6 @@ public static StringBuilder FullNameSB(TypeSpec typeSpec, bool isReflection, IFu return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeSpec - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSpec typeSpec) { - return AssemblyQualifiedNameSB(typeSpec, null, null).ToString(); - } - - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeSpec - /// Helps print the name - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper) { - return AssemblyQualifiedNameSB(typeSpec, helper, null).ToString(); - } - /// /// Returns the assembly qualified full name of a /// @@ -1138,7 +722,7 @@ public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHe /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return AssemblyQualifiedNameSB(typeSpec, helper, sb).ToString(); } @@ -1191,16 +775,6 @@ public static ModuleDef OwnerModule(TypeSpec typeSpec) { return new FullNameCreator().GetOwnerModule(typeSpec); } - /// - /// Returns the namespace of a - /// - /// The type sig - /// Set if output should be compatible with reflection - /// The namespace - public static string Namespace(TypeSig typeSig, bool isReflection) { - return NamespaceSB(typeSig, isReflection, null).ToString(); - } - /// /// Returns the namespace of a /// @@ -1208,7 +782,7 @@ public static string Namespace(TypeSig typeSig, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder sb) { + public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder sb = null) { return NamespaceSB(typeSig, isReflection, sb).ToString(); } @@ -1225,16 +799,6 @@ public static StringBuilder NamespaceSB(TypeSig typeSig, bool isReflection, Stri return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the name of a - /// - /// The type sig - /// Set if output should be compatible with reflection - /// The name - public static string Name(TypeSig typeSig, bool isReflection) { - return NameSB(typeSig, isReflection, null).ToString(); - } - /// /// Returns the name of a /// @@ -1242,7 +806,7 @@ public static string Name(TypeSig typeSig, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeSig typeSig, bool isReflection, StringBuilder sb) { + public static string Name(TypeSig typeSig, bool isReflection, StringBuilder sb = null) { return NameSB(typeSig, isReflection, sb).ToString(); } @@ -1259,52 +823,6 @@ public static StringBuilder NameSB(TypeSig typeSig, bool isReflection, StringBui return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a - /// - /// The type sig - /// Set if output should be compatible with reflection - /// The full name - public static string FullName(TypeSig typeSig, bool isReflection) { - return FullNameSB(typeSig, isReflection, null, null, null, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The type sig - /// Set if output should be compatible with reflection - /// Helps print the name - /// The full name - public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper) { - return FullNameSB(typeSig, isReflection, helper, null, null, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The type sig - /// Set if output should be compatible with reflection - /// Type generic args or null if none - /// Method generic args or null if none - /// The full name - public static string FullName(TypeSig typeSig, bool isReflection, IList typeGenArgs, IList methodGenArgs) { - return FullNameSB(typeSig, isReflection, null, typeGenArgs, methodGenArgs, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The type sig - /// Set if output should be compatible with reflection - /// Helps print the name - /// Type generic args or null if none - /// Method generic args or null if none - /// The full name - public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper, IList typeGenArgs, IList methodGenArgs) { - return FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, null).ToString(); - } - /// /// Returns the full name of a /// @@ -1315,7 +833,7 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreat /// Method generic args or null if none /// String builder to use or null /// The full name - public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { + public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper = null, IList typeGenArgs = null, IList methodGenArgs = null, StringBuilder sb = null) { return FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, sb).ToString(); } @@ -1341,25 +859,6 @@ public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFull return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeSig - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSig typeSig) { - return AssemblyQualifiedNameSB(typeSig, null, null).ToString(); - } - - /// - /// Returns the assembly qualified full name of a - /// - /// The TypeSig - /// Helps print the name - /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper) { - return AssemblyQualifiedNameSB(typeSig, helper, null).ToString(); - } - /// /// Returns the assembly qualified full name of a /// @@ -1367,7 +866,7 @@ public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelp /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return AssemblyQualifiedNameSB(typeSig, helper, sb).ToString(); } @@ -1420,16 +919,6 @@ public static ModuleDef OwnerModule(TypeSig typeSig) { return new FullNameCreator().GetOwnerModule(typeSig); } - /// - /// Returns the namespace of a - /// - /// The ExportedType - /// Set if output should be compatible with reflection - /// The namespace - public static string Namespace(ExportedType exportedType, bool isReflection) { - return NamespaceSB(exportedType, isReflection, null).ToString(); - } - /// /// Returns the namespace of a /// @@ -1437,7 +926,7 @@ public static string Namespace(ExportedType exportedType, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(ExportedType exportedType, bool isReflection, StringBuilder sb) { + public static string Namespace(ExportedType exportedType, bool isReflection, StringBuilder sb = null) { return NamespaceSB(exportedType, isReflection, sb).ToString(); } @@ -1454,16 +943,6 @@ public static StringBuilder NamespaceSB(ExportedType exportedType, bool isReflec return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the name of a - /// - /// The ExportedType - /// Set if output should be compatible with reflection - /// The name - public static string Name(ExportedType exportedType, bool isReflection) { - return NameSB(exportedType, isReflection, null).ToString(); - } - /// /// Returns the name of a /// @@ -1471,7 +950,7 @@ public static string Name(ExportedType exportedType, bool isReflection) { /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(ExportedType exportedType, bool isReflection, StringBuilder sb) { + public static string Name(ExportedType exportedType, bool isReflection, StringBuilder sb = null) { return NameSB(exportedType, isReflection, sb).ToString(); } @@ -1488,27 +967,6 @@ public static StringBuilder NameSB(ExportedType exportedType, bool isReflection, return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the full name of a - /// - /// The ExportedType - /// Set if output should be compatible with reflection - /// The full name - public static string FullName(ExportedType exportedType, bool isReflection) { - return FullNameSB(exportedType, isReflection, null, null).ToString(); - } - - /// - /// Returns the full name of a - /// - /// The ExportedType - /// Set if output should be compatible with reflection - /// Helps print the name - /// The full name - public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper) { - return FullNameSB(exportedType, isReflection, helper, null).ToString(); - } - /// /// Returns the full name of a /// @@ -1517,7 +975,7 @@ public static string FullName(ExportedType exportedType, bool isReflection, IFul /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return FullNameSB(exportedType, isReflection, helper, sb).ToString(); } @@ -1535,25 +993,6 @@ public static StringBuilder FullNameSB(ExportedType exportedType, bool isReflect return fnc.sb ?? new StringBuilder(); } - /// - /// Returns the assembly qualified full name of a - /// - /// The ExportedType - /// The assembly qualified full name - public static string AssemblyQualifiedName(ExportedType exportedType) { - return AssemblyQualifiedNameSB(exportedType, null, null).ToString(); - } - - /// - /// Returns the assembly qualified full name of a - /// - /// The ExportedType - /// Helps print the name - /// The assembly qualified full name - public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper) { - return AssemblyQualifiedNameSB(exportedType, helper, null).ToString(); - } - /// /// Returns the assembly qualified full name of a /// @@ -1561,7 +1000,7 @@ public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameC /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper, StringBuilder sb) { + public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { return AssemblyQualifiedNameSB(exportedType, helper, sb).ToString(); } diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index e84ae43e9..aeea800ff 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -177,16 +177,6 @@ public static AssemblyRef ToAssemblyRef(this IAssembly asm) { return new AssemblyRefUser(asm.Name, asm.Version, asm.PublicKeyOrToken, asm.Culture) { Attributes = asm.Attributes }; } - /// - /// Converts to a - /// - /// The type - /// A instance or null if - /// is invalid - public static TypeSig ToTypeSig(this ITypeDefOrRef type) { - return ToTypeSig(type, true); - } - /// /// Converts to a /// @@ -195,7 +185,7 @@ public static TypeSig ToTypeSig(this ITypeDefOrRef type) { /// is a /// A instance or null if /// is invalid - public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType) { + public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType = true) { if (type == null) return null; @@ -372,16 +362,6 @@ public static ITypeDefOrRef GetBaseTypeThrow(this ITypeDefOrRef tdr) { return tdr.GetBaseType(true); } - /// - /// Returns the base type of - /// - /// The type - /// The base type or null if there's no base type, or if - /// we couldn't resolve a - public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr) { - return tdr.GetBaseType(false); - } - /// /// Returns the base type of /// @@ -392,7 +372,7 @@ public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr) { /// The base type or null if there's no base type, or if /// is true and we couldn't resolve /// a - public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnResolveFailure) { + public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnResolveFailure = false) { var td = tdr as TypeDef; if (td != null) return td.BaseType; diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index be0585d99..08cf86032 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -54,48 +54,18 @@ public struct Importer { RecursionCounter recursionCounter; ImporterOptions options; - /// - /// Gets/sets the bit - /// - public bool TryToUseTypeDefs { + bool TryToUseTypeDefs { get { return (options & ImporterOptions.TryToUseTypeDefs) != 0; } - set { - if (value) - options |= ImporterOptions.TryToUseTypeDefs; - else - options &= ~ImporterOptions.TryToUseTypeDefs; - } } - /// - /// Gets/sets the bit - /// - public bool TryToUseMethodDefs { + bool TryToUseMethodDefs { get { return (options & ImporterOptions.TryToUseMethodDefs) != 0; } - set { - if (value) - options |= ImporterOptions.TryToUseMethodDefs; - else - options &= ~ImporterOptions.TryToUseMethodDefs; - } } - /// - /// Gets/sets the bit - /// - public bool TryToUseFieldDefs { + bool TryToUseFieldDefs { get { return (options & ImporterOptions.TryToUseFieldDefs) != 0; } - set { - if (value) - options |= ImporterOptions.TryToUseFieldDefs; - else - options &= ~ImporterOptions.TryToUseFieldDefs; - } } - /// - /// Gets/sets the bit - /// bool FixSignature { get { return (options & ImporterOptions.FixSignature) != 0; } set { diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index b071c64ea..c298c818b 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1336,15 +1336,6 @@ public TypeDef Find(ITypeDefOrRef typeRef) { return null; } - /// - /// Creates a new instance. There should normally only be one - /// instance shared by all s. - /// - /// A new instance - public static ModuleContext CreateModuleContext() { - return CreateModuleContext(true); - } - /// /// Creates a new instance. There should normally only be one /// instance shared by all s. @@ -1352,7 +1343,7 @@ public static ModuleContext CreateModuleContext() { /// If true, add other common assembly search /// paths, not just the module search paths and the GAC. /// A new instance - public static ModuleContext CreateModuleContext(bool addOtherSearchPaths) { + public static ModuleContext CreateModuleContext(bool addOtherSearchPaths = true) { var ctx = new ModuleContext(); var asmRes = new AssemblyResolver(ctx, addOtherSearchPaths); var res = new Resolver(asmRes); @@ -1361,20 +1352,12 @@ public static ModuleContext CreateModuleContext(bool addOtherSearchPaths) { return ctx; } - /// - /// Load everything in this module. All types, fields, asm refs, etc are loaded, all their - /// properties are read to make sure everything is cached. - /// - public void LoadEverything() { - LoadEverything(null); - } - /// /// Load everything in this module. All types, fields, asm refs, etc are loaded, all their /// properties are read to make sure everything is cached. /// /// Cancellation token or null - public virtual void LoadEverything(ICancellationToken cancellationToken) { + public virtual void LoadEverything(ICancellationToken cancellationToken = null) { ModuleLoader.LoadAll(this, cancellationToken); } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 0273c2bbd..399f86776 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -148,15 +148,6 @@ protected override VTableFixups GetVTableFixups_NoLock() { return new VTableFixups(this); } - /// - /// Creates a instance from a file - /// - /// File name of an existing .NET module/assembly - /// A new instance - public static ModuleDefMD Load(string fileName) { - return Load(fileName, (ModuleCreationOptions)null); - } - /// /// Creates a instance from a file /// @@ -173,19 +164,10 @@ public static ModuleDefMD Load(string fileName, ModuleContext context) { /// File name of an existing .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(string fileName, ModuleCreationOptions options) { + public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) { return Load(MetaDataCreator.Load(fileName), options); } - /// - /// Creates a instance from a byte[] - /// - /// Contents of a .NET module/assembly - /// A new instance - public static ModuleDefMD Load(byte[] data) { - return Load(data, (ModuleCreationOptions)null); - } - /// /// Creates a instance from a byte[] /// @@ -202,7 +184,7 @@ public static ModuleDefMD Load(byte[] data, ModuleContext context) { /// Contents of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options) { + public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) { return Load(MetaDataCreator.Load(data), options); } @@ -350,7 +332,7 @@ public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, Image /// /// Creates a instance from a stream /// - /// This will read all bytes from the stream and call . + /// This will read all bytes from the stream and call . /// It's better to use one of the other Load() methods. /// The stream (owned by caller) /// A new instance diff --git a/src/DotNet/UTF8String.cs b/src/DotNet/UTF8String.cs index be3524e67..0f945dd9d 100644 --- a/src/DotNet/UTF8String.cs +++ b/src/DotNet/UTF8String.cs @@ -51,7 +51,7 @@ public sealed class UTF8String : IEquatable, IComparable public string String { get { if (asString == null) - Interlocked.CompareExchange(ref asString, ConvertFromUTF8(data), null); + asString = ConvertFromUTF8(data); return asString; } } diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index 011f476ca..37a5a2cdb 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -16,5 +16,5 @@ [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] -[assembly: AssemblyVersion("1.5.0.1500")] -[assembly: AssemblyFileVersion("1.5.0.1500")] +[assembly: AssemblyVersion("1.6.0.0")] +[assembly: AssemblyFileVersion("1.6.0.0")] diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 5405189bb..4e40add82 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -37,7 +37,6 @@ true - From 6f2a41b1106b7be69d6b98e9fcebdf39376d5dde Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 14 May 2016 17:24:53 +0200 Subject: [PATCH 012/511] Update corlib asm ref detection code --- src/DotNet/ModuleDefMD.cs | 52 +++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 399f86776..322ddfd54 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -654,22 +654,48 @@ AssemblyRef FindCorLibAssemblyRef() { /// /// AssemblyRef CreateDefaultCorLibAssemblyRef() { - AssemblyRef asmRef; var asm = Assembly; if (asm != null && Find("System.Int32", false) != null) - asmRef = new AssemblyRefUser(asm); - else if (this.IsClr40) - asmRef = AssemblyRefUser.CreateMscorlibReferenceCLR40(); - else if (this.IsClr20) - asmRef = AssemblyRefUser.CreateMscorlibReferenceCLR20(); - else if (this.IsClr11) - asmRef = AssemblyRefUser.CreateMscorlibReferenceCLR11(); - else if (this.IsClr10) - asmRef = AssemblyRefUser.CreateMscorlibReferenceCLR10(); - else - asmRef = AssemblyRefUser.CreateMscorlibReferenceCLR40(); - return UpdateRowId(asmRef); + return UpdateRowId(new AssemblyRefUser(asm)); + + var asmRef = GetAlternativeCorLibReference(); + if (asmRef != null) + return UpdateRowId(asmRef); + + if (this.IsClr40) + return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR40()); + if (this.IsClr20) + return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20()); + if (this.IsClr11) + return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR11()); + if (this.IsClr10) + return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR10()); + return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR40()); + } + + AssemblyRef GetAlternativeCorLibReference() { + foreach (var asmRef in GetAssemblyRefs()) { + if (IsAssemblyRef(asmRef, systemRuntimeName, contractsPublicKeyToken)) + return asmRef; + } + foreach (var asmRef in GetAssemblyRefs()) { + if (IsAssemblyRef(asmRef, corefxName, contractsPublicKeyToken)) + return asmRef; + } + return null; + } + + static bool IsAssemblyRef(AssemblyRef asmRef, UTF8String name, PublicKeyToken token) { + if (asmRef.Name != name) + return false; + var pkot = asmRef.PublicKeyOrToken; + if (pkot == null) + return false; + return token.Equals(pkot.Token); } + static readonly UTF8String systemRuntimeName = new UTF8String("System.Runtime"); + static readonly UTF8String corefxName = new UTF8String("corefx"); + static readonly PublicKeyToken contractsPublicKeyToken = new PublicKeyToken("b03f5f7f11d50a3a"); /// protected override void Dispose(bool disposing) { From d08614fc5a6d50d1ed0b3c6528704052ab9906c6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 9 Jul 2016 12:41:32 +0200 Subject: [PATCH 013/511] Support new Mono GAC paths; fix mcs warnings --- src/DotNet/AssemblyResolver.cs | 18 +++++++++------- src/DotNet/ClassLayout.cs | 4 ---- src/DotNet/Constant.cs | 4 ---- src/DotNet/DeclSecurityReader.cs | 2 +- src/DotNet/ImplMap.cs | 4 ---- src/DotNet/ModuleRef.cs | 2 +- src/DotNet/Pdb/Dss/ImageStreamIStream.cs | 4 ++-- src/DotNet/Pdb/Dss/StreamIStream.cs | 6 +++--- src/DotNet/Pdb/Managed/DbiModule.cs | 2 +- src/DotNet/Pdb/Managed/PdbReader.cs | 4 ++-- src/DotNet/Resources/ResourceReader.cs | 2 +- src/DotNet/StrongNameKey.cs | 2 +- src/Threading/IThreadSafeList.cs | 26 ++++++++++++------------ 13 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index c5ea343e3..01bc83faa 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -25,10 +25,11 @@ public class AssemblyResolver : IAssemblyResolver { static readonly string[] winMDAssemblyExtensions = new string[] { ".winmd" }; static readonly List gacInfos; - static readonly List extraMonoPaths; + static readonly string[] extraMonoPaths; static readonly string[] monoVerDirs = new string[] { - "4.5", "4.0", - "3.5", "3.0", "2.0", + // The "-api" dirs are reference assembly dirs. + "4.5", @"4.5\Facades", "4.5-api", @"4.5-api\Facades", "4.0", "4.0-api", + "3.5", "3.5-api", "3.0", "3.0-api", "2.0", "2.0-api", "1.1", "1.0", }; @@ -64,7 +65,7 @@ static AssemblyResolver() { if (Type.GetType("Mono.Runtime") != null) { var dirs = new Dictionary(StringComparer.OrdinalIgnoreCase); - extraMonoPaths = new List(); + var extraMonoPathsList = new List(); foreach (var prefix in FindMonoPrefixes()) { var dir = Path.Combine(Path.Combine(Path.Combine(prefix, "lib"), "mono"), "gac"); if (dirs.ContainsKey(dir)) @@ -79,9 +80,11 @@ static AssemblyResolver() { dir = Path.GetDirectoryName(dir); foreach (var verDir in monoVerDirs) { - var dir2 = Path.Combine(dir, verDir); + var dir2 = dir; + foreach (var d in verDir.Split(new char[] { '\\' })) + dir2 = Path.Combine(dir2, d); if (Directory.Exists(dir2)) - extraMonoPaths.Add(dir2); + extraMonoPathsList.Add(dir2); } } @@ -89,9 +92,10 @@ static AssemblyResolver() { if (paths != null) { foreach (var path in paths.Split(Path.PathSeparator)) { if (path != string.Empty && Directory.Exists(path)) - extraMonoPaths.Add(path); + extraMonoPathsList.Add(path); } } + extraMonoPaths = extraMonoPathsList.ToArray(); } else { var windir = Environment.GetEnvironmentVariable("WINDIR"); diff --git a/src/DotNet/ClassLayout.cs b/src/DotNet/ClassLayout.cs index 8c93448c0..bc59668b5 100644 --- a/src/DotNet/ClassLayout.cs +++ b/src/DotNet/ClassLayout.cs @@ -70,9 +70,6 @@ public ClassLayoutUser(ushort packingSize, uint classSize) { /// Created from a row in the ClassLayout table /// sealed class ClassLayoutMD : ClassLayout, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - readonly uint origRid; /// @@ -96,7 +93,6 @@ public ClassLayoutMD(ModuleDefMD readerModule, uint rid) { #endif this.origRid = rid; this.rid = rid; - this.readerModule = readerModule; this.classSize = readerModule.TablesStream.ReadClassLayoutRow(origRid, out this.packingSize); } } diff --git a/src/DotNet/Constant.cs b/src/DotNet/Constant.cs index b9e28e4e2..750948b31 100644 --- a/src/DotNet/Constant.cs +++ b/src/DotNet/Constant.cs @@ -101,9 +101,6 @@ static ElementType GetElementType(object value) { /// Created from a row in the Constant table /// sealed class ConstantMD : Constant, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - readonly uint origRid; /// @@ -127,7 +124,6 @@ public ConstantMD(ModuleDefMD readerModule, uint rid) { #endif this.origRid = rid; this.rid = rid; - this.readerModule = readerModule; uint value = readerModule.TablesStream.ReadConstantRow(origRid, out this.type); this.value = GetValue(this.type, readerModule.BlobStream.ReadNoNull(value)); } diff --git a/src/DotNet/DeclSecurityReader.cs b/src/DotNet/DeclSecurityReader.cs index 6b9c975c2..a62ac6b7c 100644 --- a/src/DotNet/DeclSecurityReader.cs +++ b/src/DotNet/DeclSecurityReader.cs @@ -117,7 +117,7 @@ ThreadSafe.IList ReadBinaryFormat() { var name = ReadUTF8String(); // Use CA search rules. Some tools don't write the fully qualified name. var attrRef = TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(name), new CAAssemblyRefFinder(module), gpContext); - int blobLength = (int)reader.ReadCompressedUInt32(); + /*int blobLength = (int)*/reader.ReadCompressedUInt32(); int numNamedArgs = (int)reader.ReadCompressedUInt32(); var namedArgs = CustomAttributeReader.ReadNamedArguments(module, reader, numNamedArgs, gpContext); if (namedArgs == null) diff --git a/src/DotNet/ImplMap.cs b/src/DotNet/ImplMap.cs index 60d24926b..b296c0d58 100644 --- a/src/DotNet/ImplMap.cs +++ b/src/DotNet/ImplMap.cs @@ -301,9 +301,6 @@ public ImplMapUser(ModuleRef scope, UTF8String name, PInvokeAttributes flags) { /// Created from a row in the ImplMap table /// sealed class ImplMapMD : ImplMap, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - readonly uint origRid; /// @@ -327,7 +324,6 @@ public ImplMapMD(ModuleDefMD readerModule, uint rid) { #endif this.origRid = rid; this.rid = rid; - this.readerModule = readerModule; uint name; uint scope = readerModule.TablesStream.ReadImplMapRow(origRid, out this.attributes, out name); this.name = readerModule.StringsStream.ReadNoNull(name); diff --git a/src/DotNet/ModuleRef.cs b/src/DotNet/ModuleRef.cs index e0fb2ad0e..00fca704b 100644 --- a/src/DotNet/ModuleRef.cs +++ b/src/DotNet/ModuleRef.cs @@ -141,8 +141,8 @@ public ModuleRefUser(ModuleDef module) /// /// Constructor - /// Owner module /// + /// Owner module /// Module name public ModuleRefUser(ModuleDef module, UTF8String name) { this.module = module; diff --git a/src/DotNet/Pdb/Dss/ImageStreamIStream.cs b/src/DotNet/Pdb/Dss/ImageStreamIStream.cs index 1e0178671..8ed512a02 100644 --- a/src/DotNet/Pdb/Dss/ImageStreamIStream.cs +++ b/src/DotNet/Pdb/Dss/ImageStreamIStream.cs @@ -68,10 +68,10 @@ public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { var buffer = new byte[sizeToRead]; Read(buffer, sizeToRead, pcbRead); - if (pcbRead != null) + if (pcbRead != IntPtr.Zero) Marshal.WriteInt64(pcbRead, Marshal.ReadInt32(pcbRead)); pstm.Write(buffer, buffer.Length, pcbWritten); - if (pcbWritten != null) + if (pcbWritten != IntPtr.Zero) Marshal.WriteInt64(pcbWritten, Marshal.ReadInt32(pcbWritten)); } diff --git a/src/DotNet/Pdb/Dss/StreamIStream.cs b/src/DotNet/Pdb/Dss/StreamIStream.cs index 0034bbb6c..279a5246a 100644 --- a/src/DotNet/Pdb/Dss/StreamIStream.cs +++ b/src/DotNet/Pdb/Dss/StreamIStream.cs @@ -60,10 +60,10 @@ public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { var buffer = new byte[sizeToRead]; Read(buffer, sizeToRead, pcbRead); - if (pcbRead != null) + if (pcbRead != IntPtr.Zero) Marshal.WriteInt64(pcbRead, Marshal.ReadInt32(pcbRead)); pstm.Write(buffer, buffer.Length, pcbWritten); - if (pcbWritten != null) + if (pcbWritten != IntPtr.Zero) Marshal.WriteInt64(pcbWritten, Marshal.ReadInt32(pcbWritten)); } @@ -159,7 +159,7 @@ public void UnlockRegion(long libOffset, long cb, int dwLockType) { /// public void Write(byte[] pv, int cb, IntPtr pcbWritten) { stream.Write(pv, 0, cb); - if (pcbWritten != null) + if (pcbWritten != IntPtr.Zero) Marshal.WriteInt32(pcbWritten, cb); } } diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index 8fabb956b..ba894f8e1 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -120,7 +120,7 @@ void ReadFiles(PdbReader reader, Dictionary documents, IImage var nameId = stream.ReadUInt32(); var len = stream.ReadByte(); - var type = stream.ReadByte(); + /*var type = */stream.ReadByte(); var doc = reader.GetDocument(nameId); documents.Add(id, doc); diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 99cfd00c3..6cd09153e 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -69,7 +69,7 @@ void ReadInternal(IImageStream stream) { stream.Position += 2; uint pageSize = stream.ReadUInt32(); - uint fpm = stream.ReadUInt32(); + /*uint fpm = */stream.ReadUInt32(); uint pageCount = stream.ReadUInt32(); uint rootSize = stream.ReadUInt32(); stream.ReadUInt32(); @@ -157,7 +157,7 @@ void ReadNames() { using (var nameData = stream.Create(stream.FileOffset + stream.Position, nameSize)) { stream.Position += nameSize; - uint entryCount = stream.ReadUInt32(); + /*uint entryCount = */stream.ReadUInt32(); uint entryCapacity = stream.ReadUInt32(); var entryOk = new BitArray(stream.ReadBytes(stream.ReadInt32() * 4)); if (stream.ReadUInt32() != 0) diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 5dac08a8f..5ec9794d9 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -211,7 +211,7 @@ bool CheckReaders() { for (int i = 0; i < numReaders; i++) { var resourceReaderFullName = reader.ReadString(); - var resourceSetFullName = reader.ReadString(); + /*var resourceSetFullName = */reader.ReadString(); if (Regex.IsMatch(resourceReaderFullName, @"^System\.Resources\.ResourceReader,\s*mscorlib,")) validReader = true; } diff --git a/src/DotNet/StrongNameKey.cs b/src/DotNet/StrongNameKey.cs index 5942f888b..e91ea8e1e 100644 --- a/src/DotNet/StrongNameKey.cs +++ b/src/DotNet/StrongNameKey.cs @@ -196,7 +196,7 @@ void Initialize(BinaryReader reader) { // Read PublicKeyBlob signatureAlgorithm = (SignatureAlgorithm)reader.ReadUInt32(); hashAlgorithm = (AssemblyHashAlgorithm)reader.ReadUInt32(); - int pkLen = reader.ReadInt32(); + /*int pkLen = */reader.ReadInt32(); // Read PUBLICKEYSTRUC if (reader.ReadByte() != 6) diff --git a/src/Threading/IThreadSafeList.cs b/src/Threading/IThreadSafeList.cs index 205d59df1..39c899650 100644 --- a/src/Threading/IThreadSafeList.cs +++ b/src/Threading/IThreadSafeList.cs @@ -21,7 +21,7 @@ public interface IList : System.Collections.Generic.IList { /// /// Item /// Index of or -1 if it's not present in the list - /// + /// int IndexOf_NoLock(T item); /// @@ -30,7 +30,7 @@ public interface IList : System.Collections.Generic.IList { /// /// Index /// Item to insert - /// + /// void Insert_NoLock(int index, T item); /// @@ -38,7 +38,7 @@ public interface IList : System.Collections.Generic.IList { /// /// /// - /// + /// void RemoveAt_NoLock(int index); /// @@ -46,7 +46,7 @@ public interface IList : System.Collections.Generic.IList { /// /// Index /// Value - /// + /// T Get_NoLock(int index); /// @@ -54,7 +54,7 @@ public interface IList : System.Collections.Generic.IList { /// /// Index /// Value - /// + /// void Set_NoLock(int index, T value); /// @@ -62,13 +62,13 @@ public interface IList : System.Collections.Generic.IList { /// list. /// /// Item - /// + /// void Add_NoLock(T item); /// /// Must only be called when the list lock is held. Clears the list. /// - /// + /// void Clear_NoLock(); /// @@ -77,7 +77,7 @@ public interface IList : System.Collections.Generic.IList { /// /// Item /// true if exists in the list, else false - /// + /// bool Contains_NoLock(T item); /// @@ -85,20 +85,20 @@ public interface IList : System.Collections.Generic.IList { /// /// Destination array /// Destination array index - /// + /// void CopyTo_NoLock(T[] array, int arrayIndex); /// /// Must only be called when the list lock is held. Returns the size of the list. /// - /// + /// int Count_NoLock { get; } /// /// Must only be called when the list lock is held. Returns true if the list is /// read-only, false if it's writable. /// - /// + /// bool IsReadOnly_NoLock { get; } /// @@ -108,14 +108,14 @@ public interface IList : System.Collections.Generic.IList { /// Item /// true if was removed, false if /// was never inserted in the list. - /// + /// bool Remove_NoLock(T item); /// /// Must only be called when the list lock is held. Gets the enumerator. /// /// A new enumerator instance - /// + /// IEnumerator GetEnumerator_NoLock(); /// From c20090acd6909a62ddd6dd4b1fd206670e1e3bfd Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 14 Jul 2016 18:59:19 +0200 Subject: [PATCH 014/511] Add DynamicMethodBodyReader eh reader checks --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index cbe8435ee..8b2215ec8 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -257,13 +257,17 @@ public bool Read() { void CreateExceptionHandlers() { if (ehHeader != null) { + if (ehHeader.Length < 4) + return; var reader = new BinaryReader(new MemoryStream(ehHeader)); - byte b = (byte)reader.ReadByte(); + byte b = reader.ReadByte(); if ((b & 0x40) == 0) { // DynamicResolver only checks bit 6 // Calculate num ehs exactly the same way that DynamicResolver does int numHandlers = (ushort)((reader.ReadByte() - 2) / 12); reader.ReadInt16(); for (int i = 0; i < numHandlers; i++) { + if (reader.BaseStream.Position + 12 > reader.BaseStream.Length) + break; var eh = new ExceptionHandler(); eh.HandlerType = (ExceptionHandlerType)reader.ReadInt16(); int offs = reader.ReadUInt16(); @@ -287,6 +291,8 @@ void CreateExceptionHandlers() { reader.BaseStream.Position--; int numHandlers = (ushort)(((reader.ReadUInt32() >> 8) - 4) / 24); for (int i = 0; i < numHandlers; i++) { + if (reader.BaseStream.Position + 24 > reader.BaseStream.Length) + break; var eh = new ExceptionHandler(); eh.HandlerType = (ExceptionHandlerType)reader.ReadInt32(); int offs = reader.ReadInt32(); From b8ca15ff341d7fcf9064f422388ecac65005947b Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 16 Aug 2016 19:17:35 +0200 Subject: [PATCH 015/511] Update value type check --- src/DotNet/TypeDef.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index f77498a2b..ba493c236 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -679,7 +679,8 @@ public uint ClassSize { /// public bool IsValueType { get { - if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + // Don't include abstract since value types can be abstract without throwing at runtime + if ((Attributes & (TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) return false; var baseType = BaseType; if (baseType == null) @@ -722,7 +723,8 @@ public bool IsValueType { /// public bool IsEnum { get { - if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + // Don't include abstract since value types can be abstract without throwing at runtime + if ((Attributes & (TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) return false; var baseType = BaseType; if (baseType == null) From ad8e5f21488c2e27075b7f34b4dfc469df49cee1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 5 Oct 2016 19:25:20 +0200 Subject: [PATCH 016/511] Update project file --- src/dnlib.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 4e40add82..e55048e3e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,5 +1,6 @@  + Debug AnyCPU @@ -20,7 +21,7 @@ full false ..\Debug\bin\ - TRACE;DEBUG + TRACE;DEBUG;$(MoreDefineConstants) prompt 4 ..\Debug\bin\dnlib.xml @@ -30,7 +31,7 @@ pdbonly true ..\Release\bin\ - TRACE + TRACE;$(MoreDefineConstants) prompt 4 ..\Release\bin\dnlib.xml From 3e43c1a9b026c795a4bf46cafc49ec1f07516608 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 15 Oct 2016 13:50:03 +0200 Subject: [PATCH 017/511] Add portable pdb metadata tables --- src/DotNet/MD/CodedToken.cs | 11 +++++++ src/DotNet/MD/ColumnSize.cs | 18 +++++++++++ src/DotNet/MD/DotNetTableSizes.cs | 53 ++++++++++++++++++++++++++++--- src/DotNet/MD/Table.cs | 17 ++++++++++ src/DotNet/MD/TablesStream.cs | 16 ++++++++++ src/DotNet/ModuleLoader.cs | 8 +++++ src/DotNet/Writer/MetaData.cs | 8 +++++ 7 files changed, 127 insertions(+), 4 deletions(-) diff --git a/src/DotNet/MD/CodedToken.cs b/src/DotNet/MD/CodedToken.cs index 792db014b..6731fee14 100644 --- a/src/DotNet/MD/CodedToken.cs +++ b/src/DotNet/MD/CodedToken.cs @@ -78,6 +78,17 @@ public sealed class CodedToken { Table.TypeDef, Table.Method, }); + /// HasCustomDebugInformation coded token + public static readonly CodedToken HasCustomDebugInformation = new CodedToken(5, new Table[27] { + Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, + Table.Param, Table.InterfaceImpl, Table.MemberRef, Table.Module, + Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, + Table.ModuleRef, Table.TypeSpec, Table.Assembly, Table.AssemblyRef, + Table.File, Table.ExportedType, Table.ManifestResource, Table.GenericParam, + Table.GenericParamConstraint, Table.MethodSpec, Table.Document, Table.LocalScope, + Table.LocalVariable, Table.LocalConstant, Table.ImportScope, + }); + readonly Table[] tableTypes; readonly int bits; readonly int mask; diff --git a/src/DotNet/MD/ColumnSize.cs b/src/DotNet/MD/ColumnSize.cs index 4f7ef6d26..942197a11 100644 --- a/src/DotNet/MD/ColumnSize.cs +++ b/src/DotNet/MD/ColumnSize.cs @@ -95,6 +95,22 @@ public enum ColumnSize : byte { MethodSpec, /// RID into GenericParamConstraint table GenericParamConstraint, + /// RID into Document table + Document = 0x30, + /// RID into MethodDebugInformation table + MethodDebugInformation, + /// RID into LocalScope table + LocalScope, + /// RID into LocalVariable table + LocalVariable, + /// RID into LocalConstant table + LocalConstant, + /// RID into ImportScope table + ImportScope, + /// RID into StateMachineMethod table + StateMachineMethod, + /// RID into CustomDebugInformation table + CustomDebugInformation, /// 8-bit byte Byte = 0x40, /// 16-bit signed int @@ -137,5 +153,7 @@ public enum ColumnSize : byte { ResolutionScope, /// TypeOrMethodDef encoded token TypeOrMethodDef, + /// HasCustomDebugInformation encoded token + HasCustomDebugInformation, } } diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index 197505d2f..b71ce38f8 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -39,11 +39,11 @@ public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList 0xFFFF ? 4 : 2; } - else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.TypeOrMethodDef) { + else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.HasCustomDebugInformation) { CodedToken info; switch (columnSize) { case ColumnSize.TypeDefOrRef: info = CodedToken.TypeDefOrRef; break; @@ -59,6 +59,7 @@ int GetSize(ColumnSize columnSize) { case ColumnSize.CustomAttributeType:info = CodedToken.CustomAttributeType; break; case ColumnSize.ResolutionScope: info = CodedToken.ResolutionScope; break; case ColumnSize.TypeOrMethodDef: info = CodedToken.TypeOrMethodDef; break; + case ColumnSize.HasCustomDebugInformation:info = CodedToken.HasCustomDebugInformation; break; default: throw new InvalidOperationException(string.Format("Invalid ColumnSize: {0}", columnSize)); } uint maxRows = 0; @@ -106,9 +107,10 @@ public TableInfo[] CreateTables(byte majorVersion, byte minorVersion) { /// All table infos (not completely initialized) public TableInfo[] CreateTables(byte majorVersion, byte minorVersion, out int maxPresentTables) { // The three extra generics tables aren't used by CLR 1.x - maxPresentTables = (majorVersion == 1 && minorVersion == 0) ? (int)Table.NestedClass + 1 : (int)Table.GenericParamConstraint + 1; + const int normalMaxTables = (int)Table.CustomDebugInformation + 1; + maxPresentTables = (majorVersion == 1 && minorVersion == 0) ? (int)Table.NestedClass + 1 : normalMaxTables; - var tableInfos = new TableInfo[(int)Table.GenericParamConstraint + 1]; + var tableInfos = new TableInfo[normalMaxTables]; tableInfos[(int)Table.Module] = new TableInfo(Table.Module, "Module", new ColumnInfo[] { new ColumnInfo(0, "Generation", ColumnSize.UInt16), @@ -341,6 +343,49 @@ public TableInfo[] CreateTables(byte majorVersion, byte minorVersion, out int ma new ColumnInfo(0, "Owner", ColumnSize.GenericParam), new ColumnInfo(1, "Constraint", ColumnSize.TypeDefOrRef), }); + tableInfos[0x2D] = new TableInfo((Table)0x2D, string.Empty, new ColumnInfo[] { }); + tableInfos[0x2E] = new TableInfo((Table)0x2E, string.Empty, new ColumnInfo[] { }); + tableInfos[0x2F] = new TableInfo((Table)0x2F, string.Empty, new ColumnInfo[] { }); + tableInfos[(int)Table.Document] = new TableInfo(Table.Document, "Document", new ColumnInfo[] { + new ColumnInfo(0, "Name", ColumnSize.Blob), + new ColumnInfo(1, "HashAlgorithm", ColumnSize.GUID), + new ColumnInfo(2, "Hash", ColumnSize.Blob), + new ColumnInfo(3, "Language", ColumnSize.GUID), + }); + tableInfos[(int)Table.MethodDebugInformation] = new TableInfo(Table.MethodDebugInformation, "MethodDebugInformation", new ColumnInfo[] { + new ColumnInfo(0, "Document", ColumnSize.Document), + new ColumnInfo(1, "SequencePoints", ColumnSize.Blob), + }); + tableInfos[(int)Table.LocalScope] = new TableInfo(Table.LocalScope, "LocalScope", new ColumnInfo[] { + new ColumnInfo(0, "Method", ColumnSize.Method), + new ColumnInfo(1, "ImportScope", ColumnSize.ImportScope), + new ColumnInfo(2, "VariableList", ColumnSize.LocalVariable), + new ColumnInfo(3, "ConstantList", ColumnSize.LocalConstant), + new ColumnInfo(4, "StartOffset", ColumnSize.UInt32), + new ColumnInfo(5, "Length", ColumnSize.UInt32), + }); + tableInfos[(int)Table.LocalVariable] = new TableInfo(Table.LocalVariable, "LocalVariable", new ColumnInfo[] { + new ColumnInfo(0, "Attributes", ColumnSize.UInt16), + new ColumnInfo(1, "Index", ColumnSize.UInt16), + new ColumnInfo(2, "Name", ColumnSize.Strings), + }); + tableInfos[(int)Table.LocalConstant] = new TableInfo(Table.LocalConstant, "LocalConstant", new ColumnInfo[] { + new ColumnInfo(0, "Name", ColumnSize.Strings), + new ColumnInfo(1, "Signature", ColumnSize.Blob), + }); + tableInfos[(int)Table.ImportScope] = new TableInfo(Table.ImportScope, "ImportScope", new ColumnInfo[] { + new ColumnInfo(0, "Parent", ColumnSize.ImportScope), + new ColumnInfo(1, "Imports", ColumnSize.Blob), + }); + tableInfos[(int)Table.StateMachineMethod] = new TableInfo(Table.StateMachineMethod, "StateMachineMethod", new ColumnInfo[] { + new ColumnInfo(0, "MoveNextMethod", ColumnSize.Method), + new ColumnInfo(1, "KickoffMethod", ColumnSize.Method), + }); + tableInfos[(int)Table.CustomDebugInformation] = new TableInfo(Table.CustomDebugInformation, "CustomDebugInformation", new ColumnInfo[] { + new ColumnInfo(0, "Parent", ColumnSize.HasCustomDebugInformation), + new ColumnInfo(1, "Kind", ColumnSize.GUID), + new ColumnInfo(2, "Value", ColumnSize.Blob), + }); return this.tableInfos = tableInfos; } } diff --git a/src/DotNet/MD/Table.cs b/src/DotNet/MD/Table.cs index 2682c226a..e65c23bc2 100644 --- a/src/DotNet/MD/Table.cs +++ b/src/DotNet/MD/Table.cs @@ -95,5 +95,22 @@ public enum Table : byte { MethodSpec, /// GenericParamConstraint table (2Ch) GenericParamConstraint, + + /// (Portable PDB) Document table (30h) + Document = 0x30, + /// (Portable PDB) MethodDebugInformation table (31h) + MethodDebugInformation, + /// (Portable PDB) LocalScope table (32h) + LocalScope, + /// (Portable PDB) LocalVariable table (33h) + LocalVariable, + /// (Portable PDB) LocalConstant table (34h) + LocalConstant, + /// (Portable PDB) ImportScope table (35h) + ImportScope, + /// (Portable PDB) StateMachineMethod table (36h) + StateMachineMethod, + /// (Portable PDB) CustomDebugInformation table (37h) + CustomDebugInformation, } } diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 3b09a2a76..864d2faa3 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -71,6 +71,14 @@ public sealed partial class TablesStream : DotNetStream { public MDTable GenericParamTable { get; private set; } public MDTable MethodSpecTable { get; private set; } public MDTable GenericParamConstraintTable { get; private set; } + public MDTable Document { get; private set; } + public MDTable MethodDebugInformation { get; private set; } + public MDTable LocalScope { get; private set; } + public MDTable LocalVariable { get; private set; } + public MDTable LocalConstant { get; private set; } + public MDTable ImportScope { get; private set; } + public MDTable StateMachineMethod { get; private set; } + public MDTable CustomDebugInformation { get; private set; } #pragma warning restore #if THREAD_SAFE @@ -305,6 +313,14 @@ void InitializeTables() { GenericParamTable = mdTables[(int)Table.GenericParam]; MethodSpecTable = mdTables[(int)Table.MethodSpec]; GenericParamConstraintTable = mdTables[(int)Table.GenericParamConstraint]; + Document = mdTables[(int)Table.Document]; + MethodDebugInformation = mdTables[(int)Table.MethodDebugInformation]; + LocalScope = mdTables[(int)Table.LocalScope]; + LocalVariable = mdTables[(int)Table.LocalVariable]; + LocalConstant = mdTables[(int)Table.LocalConstant]; + ImportScope = mdTables[(int)Table.ImportScope]; + StateMachineMethod = mdTables[(int)Table.StateMachineMethod]; + CustomDebugInformation = mdTables[(int)Table.CustomDebugInformation]; } /// diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index f161fdc3e..649ab78d4 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -281,6 +281,14 @@ void Load(IMDTokenProvider mdt) { case Table.AssemblyRefProcessor: case Table.AssemblyRefOS: case Table.NestedClass: + case Table.Document: + case Table.MethodDebugInformation: + case Table.LocalScope: + case Table.LocalVariable: + case Table.LocalConstant: + case Table.ImportScope: + case Table.StateMachineMethod: + case Table.CustomDebugInformation: break; default: diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index ebe43b5b4..35efe238f 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -1715,6 +1715,14 @@ uint AddMDTokenProvider(IMDTokenProvider tp) { case Table.NestedClass: case Table.GenericParam: case Table.GenericParamConstraint: + case Table.Document: + case Table.MethodDebugInformation: + case Table.LocalScope: + case Table.LocalVariable: + case Table.LocalConstant: + case Table.ImportScope: + case Table.StateMachineMethod: + case Table.CustomDebugInformation: default: break; } From 6edd83cb8e51e984c0a5dff60978e6e5ce5a273c Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 15 Oct 2016 16:42:28 +0200 Subject: [PATCH 018/511] Add index checks --- src/DotNet/MD/DotNetTableSizes.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index b71ce38f8..0ad9be57d 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -41,7 +41,8 @@ public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList 0xFFFF ? 4 : 2; + uint count = table >= rowCounts.Count ? 0 : rowCounts[table]; + return count > 0xFFFF ? 4 : 2; } else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.HasCustomDebugInformation) { CodedToken info; @@ -64,7 +65,8 @@ int GetSize(ColumnSize columnSize) { } uint maxRows = 0; foreach (var tableType in info.TableTypes) { - var tableRows = rowCounts[(int)tableType]; + int index = (int)tableType; + var tableRows = index >= rowCounts.Count ? 0 : rowCounts[index]; if (tableRows > maxRows) maxRows = tableRows; } From 54a47c13f9da0a1841c9196ffbd15ca68879045e Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 20 Oct 2016 17:36:01 +0200 Subject: [PATCH 019/511] Update corlib check --- src/DotNet/ICodedToken.cs | 22 +++++++++++++++++++++- src/DotNet/ModuleDef.cs | 6 ++++++ src/DotNet/ModuleDefMD.cs | 8 +++----- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index aeea800ff..c167808bb 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -153,15 +153,35 @@ public interface IAssembly : IFullName { public static partial class Extensions { /// /// Checks whether appears to be the core library (eg. - /// mscorlib, System.Runtime or corefx) + /// mscorlib, System.Runtime or corefx). + /// + /// If is a reference to a private corlib (eg. System.Private.CoreLib), + /// this method returns false unless is an + /// whose manifest (first) module defines System.Object. This check is performed in + /// the constructor and the result can be found in . + /// + /// Note that this method also returns true if it appears to be a 'public' corlib, + /// eg. mscorlib, etc, even if it internally possibly references a private corlib. /// /// The assembly public static bool IsCorLib(this IAssembly asm) { + var asmDef = asm as AssemblyDef; + if (asmDef != null) { + var manifestModule = asmDef.ManifestModule; + if (manifestModule != null) { + var isCorModule = manifestModule.IsCoreLibraryModule; + if (isCorModule != null) + return isCorModule.Value; + } + } + string asmName; return asm != null && UTF8String.IsNullOrEmpty(asm.Culture) && ((asmName = UTF8String.ToSystemStringOrEmpty(asm.Name)).Equals("mscorlib", StringComparison.OrdinalIgnoreCase) || asmName.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) || + // This name could change but since CoreCLR is used a lot, it's worth supporting + asmName.Equals("System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) || asmName.Equals("corefx", StringComparison.OrdinalIgnoreCase)); } diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index c298c818b..173d6ae7a 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -479,6 +479,12 @@ public TypeDef GlobalType { get { return Types.Get(0, null); } } + /// + /// true if it's the core library module, false if it's not the core library module, + /// and null if it's not known. + /// + public bool? IsCoreLibraryModule { get; set; } + /// /// Gets/sets the Win32 resources /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 322ddfd54..f54171b4c 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -643,8 +643,10 @@ AssemblyRef FindCorLibAssemblyRef() { // If we've loaded mscorlib itself, it won't have any AssemblyRefs to itself. var asm = Assembly; - if (asm != null && asm.IsCorLib()) + if (asm != null && (asm.IsCorLib() || Find("System.Object", false) != null)) { + IsCoreLibraryModule = true; return UpdateRowId(new AssemblyRefUser(asm)); + } return corLibAsmRef; } @@ -654,10 +656,6 @@ AssemblyRef FindCorLibAssemblyRef() { /// /// AssemblyRef CreateDefaultCorLibAssemblyRef() { - var asm = Assembly; - if (asm != null && Find("System.Int32", false) != null) - return UpdateRowId(new AssemblyRefUser(asm)); - var asmRef = GetAlternativeCorLibReference(); if (asmRef != null) return UpdateRowId(asmRef); From 400b50a32cb22a429e3b40036514224d86a1cfcd Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 31 Oct 2016 13:07:46 +0100 Subject: [PATCH 020/511] DynamicMethodBodyReader now initializes Method.Name, fixes #83 --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 8b2215ec8..57404ec9c 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -47,6 +47,7 @@ public class DynamicMethodBodyReader : MethodBodyReaderBase, ISignatureReaderHel readonly List tokens; readonly IList ehInfos; readonly byte[] ehHeader; + readonly string methodName; class ReflectionFieldInfo { SR.FieldInfo fieldInfo; @@ -110,6 +111,7 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext this.module = module; this.importer = new Importer(module, ImporterOptions.TryToUseDefs, gpContext); this.gpContext = gpContext; + this.methodName = null; if (obj == null) throw new ArgumentNullException("obj"); @@ -128,6 +130,7 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext } if (obj is DynamicMethod) { + methodName = ((DynamicMethod)obj).Name; obj = dmResolverFieldInfo.Read(obj); if (obj == null) throw new Exception("No resolver found"); @@ -345,6 +348,7 @@ public MethodDef GetMethod() { exceptionHandlers = null; locals = null; method.Body = cilBody; + method.Name = methodName; return method; } From a38e9af502b3c0d202781e1a87f55be6933d3f17 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 14 Dec 2016 14:40:07 +0100 Subject: [PATCH 021/511] Clear module when nested type is removed --- src/DotNet/TypeDef.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index ba493c236..dad29e996 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -1799,6 +1799,7 @@ void IListListener.OnAdd(int index, TypeDef value) { /// void IListListener.OnRemove(int index, TypeDef value) { value.DeclaringType2 = null; + value.Module2 = null; } /// From 70dcd059b95f7355e6be69037542f83cfe0aa718 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 26 Dec 2016 13:35:43 +0100 Subject: [PATCH 022/511] Allow null vtable RVAs if there are no methods --- src/DotNet/Writer/NativeModuleWriter.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 2c09141dd..5d0897183 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -657,8 +657,10 @@ void UpdateVTableFixups(BinaryWriter writer) { long pos = writer.BaseStream.Position; writer.BaseStream.Position = ToWriterOffset(vtable.RVA); - if (writer.BaseStream.Position == 0) - Error("Could not convert RVA to file offset"); + if (writer.BaseStream.Position == 0) { + if (vtable.RVA != 0 || vtable.Methods.Count > 0) + Error("Could not convert RVA to file offset"); + } else { foreach (var method in vtable.Methods) { writer.Write(GetMethodToken(method)); From 106599248c8921cb88cd23c1fe4e79ad8198d04d Mon Sep 17 00:00:00 2001 From: Alcatraz Developer Date: Tue, 17 Jan 2017 21:38:18 +0100 Subject: [PATCH 023/511] Fixed ExceptionHandlers reader from DynamicMethodBodyReader (#99) * Update DynamicMethodBodyReader.cs Fixed ExceptionHandler reader * Update DynamicMethodBodyReader.cs * Fixed tabs from last commit --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 57404ec9c..9d55871a6 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -267,18 +267,18 @@ void CreateExceptionHandlers() { if ((b & 0x40) == 0) { // DynamicResolver only checks bit 6 // Calculate num ehs exactly the same way that DynamicResolver does int numHandlers = (ushort)((reader.ReadByte() - 2) / 12); - reader.ReadInt16(); + reader.ReadUInt16(); for (int i = 0; i < numHandlers; i++) { if (reader.BaseStream.Position + 12 > reader.BaseStream.Length) break; var eh = new ExceptionHandler(); - eh.HandlerType = (ExceptionHandlerType)reader.ReadInt16(); + eh.HandlerType = (ExceptionHandlerType)reader.ReadUInt16(); int offs = reader.ReadUInt16(); eh.TryStart = GetInstructionThrow((uint)offs); - eh.TryEnd = GetInstruction((uint)(reader.ReadSByte() + offs)); + eh.TryEnd = GetInstruction((uint)(reader.ReadByte() + offs)); offs = reader.ReadUInt16(); eh.HandlerStart = GetInstructionThrow((uint)offs); - eh.HandlerEnd = GetInstruction((uint)(reader.ReadSByte() + offs)); + eh.HandlerEnd = GetInstruction((uint)(reader.ReadByte() + offs)); if (eh.HandlerType == ExceptionHandlerType.Catch) eh.CatchType = ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; @@ -297,13 +297,13 @@ void CreateExceptionHandlers() { if (reader.BaseStream.Position + 24 > reader.BaseStream.Length) break; var eh = new ExceptionHandler(); - eh.HandlerType = (ExceptionHandlerType)reader.ReadInt32(); - int offs = reader.ReadInt32(); + eh.HandlerType = (ExceptionHandlerType)reader.ReadUInt32(); + var offs = reader.ReadUInt32(); eh.TryStart = GetInstructionThrow((uint)offs); - eh.TryEnd = GetInstruction((uint)(reader.ReadInt32() + offs)); - offs = reader.ReadInt32(); + eh.TryEnd = GetInstruction((uint)(reader.ReadUInt32() + offs)); + offs = reader.ReadUInt32(); eh.HandlerStart = GetInstructionThrow((uint)offs); - eh.HandlerEnd = GetInstruction((uint)(reader.ReadInt32() + offs)); + eh.HandlerEnd = GetInstruction((uint)(reader.ReadUInt32() + offs)); if (eh.HandlerType == ExceptionHandlerType.Catch) eh.CatchType = ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; From 1ef3defff337a172d97f8d636b00208b57d3668a Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 17 Jan 2017 21:40:33 +0100 Subject: [PATCH 024/511] Use tabs --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 9d55871a6..552b15270 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -275,7 +275,7 @@ void CreateExceptionHandlers() { eh.HandlerType = (ExceptionHandlerType)reader.ReadUInt16(); int offs = reader.ReadUInt16(); eh.TryStart = GetInstructionThrow((uint)offs); - eh.TryEnd = GetInstruction((uint)(reader.ReadByte() + offs)); + eh.TryEnd = GetInstruction((uint)(reader.ReadByte() + offs)); offs = reader.ReadUInt16(); eh.HandlerStart = GetInstructionThrow((uint)offs); eh.HandlerEnd = GetInstruction((uint)(reader.ReadByte() + offs)); From 72db232eb15c7222202d65136d432ad0b5611e79 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Jan 2017 15:17:44 +0100 Subject: [PATCH 025/511] Include opt/req modifiers when importing field infos --- src/DotNet/Importer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 08cf86032..671dd5ce3 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -593,7 +593,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); } else { - var fieldSig = new FieldSig(ImportAsTypeSig(fieldInfo.FieldType)); + var fieldSig = new FieldSig(ImportAsTypeSig(fieldInfo.FieldType, fieldInfo.GetRequiredCustomModifiers(), fieldInfo.GetOptionalCustomModifiers())); fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); } var field = TryResolveField(fieldRef); From a4b2b89e85c059581919e4971a6d345de377fe4e Mon Sep 17 00:00:00 2001 From: kiootic Date: Sun, 2 Apr 2017 23:59:28 +0800 Subject: [PATCH 026/511] Add support for .NET Core build tools (#110) --- src/dnlib.csproj | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index e55048e3e..30e7c5a3f 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -16,6 +16,14 @@ true ..\dnlib.snk + + true + + /usr/lib/mono/2.0-api + /usr/local/lib/mono/2.0-api + /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.0-api + /usr/local/Cellar/mono/4.6.2.16/lib/mono/2.0-api + true full @@ -360,7 +368,7 @@ - + From 2cb05c59ec9bd3b70307bc97da35ea71ec49e430 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 21 May 2017 20:13:21 +0200 Subject: [PATCH 027/511] Add a new GetPointerSize() overload --- src/DotNet/ModuleDef.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 173d6ae7a..8708e74d9 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1213,6 +1213,16 @@ public int GetPointerSize() { /// can be 32-bit or 64-bit /// Size of a pointer (4 or 8) public int GetPointerSize(int defaultPointerSize) { + return GetPointerSize(defaultPointerSize, defaultPointerSize); + } + + /// + /// Returns the size of a pointer + /// + /// Default pointer size + /// Pointer size if it's prefer-32-bit (should usually be 4) + /// + public int GetPointerSize(int defaultPointerSize, int prefer32bitPointerSize) { var machine = Machine; if (machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64) return 8; @@ -1247,7 +1257,7 @@ public int GetPointerSize(int defaultPointerSize) { case ComImageFlags._32BitRequired | ComImageFlags._32BitPreferred: // Platform neutral but prefers to be 32-bit - return defaultPointerSize; + return prefer32bitPointerSize; } return defaultPointerSize; From 00de2e358c18b7af50ad7df67679091bbe65520a Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 30 May 2017 19:30:11 +0200 Subject: [PATCH 028/511] Add lcid/retval param attr bits --- src/DotNet/ParamAttributes.cs | 4 ++++ src/DotNet/ParamDef.cs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/DotNet/ParamAttributes.cs b/src/DotNet/ParamAttributes.cs index 98a7ac87c..5e0ac484a 100644 --- a/src/DotNet/ParamAttributes.cs +++ b/src/DotNet/ParamAttributes.cs @@ -12,6 +12,10 @@ public enum ParamAttributes : ushort { In = 0x0001, /// Param is [out] Out = 0x0002, + /// Param is a locale identifier + Lcid = 0x0004, + /// Param is a return value + Retval = 0x0008, /// Param is optional Optional = 0x0010, diff --git a/src/DotNet/ParamDef.cs b/src/DotNet/ParamDef.cs index 12a77d34f..524ad477a 100644 --- a/src/DotNet/ParamDef.cs +++ b/src/DotNet/ParamDef.cs @@ -275,6 +275,22 @@ public bool IsOut { set { ModifyAttributes(value, ParamAttributes.Out); } } + /// + /// Gets/sets the bit + /// + public bool IsLcid { + get { return ((ParamAttributes)attributes & ParamAttributes.Lcid) != 0; } + set { ModifyAttributes(value, ParamAttributes.Lcid); } + } + + /// + /// Gets/sets the bit + /// + public bool IsRetval { + get { return ((ParamAttributes)attributes & ParamAttributes.Retval) != 0; } + set { ModifyAttributes(value, ParamAttributes.Retval); } + } + /// /// Gets/sets the bit /// From 0dd211373a84214d30b2b5e12737d564d5fb7f91 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 18 Jun 2017 13:57:13 +0200 Subject: [PATCH 029/511] Add LPUTF8Str --- src/DotNet/NativeType.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/NativeType.cs b/src/DotNet/NativeType.cs index 548f5d7f5..d390d595e 100644 --- a/src/DotNet/NativeType.cs +++ b/src/DotNet/NativeType.cs @@ -97,6 +97,8 @@ public enum NativeType : uint { IInspectable = 0x2E, /// hstring HString = 0x2F, + /// UTF-8 encoded string + LPUTF8Str = 0x30, /// first invalid element type Max = 0x50, /// Value wasn't present in the blob From 289b5048228fb40f807490060be2bc2caf193449 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 25 Jun 2017 17:07:45 +0200 Subject: [PATCH 030/511] Update PDB reader/writer, #94 --- src/DotNet/AssemblyResolver.cs | 5 + src/DotNet/Emit/MethodBody.cs | 41 +- src/DotNet/ModuleDefMD.cs | 9 +- src/DotNet/ModuleLoader.cs | 28 +- src/DotNet/Pdb/CustomDebugInfoConstants.cs | 8 + src/DotNet/Pdb/Dss/ComInterfaces.cs | 54 ++ src/DotNet/Pdb/Dss/SymbolMethod.cs | 44 +- src/DotNet/Pdb/Dss/SymbolReader.cs | 3 + src/DotNet/Pdb/Dss/SymbolScope.cs | 57 +- src/DotNet/Pdb/Dss/SymbolWriter.cs | 48 +- src/DotNet/Pdb/ISymbolMethod2.cs | 23 + src/DotNet/Pdb/ISymbolScope2.cs | 19 + src/DotNet/Pdb/ISymbolWriter2.cs | 41 ++ src/DotNet/Pdb/Managed/DbiFunction.cs | 55 +- src/DotNet/Pdb/Managed/DbiScope.cs | 124 +++- src/DotNet/Pdb/Managed/NumericLeaf.cs | 36 ++ src/DotNet/Pdb/Managed/NumericReader.cs | 101 ++++ src/DotNet/Pdb/Managed/PdbReader.cs | 21 +- src/DotNet/Pdb/PdbAsyncMethod.cs | 84 +++ src/DotNet/Pdb/PdbConstant.cs | 44 ++ src/DotNet/Pdb/PdbCustomDebugInfo.cs | 603 ++++++++++++++++++++ src/DotNet/Pdb/PdbCustomDebugInfoReader.cs | 349 +++++++++++ src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs | 405 +++++++++++++ src/DotNet/Pdb/PdbMethod.cs | 42 ++ src/DotNet/Pdb/PdbScope.cs | 15 + src/DotNet/Pdb/PdbState.cs | 173 +++++- src/DotNet/Pdb/PdbWriter.cs | 238 ++++++-- src/DotNet/Writer/MetaData.cs | 22 + src/DotNet/Writer/ModuleWriterBase.cs | 2 +- src/DotNet/Writer/PreserveTokensMetaData.cs | 11 + src/dnlib.csproj | 11 + 31 files changed, 2624 insertions(+), 92 deletions(-) create mode 100644 src/DotNet/Pdb/CustomDebugInfoConstants.cs create mode 100644 src/DotNet/Pdb/ISymbolMethod2.cs create mode 100644 src/DotNet/Pdb/ISymbolScope2.cs create mode 100644 src/DotNet/Pdb/Managed/NumericLeaf.cs create mode 100644 src/DotNet/Pdb/Managed/NumericReader.cs create mode 100644 src/DotNet/Pdb/PdbAsyncMethod.cs create mode 100644 src/DotNet/Pdb/PdbConstant.cs create mode 100644 src/DotNet/Pdb/PdbCustomDebugInfo.cs create mode 100644 src/DotNet/Pdb/PdbCustomDebugInfoReader.cs create mode 100644 src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs create mode 100644 src/DotNet/Pdb/PdbMethod.cs diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 01bc83faa..70fa48bfa 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -621,6 +621,8 @@ IEnumerable FindAssembliesGacAny(GacInfo gacInfo, IAssembly assembly, Mo } IEnumerable GetDirs(string baseDir) { + if (!Directory.Exists(baseDir)) + return emtpyStringArray; var dirs = new List(); try { foreach (var di in new DirectoryInfo(baseDir).GetDirectories()) @@ -630,6 +632,7 @@ IEnumerable GetDirs(string baseDir) { } return dirs; } + static readonly string[] emtpyStringArray = new string[0]; IEnumerable FindAssembliesModuleSearchPaths(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { string asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); @@ -871,6 +874,8 @@ static void AddOtherAssemblySearchPaths(IList paths, string path) { } static void AddSilverlightDirs(IList paths, string basePath) { + if (!Directory.Exists(basePath)) + return; try { var di = new DirectoryInfo(basePath); foreach (var dir in di.GetDirectories()) { diff --git a/src/DotNet/Emit/MethodBody.cs b/src/DotNet/Emit/MethodBody.cs index 3792e4c71..811f5bb63 100644 --- a/src/DotNet/Emit/MethodBody.cs +++ b/src/DotNet/Emit/MethodBody.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; +using System; +using System.Collections.Generic; using dnlib.DotNet.Pdb; using dnlib.PE; using dnlib.Threading; @@ -59,7 +60,6 @@ public sealed class CilBody : MethodBody { readonly ThreadSafe.IList instructions; readonly ThreadSafe.IList exceptionHandlers; readonly LocalList localList; - PdbScope pdbScope; /// /// Size of a small header @@ -164,19 +164,46 @@ public bool HasVariables { } /// - /// Gets/sets the PDB scope. This is null if no PDB has been loaded or if there's - /// no PDB scope for this method. + /// Gets/sets the PDB method. This is null if no PDB has been loaded or if there's + /// no PDB info for this method. /// + public PdbMethod PdbMethod { + get { return pdbMethod; } + set { pdbMethod = value; } + } + PdbMethod pdbMethod; + + /// + /// true if is not null + /// + public bool HasPdbMethod { + get { return PdbMethod != null; } + } + + /// + /// Gets/sets the PDB scope + /// + [Obsolete("Use PdbMethod.Scope property instead")] public PdbScope Scope { - get { return pdbScope; } - set { pdbScope = value; } + get { + var pdbMethod = this.pdbMethod; + return pdbMethod == null ? null : pdbMethod.Scope; + } + set { + var pdbMethod = this.pdbMethod; + if (pdbMethod == null && value != null) + this.pdbMethod = pdbMethod = new PdbMethod(); + if (pdbMethod != null) + pdbMethod.Scope = value; + } } /// /// true if is not null /// + [Obsolete("Use HasPdbMethod to check if it has PDB info")] public bool HasScope { - get { return pdbScope != null; } + get { return Scope != null; } } /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index f54171b4c..560b706b2 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1852,7 +1852,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out mb)) { var cilBody = mb as CilBody; if (cilBody != null) - return InitializeBodyFromPdb(cilBody, method.OrigRid); + return InitializeBodyFromPdb(method, cilBody, method.OrigRid); return mb; } @@ -1860,7 +1860,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib return null; var codeType = implAttrs & MethodImplAttributes.CodeTypeMask; if (codeType == MethodImplAttributes.IL) - return InitializeBodyFromPdb(ReadCilBody(method.Parameters, rva, gpContext), method.OrigRid); + return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext), method.OrigRid); if (codeType == MethodImplAttributes.Native) return new NativeMethodBody(rva); return null; @@ -1869,12 +1869,13 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// /// Updates with the PDB info (if any) /// + /// Owner method /// Method body /// Method rid /// Returns originak value - CilBody InitializeBodyFromPdb(CilBody body, uint rid) { + CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body, uint rid) { if (pdbState != null) - pdbState.InitializeDontCall(body, rid); + pdbState.InitializeMethodBody(this, method, body, rid); return body; } diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index 649ab78d4..57595edc5 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -126,9 +126,9 @@ void LoadObj(object o) { return; } - var scope = o as PdbScope; - if (scope != null) { - Load(scope); + var pdbMethod = o as PdbMethod; + if (pdbMethod != null) { + Load(pdbMethod); return; } @@ -676,14 +676,7 @@ void Load(CAArgument obj) { AddCAValue(obj.Value); } - void Load(PdbScope obj) { - if (obj == null) - return; - Add(obj.Start); - Add(obj.End); - Add(obj.Scopes); - Add(obj.Variables); - } + void Load(PdbMethod obj) { } void Load(ResourceDirectory obj) { if (obj == null) @@ -729,9 +722,7 @@ void Add(IMDTokenProvider o) { AddToStack(o); } - void Add(PdbScope scope) { - AddToStack(scope); - } + void Add(PdbMethod pdbMethod) { } void Add(TypeSig ts) { AddToStack(ts); @@ -822,13 +813,6 @@ void Add(IList list) { Add(item); } - void Add(IList list) { - if (list == null) - return; - foreach (var item in list.GetSafeEnumerable()) - Add(item); - } - void Add(IList list) { if (list == null) return; @@ -950,7 +934,7 @@ void Add(CilBody body) { Add(body.Instructions); Add(body.ExceptionHandlers); Add(body.Variables); - Add(body.Scope); + Add(body.PdbMethod); } void Add(Instruction instr) { diff --git a/src/DotNet/Pdb/CustomDebugInfoConstants.cs b/src/DotNet/Pdb/CustomDebugInfoConstants.cs new file mode 100644 index 000000000..af851b9c4 --- /dev/null +++ b/src/DotNet/Pdb/CustomDebugInfoConstants.cs @@ -0,0 +1,8 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb { + static class CustomDebugInfoConstants { + public const int Version = 4; + public const int RecordVersion = 4; + } +} diff --git a/src/DotNet/Pdb/Dss/ComInterfaces.cs b/src/DotNet/Pdb/Dss/ComInterfaces.cs index d7c31c539..5decee493 100644 --- a/src/DotNet/Pdb/Dss/ComInterfaces.cs +++ b/src/DotNet/Pdb/Dss/ComInterfaces.cs @@ -89,6 +89,19 @@ interface ISymUnmanagedMethod { void GetSequencePoints([In] uint cPoints, [Out] out uint pcPoints, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] offsets, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedDocument[] documents, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] lines, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] columns, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] endLines, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] endColumns); } + [ComVisible(true), + ComImport, + Guid("B20D55B3-532E-4906-87E7-25BD5734ABD2"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedAsyncMethod { + bool IsAsyncMethod(); + uint GetKickoffMethod(); + bool HasCatchHandlerILOffset(); + uint GetCatchHandlerILOffset(); + uint GetAsyncStepInfoCount(); + void GetAsyncStepInfo([In] uint cStepInfo, [Out] out uint pcStepInfo, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] yieldOffsets, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] breakpointOffset, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] breakpointMethod); + } + [ComVisible(true), ComImport, Guid("9F60EEBE-2D9A-3F7C-BF58-80BC991C60BB"), @@ -130,6 +143,37 @@ interface ISymUnmanagedScope { void GetNamespaces([In] uint cNameSpaces, [Out] out uint pcNameSpaces, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedNamespace[] namespaces); } + [ComVisible(true), + ComImport, + Guid("AE932FBA-3FD8-4dba-8232-30A2309B02DB"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedScope2 : ISymUnmanagedScope { +#pragma warning disable 0108 + void GetMethod([Out] out ISymUnmanagedMethod pRetVal); + void GetParent([Out] out ISymUnmanagedScope pRetVal); + void GetChildren([In] uint cChildren, [Out] out uint pcChildren, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedScope[] children); + void GetStartOffset([Out] out uint pRetVal); + void GetEndOffset([Out] out uint pRetVal); + void GetLocalCount([Out] out uint pRetVal); + void GetLocals([In] uint cLocals, [Out] out uint pcLocals, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] locals); + void GetNamespaces([In] uint cNameSpaces, [Out] out uint pcNameSpaces, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedNamespace[] namespaces); +#pragma warning restore 0108 + + uint GetConstantCount(); + void GetConstants([In] uint cConstants, [Out] out uint pcConstants, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedConstant[] constants); + } + + [ComVisible(true), + ComImport, + Guid("48B25ED8-5BAD-41bc-9CEE-CD62FABC74E9"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedConstant { + void GetName([In] uint cchName, [Out] out uint pcchName, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] szName); + void GetValue(out object pValue); + [PreserveSig] + int GetSignature([In] uint cSig, [Out] out uint pcSig, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] sig); + } + [ComVisible(true), ComImport, Guid("7DAC8207-D3AE-4C75-9B67-92801A497D44"), @@ -332,4 +376,14 @@ public interface ISymUnmanagedDocumentWriter { void SetCheckSum([In] Guid algorithmId, [In] uint checkSumSize, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] checkSum); } #pragma warning restore 1591 + + [ComVisible(true), + ComImport, + Guid("FC073774-1739-4232-BD56-A027294BEC15"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedAsyncMethodPropertiesWriter { + void DefineKickoffMethod([In] uint kickoffMethod); + void DefineCatchHandlerILOffset([In] uint catchHandlerOffset); + void DefineAsyncStepInfo([In] uint count, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] yieldOffsets, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] breakpointOffset, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] breakpointMethod); + } } diff --git a/src/DotNet/Pdb/Dss/SymbolMethod.cs b/src/DotNet/Pdb/Dss/SymbolMethod.cs index a7f0595e2..0c752ce3b 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethod.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethod.cs @@ -1,14 +1,17 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Diagnostics; using System.Diagnostics.SymbolStore; namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolMethod : ISymbolMethod { + sealed class SymbolMethod : ISymbolMethod2 { readonly ISymUnmanagedMethod method; + readonly ISymUnmanagedAsyncMethod asyncMethod; public SymbolMethod(ISymUnmanagedMethod method) { this.method = method; + this.asyncMethod = method as ISymUnmanagedAsyncMethod; } public ISymbolScope RootScope { @@ -125,5 +128,44 @@ public bool GetSourceStartEnd(ISymbolDocument[] docs, int[] lines, int[] columns return result; } + + public bool IsAsyncMethod { + get { return asyncMethod != null && asyncMethod.IsAsyncMethod(); } + } + + public uint KickoffMethod { + get { + Debug.Assert(IsAsyncMethod); + if (asyncMethod == null) + throw new InvalidOperationException(); + return asyncMethod.GetKickoffMethod(); + } + } + + public uint? CatchHandlerILOffset { + get { + Debug.Assert(IsAsyncMethod); + if (asyncMethod == null) + throw new InvalidOperationException(); + if (!asyncMethod.HasCatchHandlerILOffset()) + return null; + return asyncMethod.GetCatchHandlerILOffset(); + } + } + + public RawAsyncStepInfo[] GetAsyncStepInfos() { + Debug.Assert(IsAsyncMethod); + if (asyncMethod == null) + throw new InvalidOperationException(); + var stepInfoCount = asyncMethod.GetAsyncStepInfoCount(); + var yieldOffsets = new uint[stepInfoCount]; + var breakpointOffsets = new uint[stepInfoCount]; + var breakpointMethods = new uint[stepInfoCount]; + asyncMethod.GetAsyncStepInfo(stepInfoCount, out stepInfoCount, yieldOffsets, breakpointOffsets, breakpointMethods); + var res = new RawAsyncStepInfo[stepInfoCount]; + for (int i = 0; i < res.Length; i++) + res[i] = new RawAsyncStepInfo(yieldOffsets[i], breakpointOffsets[i], breakpointMethods[i]); + return res; + } } } diff --git a/src/DotNet/Pdb/Dss/SymbolReader.cs b/src/DotNet/Pdb/Dss/SymbolReader.cs index 20e21fcdf..7e546f76f 100644 --- a/src/DotNet/Pdb/Dss/SymbolReader.cs +++ b/src/DotNet/Pdb/Dss/SymbolReader.cs @@ -104,10 +104,13 @@ public ISymbolNamespace[] GetNamespaces() { public byte[] GetSymAttribute(SymbolToken parent, string name) { uint bufSize; reader.GetSymAttribute((uint)parent.GetToken(), name, 0, out bufSize, null); + if (bufSize == 0) + return emptyBytes; var buffer = new byte[bufSize]; reader.GetSymAttribute((uint)parent.GetToken(), name, (uint)buffer.Length, out bufSize, buffer); return buffer; } + static readonly byte[] emptyBytes = new byte[0]; public ISymbolVariable[] GetVariables(SymbolToken parent) { uint numVars; diff --git a/src/DotNet/Pdb/Dss/SymbolScope.cs b/src/DotNet/Pdb/Dss/SymbolScope.cs index b15848f6a..07cc70c94 100644 --- a/src/DotNet/Pdb/Dss/SymbolScope.cs +++ b/src/DotNet/Pdb/Dss/SymbolScope.cs @@ -1,9 +1,10 @@ // dnlib: See LICENSE.txt for more info +using System.Diagnostics; using System.Diagnostics.SymbolStore; namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolScope : ISymbolScope { + sealed class SymbolScope : ISymbolScope2 { readonly ISymUnmanagedScope scope; public SymbolScope(ISymUnmanagedScope scope) { @@ -74,5 +75,59 @@ public ISymbolNamespace[] GetNamespaces() { nss[i] = new SymbolNamespace(unNss[i]); return nss; } + + public PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { + var scope2 = scope as ISymUnmanagedScope2; + if (scope2 == null) + return emptySymbolConstants; + uint numCs; + scope2.GetConstants(0, out numCs, null); + if (numCs == 0) + return emptySymbolConstants; + var unCs = new ISymUnmanagedConstant[numCs]; + scope2.GetConstants((uint)unCs.Length, out numCs, unCs); + var nss = new PdbConstant[numCs]; + for (uint i = 0; i < numCs; i++) { + var unc = unCs[i]; + var name = GetName(unc); + object value; + unc.GetValue(out value); + var sigBytes = GetSignatureBytes(unc); + TypeSig signature; + if (sigBytes.Length == 0) + signature = null; + else + signature = SignatureReader.ReadTypeSig(module, module.CorLibTypes, sigBytes, gpContext); + nss[i] = new PdbConstant(name, signature, value); + } + return nss; + } + static readonly PdbConstant[] emptySymbolConstants = new PdbConstant[0]; + + string GetName(ISymUnmanagedConstant unc) { + uint count; + unc.GetName(0, out count, null); + var chars = new char[count]; + unc.GetName((uint)chars.Length, out count, chars); + if (chars.Length == 0) + return string.Empty; + return new string(chars, 0, chars.Length - 1); + } + + byte[] GetSignatureBytes(ISymUnmanagedConstant unc) { + const int E_FAIL = unchecked((int)0x80004005); + const int E_NOTIMPL = unchecked((int)0x80004001); + uint bufSize; + int hr = unc.GetSignature(0, out bufSize, null); + if (bufSize == 0 || (hr < 0 && hr != E_FAIL && hr != E_NOTIMPL)) + return emptyByteArray; + var buffer = new byte[bufSize]; + hr = unc.GetSignature((uint)buffer.Length, out bufSize, buffer); + Debug.Assert(hr == 0); + if (hr != 0) + return emptyByteArray; + return buffer; + } + static readonly byte[] emptyByteArray = new byte[0]; } } diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index 493153ac3..230c704a7 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -8,12 +8,17 @@ using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolWriter : ISymbolWriter2 { + sealed class SymbolWriter : ISymbolWriter3 { readonly ISymUnmanagedWriter2 writer; + readonly ISymUnmanagedAsyncMethodPropertiesWriter asyncMethodWriter; readonly string pdbFileName; readonly Stream pdbStream; bool closeCalled; + public bool SupportsAsyncMethods { + get { return asyncMethodWriter != null; } + } + /// /// Constructor /// @@ -25,6 +30,7 @@ public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName) { if (pdbFileName == null) throw new ArgumentNullException("pdbFileName"); this.writer = writer; + this.asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; this.pdbFileName = pdbFileName; } @@ -44,6 +50,10 @@ public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbS this.pdbFileName = pdbFileName; } + public void Abort() { + writer.Abort(); + } + public void Close() { if (closeCalled) return; @@ -63,6 +73,28 @@ public void CloseScope(int endOffset) { writer.CloseScope((uint)endOffset); } + public void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod) { + if (asyncMethodWriter == null) + throw new InvalidOperationException(); + if (yieldOffsets.Length != breakpointOffset.Length || yieldOffsets.Length != breakpointMethod.Length) + throw new ArgumentException(); + asyncMethodWriter.DefineAsyncStepInfo((uint)yieldOffsets.Length, yieldOffsets, breakpointOffset, breakpointMethod); + } + + public void DefineCatchHandlerILOffset(uint catchHandlerOffset) { + if (asyncMethodWriter == null) + throw new InvalidOperationException(); + asyncMethodWriter.DefineCatchHandlerILOffset(catchHandlerOffset); + } + + public void DefineConstant(string name, object value, byte[] signature) { + writer.DefineConstant(name, value, (uint)signature.Length, signature); + } + + public void DefineConstant2(string name, object value, uint sigToken) { + writer.DefineConstant2(name, value, sigToken); + } + public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { ISymUnmanagedDocumentWriter unDocWriter; writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out unDocWriter); @@ -77,6 +109,16 @@ public void DefineGlobalVariable(string name, System.Reflection.FieldAttributes writer.DefineGlobalVariable(name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); } + public void DefineGlobalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3) { + writer.DefineGlobalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3); + } + + public void DefineKickoffMethod(uint kickoffMethod) { + if (asyncMethodWriter == null) + throw new InvalidOperationException(); + asyncMethodWriter.DefineKickoffMethod(kickoffMethod); + } + public void DefineLocalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) { writer.DefineLocalVariable(name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3, (uint)startOffset, (uint)endOffset); } @@ -124,6 +166,10 @@ public int OpenScope(int startOffset) { return (int)result; } + public void RemapToken(uint oldToken, uint newToken) { + writer.RemapToken(oldToken, newToken); + } + public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn) { var sdoc = startDoc as SymbolDocumentWriter; if (sdoc == null) diff --git a/src/DotNet/Pdb/ISymbolMethod2.cs b/src/DotNet/Pdb/ISymbolMethod2.cs new file mode 100644 index 000000000..402b9a181 --- /dev/null +++ b/src/DotNet/Pdb/ISymbolMethod2.cs @@ -0,0 +1,23 @@ +// dnlib: See LICENSE.txt for more info + +using System.Diagnostics.SymbolStore; + +namespace dnlib.DotNet.Pdb { + interface ISymbolMethod2 : ISymbolMethod { + bool IsAsyncMethod { get; } + uint KickoffMethod { get; } + uint? CatchHandlerILOffset { get; } + RawAsyncStepInfo[] GetAsyncStepInfos(); + } + + struct RawAsyncStepInfo { + public uint YieldOffset; + public uint BreakpointOffset; + public uint BreakpointMethod; + public RawAsyncStepInfo(uint yieldOffset, uint breakpointOffset, uint breakpointMethod) { + YieldOffset = yieldOffset; + BreakpointOffset = breakpointOffset; + BreakpointMethod = breakpointMethod; + } + } +} diff --git a/src/DotNet/Pdb/ISymbolScope2.cs b/src/DotNet/Pdb/ISymbolScope2.cs new file mode 100644 index 000000000..699c4a896 --- /dev/null +++ b/src/DotNet/Pdb/ISymbolScope2.cs @@ -0,0 +1,19 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Diagnostics.SymbolStore; + +namespace dnlib.DotNet.Pdb { + /// + /// The managed version of ISymUnmanagedScope2 + /// + interface ISymbolScope2 : ISymbolScope { + /// + /// Gets all the constants + /// + /// Owner module if a signature must be read from the #Blob + /// Generic parameter context + /// + PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext); + } +} diff --git a/src/DotNet/Pdb/ISymbolWriter2.cs b/src/DotNet/Pdb/ISymbolWriter2.cs index 8f33ce380..7e9b35ae5 100644 --- a/src/DotNet/Pdb/ISymbolWriter2.cs +++ b/src/DotNet/Pdb/ISymbolWriter2.cs @@ -67,4 +67,45 @@ public interface ISymbolWriter2 : ISymbolWriter, IDisposable { /// Metadata void Initialize(MetaData metaData); } + + /// + /// Implements and adds a few extra methods we need that are part of + /// ISymUnmanagedWriter and ISymUnmanagedWriter2 but not present in + /// . + /// + public interface ISymbolWriter3 : ISymbolWriter2 { + /// + /// Defines a constant + /// + /// Name of constant + /// Constant value + /// StandAloneSig token of constant field type + void DefineConstant2(string name, object value, uint sigToken); + + /// + /// true if it supports , + /// and + /// + bool SupportsAsyncMethods { get; } + + /// + /// Defines an async kickoff method + /// + /// Kickoff method token + void DefineKickoffMethod(uint kickoffMethod); + + /// + /// Defines an async catch handler + /// + /// Catch handler IL offset + void DefineCatchHandlerILOffset(uint catchHandlerOffset); + + /// + /// Defines async step info + /// + /// Yield IL offsets + /// Breakpoint method IL offset + /// Breakpoint method + void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod); + } } diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index b61a12577..f1baf6a8c 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -2,11 +2,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiFunction : ISymbolMethod { + sealed class DbiFunction : ISymbolMethod2 { public uint Token { get; internal set; } public string Name { get; private set; } public PdbAddress Address { get; private set; } @@ -42,8 +43,6 @@ void FixOffsets(RecursionCounter counter, DbiScope scope) { counter.Decrement(); } - #region ISymbolMethod - ISymbolScope ISymbolMethod.RootScope { get { return Root; } } @@ -111,6 +110,54 @@ SymbolToken ISymbolMethod.Token { get { throw new NotImplementedException(); } } - #endregion + const string asyncMethodInfoAttributeName = "asyncMethodInfo"; + public bool IsAsyncMethod { + get { + var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); + return data != null && data.Length >= 0x0C; + } + } + + uint ISymbolMethod2.KickoffMethod { + get { + Debug.Assert(IsAsyncMethod); + var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); + if (data == null) + throw new InvalidOperationException(); + return BitConverter.ToUInt32(data, 0); + } + } + + uint? ISymbolMethod2.CatchHandlerILOffset { + get { + Debug.Assert(IsAsyncMethod); + var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); + if (data == null) + throw new InvalidOperationException(); + uint token = BitConverter.ToUInt32(data, 4); + return token == uint.MaxValue ? (uint?)null : token; + } + } + + RawAsyncStepInfo[] ISymbolMethod2.GetAsyncStepInfos() { + Debug.Assert(IsAsyncMethod); + var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); + if (data == null) + throw new InvalidOperationException(); + int pos = 8; + int count = BitConverter.ToInt32(data, pos); + pos += 4; + if (pos + (long)count * 12 > data.Length) + return emptyRawAsyncStepInfo; + if (count == 0) + return emptyRawAsyncStepInfo; + var res = new RawAsyncStepInfo[count]; + for (int i = 0; i < res.Length; i++) { + res[i] = new RawAsyncStepInfo(BitConverter.ToUInt32(data, pos), BitConverter.ToUInt32(data, pos + 8), BitConverter.ToUInt32(data, pos + 4)); + pos += 12; + } + return res; + } + static readonly RawAsyncStepInfo[] emptyRawAsyncStepInfo = new RawAsyncStepInfo[0]; } } \ No newline at end of file diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 5a1cdb06f..2c49b891e 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -1,13 +1,14 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.SymbolStore; +using System.Text; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiScope : ISymbolScope { + sealed class DbiScope : ISymbolScope2 { public DbiScope(string name, uint offset, uint length) { Name = name; BeginOffset = offset; @@ -26,6 +27,36 @@ public DbiScope(string name, uint offset, uint length) { public IList Variables { get; private set; } public IList Children { get; private set; } + List oemInfos; + List constants; + + struct ConstantInfo { + public string Name; + public uint SignatureToken; + public object Value; + public ConstantInfo(string name, uint signatureToken, object value) { + Name = name; + SignatureToken = signatureToken; + Value = value; + } + } + + internal struct OemInfo { + public readonly string Name; + public readonly byte[] Data; + public OemInfo(string name, byte[] data) { + Name = name; + Data = data; + } + public override string ToString() { + return Name + " = (" + Data.Length.ToString() + " bytes)"; + } + } + + static readonly byte[] dotNetOemGuid = new byte[] { + 0xC9, 0x3F, 0xEA, 0xC6, 0xB3, 0x59, 0xD6, 0x49, 0xBC, 0x25, 0x09, 0x02, 0xBB, 0xAB, 0xB4, 0x60 + }; + public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { if (!counter.Increment()) throw new PdbException("Scopes too deep"); @@ -38,13 +69,14 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { var type = (SymbolType)stream.ReadUInt16(); DbiScope child = null; uint? childEnd = null; + string name; switch (type) { case SymbolType.S_BLOCK32: { stream.Position += 4; childEnd = stream.ReadUInt32(); var len = stream.ReadUInt32(); var addr = PdbAddress.ReadAddress(stream); - var name = PdbReader.ReadCString(stream); + name = PdbReader.ReadCString(stream); child = new DbiScope(name, addr.Offset, len); break; } @@ -57,6 +89,38 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { Variables.Add(variable); break; } + case SymbolType.S_OEM: + if (stream.Position + 20 > end) + break; + if (!ReadAndCompareBytes(stream, end, dotNetOemGuid)) { + Debug.Fail("Unknown OEM record GUID, not .NET GUID"); + break; + } + stream.Position += 4;// typeIndex or 0 + name = ReadUnicodeString(stream, end); + Debug.Assert(name != null); + if (name == null) + break; + var data = stream.ReadBytes((int)(end - stream.Position)); + if (oemInfos == null) + oemInfos = new List(1); + oemInfos.Add(new OemInfo(name, data)); + break; + case SymbolType.S_MANCONSTANT: + uint signatureToken = stream.ReadUInt32(); + object value; + if (!NumericReader.TryReadNumeric(stream, end, out value)) + break; + name = PdbReader.ReadCString(stream); + if (constants == null) + constants = new List(); + constants.Add(new ConstantInfo(name, signatureToken, value)); + break; + case SymbolType.S_END: + break; + default: + Debug.Write("Unknown symbol type: " + type); + break; } stream.Position = end; @@ -71,6 +135,60 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { Debugger.Break(); } + static string ReadUnicodeString(IImageStream stream, long end) { + var sb = new StringBuilder(); + for (;;) { + if (stream.Position + 2 > end) + return null; + var c = (char)stream.ReadUInt16(); + if (c == 0) + break; + sb.Append(c); + } + return sb.ToString(); + } + + static bool ReadAndCompareBytes(IImageStream stream, long end, byte[] bytes) { + if (stream.Position + bytes.Length > end) + return false; + for (int i = 0; i < bytes.Length; i++) { + if (stream.ReadByte() != bytes[i]) + return false; + } + return true; + } + + public PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { + if (constants == null) + return emptySymbolConstants; + var res = new PdbConstant[constants.Count]; + for (int i = 0; i < res.Length; i++) { + var info = constants[i]; + TypeSig signature; + var saSig = module.ResolveToken(info.SignatureToken) as StandAloneSig; + var fieldSig = saSig == null ? null : saSig.Signature as FieldSig; + if (fieldSig == null) { + Debug.Fail("Constant without a signature"); + signature = null; + } + else + signature = fieldSig.Type; + res[i] = new PdbConstant(info.Name, signature, info.Value); + } + return res; + } + static readonly PdbConstant[] emptySymbolConstants = new PdbConstant[0]; + + internal byte[] GetSymAttribute(string name) { + if (oemInfos == null) + return null; + foreach (var info in oemInfos) { + if (info.Name == name) + return info.Data; + } + return null; + } + #region ISymbolScope int ISymbolScope.StartOffset { diff --git a/src/DotNet/Pdb/Managed/NumericLeaf.cs b/src/DotNet/Pdb/Managed/NumericLeaf.cs new file mode 100644 index 000000000..730d843ef --- /dev/null +++ b/src/DotNet/Pdb/Managed/NumericLeaf.cs @@ -0,0 +1,36 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb.Managed { + enum NumericLeaf : ushort { + LF_NUMERIC = 0x8000, + LF_CHAR = 0x8000, + LF_SHORT = 0x8001, + LF_USHORT = 0x8002, + LF_LONG = 0x8003, + LF_ULONG = 0x8004, + LF_REAL32 = 0x8005, + LF_REAL64 = 0x8006, + LF_REAL80 = 0x8007, + LF_REAL128 = 0x8008, + LF_QUADWORD = 0x8009, + LF_UQUADWORD = 0x800A, + LF_REAL48 = 0x800B, + LF_COMPLEX32 = 0x800C, + LF_COMPLEX64 = 0x800D, + LF_COMPLEX80 = 0x800E, + LF_COMPLEX128 = 0x800F, + LF_VARSTRING = 0x8010, + LF_RESERVED_8011 = 0x8011, + LF_RESERVED_8012 = 0x8012, + LF_RESERVED_8013 = 0x8013, + LF_RESERVED_8014 = 0x8014, + LF_RESERVED_8015 = 0x8015, + LF_RESERVED_8016 = 0x8016, + LF_OCTWORD = 0x8017, + LF_UOCTWORD = 0x8018, + LF_VARIANT = 0x8019, + LF_DATE = 0x801A, + LF_UTF8STRING = 0x801B, + LF_REAL16 = 0x801C, + } +} diff --git a/src/DotNet/Pdb/Managed/NumericReader.cs b/src/DotNet/Pdb/Managed/NumericReader.cs new file mode 100644 index 000000000..d35445abe --- /dev/null +++ b/src/DotNet/Pdb/Managed/NumericReader.cs @@ -0,0 +1,101 @@ +// dnlib: See LICENSE.txt for more info + +using System.Text; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Managed { + static class NumericReader { + public static bool TryReadNumeric(IImageStream stream, long end, out object value) { + value = null; + if (stream.Position + 2 > end) + return false; + var numLeaf = (NumericLeaf)stream.ReadUInt16(); + if (numLeaf < NumericLeaf.LF_NUMERIC) { + value = (short)numLeaf; + return true; + } + + switch (numLeaf) { + case NumericLeaf.LF_CHAR: + if (stream.Position > end) + return false; + value = stream.ReadSByte(); + return true; + + case NumericLeaf.LF_SHORT: + if (stream.Position + 2 > end) + return false; + value = stream.ReadInt16(); + return true; + + case NumericLeaf.LF_USHORT: + if (stream.Position + 2 > end) + return false; + value = stream.ReadUInt16(); + return true; + + case NumericLeaf.LF_LONG: + if (stream.Position + 4 > end) + return false; + value = stream.ReadInt32(); + return true; + + case NumericLeaf.LF_ULONG: + if (stream.Position + 4 > end) + return false; + value = stream.ReadUInt32(); + return true; + + case NumericLeaf.LF_REAL32: + if (stream.Position + 4 > end) + return false; + value = stream.ReadSingle(); + return true; + + case NumericLeaf.LF_REAL64: + if (stream.Position + 8 > end) + return false; + value = stream.ReadDouble(); + return true; + + case NumericLeaf.LF_QUADWORD: + if (stream.Position + 8 > end) + return false; + value = stream.ReadInt64(); + return true; + + case NumericLeaf.LF_UQUADWORD: + if (stream.Position + 8 > end) + return false; + value = stream.ReadUInt64(); + return true; + + case NumericLeaf.LF_VARSTRING: + if (stream.Position + 2 > end) + return false; + int varStrLen = stream.ReadUInt16(); + if (stream.Position + varStrLen > end) + return false; + value = Encoding.UTF8.GetString(stream.ReadBytes(varStrLen)); + return true; + + case NumericLeaf.LF_VARIANT: + if (stream.Position + 0x10 > end) + return false; + int v0 = stream.ReadInt32(); + int v1 = stream.ReadInt32(); + int v2 = stream.ReadInt32(); + int v3 = stream.ReadInt32(); + byte scale = (byte)(v0 >> 16); + if (scale <= 28) + value = new decimal(v2, v3, v1, v0 < 0, scale); + else + value = null; + return true; + + default: + return false; + } + } + } +} diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 6cd09153e..4e426fecf 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -3,6 +3,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.SymbolStore; using System.Text; using dnlib.IO; @@ -272,8 +273,10 @@ void ReadGlobalSymbols(IImageStream stream) { stream.Position += 2; var name = ReadCString(stream); - if (name == "COM+_Entry_Point") + if (name == "COM+_Entry_Point") { entryPt = offset; + break; + } } stream.Position = end; @@ -301,7 +304,10 @@ void ApplyRidMap(IImageStream stream) { } internal static string ReadCString(IImageStream stream) { - var value = Encoding.UTF8.GetString(stream.ReadBytesUntilByte(0)); + var bytes = stream.ReadBytesUntilByte(0); + if (bytes == null) + return string.Empty; + var value = Encoding.UTF8.GetString(bytes); stream.Position++; return value; } @@ -348,8 +354,17 @@ ISymbolNamespace[] ISymbolReader.GetNamespaces() { } byte[] ISymbolReader.GetSymAttribute(SymbolToken parent, string name) { - throw new NotImplementedException(); + DbiFunction func; + bool b = functions.TryGetValue((uint)parent.GetToken(), out func); + Debug.Assert(b); + if (!b) + return emptyByteArray; + var res = func.Root.GetSymAttribute(name); + if (res == null) + return emptyByteArray; + return res; } + static readonly byte[] emptyByteArray = new byte[0]; ISymbolVariable[] ISymbolReader.GetVariables(SymbolToken parent) { throw new NotImplementedException(); diff --git a/src/DotNet/Pdb/PdbAsyncMethod.cs b/src/DotNet/Pdb/PdbAsyncMethod.cs new file mode 100644 index 000000000..4f4b51c78 --- /dev/null +++ b/src/DotNet/Pdb/PdbAsyncMethod.cs @@ -0,0 +1,84 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.DotNet.Emit; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + +namespace dnlib.DotNet.Pdb { + /// + /// Async method info + /// + public sealed class PdbAsyncMethod { + readonly ThreadSafe.IList asyncStepInfos; + + /// + /// Gets/sets the starting method that initiates the async operation + /// + public MethodDef KickoffMethod { get; set; } + + /// + /// Gets/sets the instruction for the compiler generated catch handler that wraps an async method. + /// This can be null. + /// + public Instruction CatchHandlerInstruction { get; set; } + + /// + /// Gets all step infos used by the debugger + /// + public ThreadSafe.IList StepInfos { + get { return asyncStepInfos; } + } + + /// + /// Constructor + /// + public PdbAsyncMethod() { + asyncStepInfos = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Default capacity for + public PdbAsyncMethod(int stepInfosCapacity) { + asyncStepInfos = ThreadSafeListCreator.Create(stepInfosCapacity); + } + } + + /// + /// Async step info used by debuggers + /// + public struct PdbAsyncStepInfo { + /// + /// The yield instruction + /// + public Instruction YieldInstruction; + + /// + /// Resume method + /// + public MethodDef BreakpointMethod; + + /// + /// Resume instruction (where the debugger puts a breakpoint) + /// + public Instruction BreakpointInstruction; + + /// + /// Constructor + /// + /// The yield instruction + /// Resume method + /// Resume instruction (where the debugger puts a breakpoint) + public PdbAsyncStepInfo(Instruction yieldInstruction, MethodDef breakpointMethod, Instruction breakpointInstruction) { + YieldInstruction = yieldInstruction; + BreakpointMethod = breakpointMethod; + BreakpointInstruction = breakpointInstruction; + } + } +} diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs new file mode 100644 index 000000000..4be90daa9 --- /dev/null +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -0,0 +1,44 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb { + /// + /// A constant in a method scope, eg. "const int SomeConstant = 123;" + /// + public struct PdbConstant { + /// + /// Gets/sets the name + /// + public string Name { get; set; } + + /// + /// Gets/sets the type of the constant + /// + public TypeSig Type { get; set; } + + /// + /// Gets/sets the value of the constant + /// + public object Value { get; set; } + + /// + /// Constructor + /// + /// Name of constant + /// Type of constant + /// Constant value + public PdbConstant(string name, TypeSig type, object value) { + Name = name; + Type = type; + Value = value; + } + + /// + /// ToString() + /// + /// + public override string ToString() { + var type = Type; + return (type == null ? "" : type.ToString()) + " " + Name + " = " + (Value == null ? "null" : Value.ToString() + " (" + Value.GetType().FullName + ")"); + } + } +} diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs new file mode 100644 index 000000000..11fc983fa --- /dev/null +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -0,0 +1,603 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using dnlib.DotNet.Emit; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + +namespace dnlib.DotNet.Pdb { + /// + /// Custom debug info kind + /// + /// See CustomDebugInfoKind in Roslyn source code + public enum PdbCustomDebugInfoKind { + /// + /// + /// + UsingGroups, + + /// + /// + /// + ForwardMethodInfo, + + /// + /// + /// + ForwardModuleInfo, + + /// + /// + /// + StateMachineHoistedLocalScopes, + + /// + /// + /// + StateMachineTypeName, + + /// + /// + /// + DynamicLocals, + + /// + /// + /// + EditAndContinueLocalSlotMap, + + /// + /// + /// + EditAndContinueLambdaMap, + + /// + /// + /// + TupleElementNames, + } + + /// + /// Base class of custom debug info added to the PDB file by the compiler + /// + public abstract class PdbCustomDebugInfo { + /// + /// Gets the custom debug info kind + /// + public abstract PdbCustomDebugInfoKind Kind { get; } + } + + /// + /// Unknown custom debug info. If you see an instance of this class, you're using an old dnlib version or + /// dnlib hasn't been updated to support this new custom debug info kind. + /// + public sealed class PdbUnknownCustomDebugInfo : PdbCustomDebugInfo { + readonly PdbCustomDebugInfoKind kind; + readonly byte[] data; + + /// + /// Gets the custom debug info kind + /// + public override PdbCustomDebugInfoKind Kind { + get { return kind; } + } + + /// + /// Gets the data + /// + public byte[] Data { + get { return data; } + } + + /// + /// Constructor + /// + /// Custom debug info kind + /// Raw custom debug info data + public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data) { + if (data == null) + throw new ArgumentNullException("data"); + this.kind = kind; + this.data = data; + } + } + + /// + /// Contains sizes of using groups + /// + public sealed class PdbUsingGroupsCustomDebugInfo : PdbCustomDebugInfo { + readonly ThreadSafe.IList usingCounts; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.UsingGroups; } + } + + /// + /// Gets the using counts + /// + public ThreadSafe.IList UsingCounts { + get { return usingCounts; } + } + + /// + /// Constructor + /// + public PdbUsingGroupsCustomDebugInfo() { + usingCounts = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PdbUsingGroupsCustomDebugInfo(int capacity) { + usingCounts = ThreadSafeListCreator.Create(capacity); + } + } + + /// + /// Contains a reference to another method that contains the import strings + /// + public sealed class PdbForwardMethodInfoCustomDebugInfo : PdbCustomDebugInfo { + IMethodDefOrRef method; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.ForwardMethodInfo; } + } + + /// + /// Gets/sets the referenced method + /// + public IMethodDefOrRef Method { + get { return method; } + set { method = value; } + } + + /// + /// Constructor + /// + public PdbForwardMethodInfoCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// The referenced method + public PdbForwardMethodInfoCustomDebugInfo(IMethodDefOrRef method) { + this.method = method; + } + } + + /// + /// Contains a reference to another method that contains the per-module debug info (assembly reference aliases) + /// + public sealed class PdbForwardModuleInfoCustomDebugInfo : PdbCustomDebugInfo { + IMethodDefOrRef method; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.ForwardModuleInfo; } + } + + /// + /// Gets/sets the referenced method + /// + public IMethodDefOrRef Method { + get { return method; } + set { method = value; } + } + + /// + /// Constructor + /// + public PdbForwardModuleInfoCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// The referenced method + public PdbForwardModuleInfoCustomDebugInfo(IMethodDefOrRef method) { + this.method = method; + } + } + + /// + /// State machine hosted local scope info + /// + public struct StateMachineHoistedLocalScope { + /// + /// true if it's a syntesized local ( and are both null) + /// + public bool IsSynthesizedLocal { + get { return Start == null && End == null; } + } + + /// + /// The instruction of the first operation in the scope. Can be null if it's a synthesized local + /// + public Instruction Start; + + /// + /// The instruction of the first operation outside of the scope or null if it ends at the last instruction in the body. + /// Can also be null if it's a synthesized local (in which case is also null, see ) + /// + public Instruction End; + + /// + /// Constructor + /// + /// Start of the scope + /// First instruction after the end of the scope + public StateMachineHoistedLocalScope(Instruction start, Instruction end) { + Start = start; + End = end; + } + } + + /// + /// Contains local scopes for state machine hoisted local variables. + /// + public sealed class PdbStateMachineHoistedLocalScopesCustomDebugInfo : PdbCustomDebugInfo { + readonly ThreadSafe.IList scopes; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes; } + } + + /// + /// Gets the scopes + /// + public ThreadSafe.IList Scopes { + get { return scopes; } + } + + /// + /// Constructor + /// + public PdbStateMachineHoistedLocalScopesCustomDebugInfo() { + scopes = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PdbStateMachineHoistedLocalScopesCustomDebugInfo(int capacity) { + scopes = ThreadSafeListCreator.Create(capacity); + } + } + + /// + /// Contains the state machine type + /// + public sealed class PdbStateMachineTypeNameCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.StateMachineTypeName; } + } + + /// + /// Gets/sets the state machine type + /// + public TypeDef Type { get; set; } + + /// + /// Constructor + /// + public PdbStateMachineTypeNameCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// State machine type + public PdbStateMachineTypeNameCustomDebugInfo(TypeDef type) { + Type = type; + } + } + + /// + /// Contains dynamic flags for local variables and constants + /// + public sealed class PdbDynamicLocalsCustomDebugInfo : PdbCustomDebugInfo { + readonly ThreadSafe.IList locals; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.DynamicLocals; } + } + + /// + /// Gets the dynamic locals + /// + public ThreadSafe.IList Locals { + get { return locals; } + } + + /// + /// Constructor + /// + public PdbDynamicLocalsCustomDebugInfo() { + locals = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PdbDynamicLocalsCustomDebugInfo(int capacity) { + locals = ThreadSafeListCreator.Create(capacity); + } + } + + /// + /// Dynamic local info + /// + public sealed class PdbDynamicLocal { + readonly ThreadSafe.IList flags; + string name; + Local local; + + /// + /// Gets the dynamic flags + /// + public ThreadSafe.IList Flags { + get { return flags; } + } + + /// + /// Gets/sets the name of the local. The name must have at most 64 characters and no char can be NUL (0x0000). + /// If null is written, is returned instead. + /// + public string Name { + get { + var n = name; + if (n != null) + return n; + var l = local; + return l == null ? null : l.Name; + } + set { name = value; } + } + + /// + /// true if it's a constant and not a variable ( is null) + /// + public bool IsConstant { + get { return Local == null; } + } + + /// + /// true if it's a variable ( is not null) + /// + public bool IsVariable { + get { return Local != null; } + } + + /// + /// Gets/sets the local. Could be null if there's no local (it's a 'const' local). + /// + public Local Local { + get { return local; } + set { local = value; } + } + + /// + /// Constructor + /// + public PdbDynamicLocal() { + flags = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PdbDynamicLocal(int capacity) { + flags = ThreadSafeListCreator.Create(capacity); + } + } + + /// + /// Contains the EnC local variable slot map + /// + public sealed class PdbEditAndContinueLocalSlotMapCustomDebugInfo : PdbCustomDebugInfo { + readonly byte[] data; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap; } + } + + /// + /// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLocalSlotMap + /// + public byte[] Data { + get { return data; } + } + + /// + /// Constructor + /// + /// Raw custom debug info data + public PdbEditAndContinueLocalSlotMapCustomDebugInfo(byte[] data) { + if (data == null) + throw new ArgumentNullException("data"); + this.data = data; + } + } + + /// + /// Contains the EnC lambda map + /// + public sealed class PdbEditAndContinueLambdaMapCustomDebugInfo : PdbCustomDebugInfo { + readonly byte[] data; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.EditAndContinueLambdaMap; } + } + + /// + /// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLambdaAndClosureMap + /// + public byte[] Data { + get { return data; } + } + + /// + /// Constructor + /// + /// Raw custom debug info data + public PdbEditAndContinueLambdaMapCustomDebugInfo(byte[] data) { + if (data == null) + throw new ArgumentNullException("data"); + this.data = data; + } + } + + /// + /// Contains tuple element names for local variables and constants + /// + public sealed class PdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo { + readonly ThreadSafe.IList names; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.TupleElementNames; } + } + + /// + /// Gets the tuple element names + /// + public ThreadSafe.IList Names { + get { return names; } + } + + /// + /// Constructor + /// + public PdbTupleElementNamesCustomDebugInfo() { + names = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PdbTupleElementNamesCustomDebugInfo(int capacity) { + names = ThreadSafeListCreator.Create(capacity); + } + } + + /// + /// Tuple element name info + /// + public sealed class PdbTupleElementNames { + readonly ThreadSafe.IList tupleElementNames; + string name; + Local local; + Instruction scopeStart, scopeEnd; + + /// + /// Gets/sets the name of the local. If null is written, is returned instead. + /// + public string Name { + get { + var n = name; + if (n != null) + return n; + var l = local; + return l == null ? null : l.Name; + } + set { name = value; } + } + + /// + /// Gets/sets the local. It's null if it's a constant, and non-null if it's a variable + /// + public Local Local { + get { return local; } + set { local = value; } + } + + /// + /// true if it's a constant. Constants have a scope ( and ) + /// + public bool IsConstant { + get { return local == null; } + } + + /// + /// true if it's a variable. Variables don't have a scope ( and ) + /// + public bool IsVariable { + get { return local != null; } + } + + /// + /// Gets/sets the start of the scope or null. Only constants have a scope. + /// + public Instruction ScopeStart { + get { return scopeStart; } + set { scopeStart = value; } + } + + /// + /// Gets/sets the end of the scope or null if it has no scope or if the scope ends at the end of the body. Only constants have a scope. + /// + public Instruction ScopeEnd { + get { return scopeEnd; } + set { scopeEnd = value; } + } + + /// + /// Gets the tuple element names + /// + public ThreadSafe.IList TupleElementNames { + get { return tupleElementNames; } + } + + /// + /// Constructor + /// + public PdbTupleElementNames() { + tupleElementNames = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PdbTupleElementNames(int capacity) { + tupleElementNames = ThreadSafeListCreator.Create(capacity); + } + } +} diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs new file mode 100644 index 000000000..0521d9108 --- /dev/null +++ b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs @@ -0,0 +1,349 @@ +// dnlib: See LICENSE.txt for more info + +// C# & Visual Basic compiler's Custom Debug Info is "documented" in source code only, see Roslyn classes: +// CustomDebugInfoReader, CustomDebugInfoWriter, CustomDebugInfoEncoder + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using dnlib.DotNet.Emit; +using dnlib.IO; +using dnlib.Threading; + +namespace dnlib.DotNet.Pdb { + /// + /// Reads custom debug infos produced by the C# and Visual Basic compilers. They're stored in PDB files + /// as PDB method custom attributes with the name "MD2". + /// + struct PdbCustomDebugInfoReader : IDisposable { + /// + /// Reads custom debug info + /// + /// Method + /// The method's body. Needs to be provided by the caller since we're called from + /// PDB-init code when the Body property hasn't been initialized yet + /// Place all custom debug info in this list + /// Custom debug info from the PDB file + public static void Read(MethodDef method, CilBody body, IList result, byte[] data) { + Read(method, body, result, MemoryImageStream.Create(data)); + } + + /// + /// Reads custom debug info + /// + /// Method + /// The method's body. Needs to be provided by the caller since we're called from + /// PDB-init code when the Body property hasn't been initialized yet + /// Place all custom debug info in this list + /// Custom debug info from the PDB file + public static void Read(MethodDef method, CilBody body, IList result, IBinaryReader stream) { + try { + using (var reader = new PdbCustomDebugInfoReader(method, body, result, stream)) + reader.Read(); + } + catch (ArgumentException) { + } + catch (OutOfMemoryException) { + } + catch (IOException) { + } + } + + readonly MethodDef method; + readonly CilBody body; + readonly IList result; + readonly IBinaryReader reader; + + PdbCustomDebugInfoReader(MethodDef method, CilBody body, IList result, IBinaryReader reader) { + this.method = method; + this.body = body; + this.result = result; + this.reader = reader; + } + + void Read() { + if (reader.Length < 4) + return; + int version = reader.ReadByte(); + Debug.Assert(version == CustomDebugInfoConstants.Version); + if (version != CustomDebugInfoConstants.Version) + return; + int count = reader.ReadByte(); + reader.Position += 2; + + while (reader.Position + 8 <= reader.Length) { + int recVersion = reader.ReadByte(); + Debug.Assert(recVersion == CustomDebugInfoConstants.RecordVersion); + var recKind = (PdbCustomDebugInfoKind)reader.ReadByte(); + reader.Position++; + int alignmentSize = reader.ReadByte(); + int recSize = reader.ReadInt32(); + if (recSize < 8 || reader.Position - 8 + (uint)recSize > reader.Length) + return; + if (recKind <= PdbCustomDebugInfoKind.DynamicLocals) + alignmentSize = 0; + if (alignmentSize > 3) + return; + var nextRecPos = reader.Position - 8 + recSize; + + if (recVersion == CustomDebugInfoConstants.RecordVersion) { + var recPosEnd = reader.Position - 8 + recSize - alignmentSize; + var cdi = ReadRecord(recKind, recPosEnd); + Debug.Assert(cdi != null); + Debug.Assert(reader.Position <= recPosEnd); + if (reader.Position > recPosEnd) + return; + if (cdi != null) { + Debug.Assert(cdi.Kind == recKind); + result.Add(cdi); + } + } + + reader.Position = nextRecPos; + } + } + + PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { + IMethodDefOrRef method; + byte[] data; + Local local; + int count; + int localIndex; + switch (recKind) { + case PdbCustomDebugInfoKind.UsingGroups: + count = reader.ReadUInt16(); + if (count < 0) + return null; + var usingCountRec = new PdbUsingGroupsCustomDebugInfo(count); + for (int i = 0; i < count; i++) + usingCountRec.UsingCounts.Add(reader.ReadUInt16()); + return usingCountRec; + + case PdbCustomDebugInfoKind.ForwardMethodInfo: + method = this.method.Module.ResolveToken(reader.ReadUInt32(), GenericParamContext.Create(this.method)) as IMethodDefOrRef; + if (method == null) + return null; + return new PdbForwardMethodInfoCustomDebugInfo(method); + + case PdbCustomDebugInfoKind.ForwardModuleInfo: + method = this.method.Module.ResolveToken(reader.ReadUInt32(), GenericParamContext.Create(this.method)) as IMethodDefOrRef; + if (method == null) + return null; + return new PdbForwardModuleInfoCustomDebugInfo(method); + + case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: + count = reader.ReadInt32(); + if (count < 0) + return null; + var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); + int maxEndOffset = -1; + for (int i = 0; i < count; i++) { + uint startOffset = reader.ReadUInt32(); + uint endOffset = reader.ReadUInt32(); + if (startOffset > endOffset) + return null; + // Try to detect synthesized locals, whose start==end==0. The problem is that endOffset + // read from the PDB is inclusive (add 1 to get 'end'), so a synthesized local and a + // local at [0, 1) will be encoded the same {0, 0}. + if (endOffset == 0) + smScope.Scopes.Add(new StateMachineHoistedLocalScope()); + else { + var start = GetInstruction(startOffset); + var end = GetInstruction(endOffset + 1); + if (start == null) + return null; + smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); + } + maxEndOffset = Math.Max(maxEndOffset, (int)endOffset + 1); + } + return smScope; + + case PdbCustomDebugInfoKind.StateMachineTypeName: + var name = ReadUnicodeZ(recPosEnd, needZeroChar: true); + if (name == null) + return null; + var type = GetNestedType(name); + if (type == null) + return null; + return new PdbStateMachineTypeNameCustomDebugInfo(type); + + case PdbCustomDebugInfoKind.DynamicLocals: + count = reader.ReadInt32(); + const int dynLocalRecSize = 64 + 4 + 4 + 2 * 64; + if (reader.Position + (long)(uint)count * dynLocalRecSize > recPosEnd) + return null; + var dynLocListRec = new PdbDynamicLocalsCustomDebugInfo(count); + for (int i = 0; i < count; i++) { + reader.Position += 64; + int flagsCount = reader.ReadInt32(); + if ((uint)flagsCount > 64) + return null; + var dynLocRec = new PdbDynamicLocal(flagsCount); + var afterPos = reader.Position; + + reader.Position -= 64 + 4; + for (int j = 0; j < flagsCount; j++) + dynLocRec.Flags.Add(reader.ReadByte()); + reader.Position = afterPos; + + localIndex = reader.ReadInt32(); + // 'const' locals have index -1 but they're encoded as 0 by Roslyn + if (localIndex != 0 && (uint)localIndex >= (uint)body.Variables.Count) + return null; + + var nameEndPos = reader.Position + 2 * 64; + name = ReadUnicodeZ(nameEndPos, needZeroChar: false); + reader.Position = nameEndPos; + + local = localIndex < body.Variables.Count ? body.Variables[localIndex] : null; + // Roslyn writes 0 to localIndex if it's a 'const' local, try to undo that now + if (localIndex == 0 && local != null && local.Name != name) + local = null; + if (local != null && local.Name == name) + name = null; + dynLocRec.Name = name; + dynLocRec.Local = local; + dynLocListRec.Locals.Add(dynLocRec); + } + return dynLocListRec; + + case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: + data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); + + case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: + data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLambdaMapCustomDebugInfo(data); + + case PdbCustomDebugInfoKind.TupleElementNames: + count = reader.ReadInt32(); + if (count < 0) + return null; + var tupleListRec = new PdbTupleElementNamesCustomDebugInfo(count); + for (int i = 0; i < count; i++) { + int nameCount = reader.ReadInt32(); + if ((uint)nameCount >= 10000) + return null; + var tupleInfo = new PdbTupleElementNames(nameCount); + + for (int j = 0; j < nameCount; j++) { + var s = ReadUTF8Z(recPosEnd); + if (s == null) + return null; + tupleInfo.TupleElementNames.Add(s); + } + + localIndex = reader.ReadInt32(); + uint scopeStart = reader.ReadUInt32(); + uint scopeEnd = reader.ReadUInt32(); + name = ReadUTF8Z(recPosEnd); + if (name == null) + return null; + Debug.Assert(localIndex >= -1); + // -1 = 'const' local. Only 'const' locals have a scope + Debug.Assert((localIndex == -1) ^ (scopeStart == 0 && scopeEnd == 0)); + + if (localIndex == -1) { + local = null; + tupleInfo.ScopeStart = GetInstruction(scopeStart); + tupleInfo.ScopeEnd = GetInstruction(scopeEnd); + if (tupleInfo.ScopeStart == null) + return null; + } + else { + if ((uint)localIndex >= (uint)body.Variables.Count) + return null; + local = body.Variables[localIndex]; + } + + if (local != null && local.Name == name) + name = null; + tupleInfo.Local = local; + tupleInfo.Name = name; + + tupleListRec.Names.Add(tupleInfo); + } + return tupleListRec; + + default: + Debug.Fail("Unknown custom debug info kind: 0x" + ((int)recKind).ToString("X")); + data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbUnknownCustomDebugInfo(recKind, data); + } + } + + TypeDef GetNestedType(string name) { + foreach (var type in method.DeclaringType.NestedTypes.GetSafeEnumerable()) { + if (UTF8String.IsNullOrEmpty(type.Namespace)) { + if (type.Name == name) + return type; + var typeName = type.Name.String; + if (typeName.StartsWith(name) && typeName.Length >= name.Length + 2) { + int i = name.Length; + if (typeName[i] == '`') { + Debug.Assert(i + 1 < typeName.Length); + bool ok = true; + i++; + while (i < typeName.Length) { + if (!char.IsDigit(typeName[i])) { + ok = false; + break; + } + i++; + } + if (ok) + return type; + } + } + } + } + return null; + } + + string ReadUnicodeZ(long recPosEnd, bool needZeroChar) { + var sb = new StringBuilder(); + + for (;;) { + if (reader.Position >= recPosEnd) + return needZeroChar ? null : sb.ToString(); + var c = (char)reader.ReadUInt16(); + if (c == 0) + return sb.ToString(); + sb.Append(c); + } + } + + string ReadUTF8Z(long recPosEnd) { + if (reader.Position > recPosEnd) + return null; + var bytes = reader.ReadBytesUntilByte(0); + if (bytes == null) + return null; + var s = Encoding.UTF8.GetString(bytes); + reader.Position++; + return s; + } + + Instruction GetInstruction(uint offset) { + var instructions = body.Instructions; + int lo = 0, hi = instructions.Count - 1; + while (lo <= hi && hi != -1) { + int i = (lo + hi) / 2; + var instr = instructions[i]; + if (instr.Offset == offset) + return instr; + if (offset < instr.Offset) + hi = i - 1; + else + lo = i + 1; + } + return null; + } + + public void Dispose() { + reader.Dispose(); + } + } +} diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs new file mode 100644 index 000000000..e68177c80 --- /dev/null +++ b/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs @@ -0,0 +1,405 @@ +// dnlib: See LICENSE.txt for more info + +// C# & Visual Basic compiler's Custom Debug Info is "documented" in source code only, see Roslyn classes: +// CustomDebugInfoReader, CustomDebugInfoWriter, CustomDebugInfoEncoder + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using dnlib.DotNet.Emit; +using dnlib.DotNet.Writer; + +namespace dnlib.DotNet.Pdb { + sealed class PdbCustomDebugInfoWriterContext { + public ILogger Logger; + public readonly MemoryStream MemoryStream; + public readonly BinaryWriter Writer; + public readonly Dictionary InstructionToOffsetDict; + + public PdbCustomDebugInfoWriterContext() { + MemoryStream = new MemoryStream(); + Writer = new BinaryWriter(MemoryStream); + InstructionToOffsetDict = new Dictionary(); + } + } + + /// + /// Writes custom debug infos produced by the C# and Visual Basic compilers. They're stored in PDB files + /// as PDB method custom attributes with the name "MD2". + /// + struct PdbCustomDebugInfoWriter { + readonly MetaData metaData; + readonly MethodDef method; + readonly ILogger logger; + readonly MemoryStream memoryStream; + readonly BinaryWriter writer; + readonly Dictionary instructionToOffsetDict; + uint bodySize; + bool instructionToOffsetDictInitd; + + /// + /// Returns the raw custom debug info or null if there was an error + /// + /// Metadata + /// Writer context + /// Method + /// Custom debug infos to write + /// + public static byte[] Write(MetaData metaData, MethodDef method, PdbCustomDebugInfoWriterContext context, IList customDebugInfos) { + var writer = new PdbCustomDebugInfoWriter(metaData, method, context); + return writer.Write(customDebugInfos); + } + + PdbCustomDebugInfoWriter(MetaData metaData, MethodDef method, PdbCustomDebugInfoWriterContext context) { + this.metaData = metaData; + this.method = method; + this.logger = context.Logger; + this.memoryStream = context.MemoryStream; + this.writer = context.Writer; + this.instructionToOffsetDict = context.InstructionToOffsetDict; + this.bodySize = 0; + this.instructionToOffsetDictInitd = false; + memoryStream.SetLength(0); + memoryStream.Position = 0; + } + + void InitializeInstructionDictionary() { + Debug.Assert(!instructionToOffsetDictInitd); + instructionToOffsetDict.Clear(); + var body = method.Body; + if (body == null) + return; + var instrs = body.Instructions; + uint offset = 0; + for (int i = 0; i < instrs.Count; i++) { + var instr = instrs[i]; + instructionToOffsetDict[instr] = offset; + offset += (uint)instr.GetSize(); + } + bodySize = offset; + instructionToOffsetDictInitd = true; + } + + uint GetInstructionOffset(Instruction instr, bool nullIsEndOfMethod) { + if (!instructionToOffsetDictInitd) + InitializeInstructionDictionary(); + if (instr == null) { + if (nullIsEndOfMethod) + return bodySize; + Error("Instruction is null"); + return uint.MaxValue; + } + uint offset; + if (instructionToOffsetDict.TryGetValue(instr, out offset)) + return offset; + Error("Instruction is missing in body but it's still being referenced by PDB data. Method {0} (0x{1:X8}), instruction: {2}", method, method.MDToken.Raw, instr); + return uint.MaxValue; + } + + void Error(string message, params object[] args) { + logger.Log(this, LoggerEvent.Error, message, args); + } + + byte[] Write(IList customDebugInfos) { + if (customDebugInfos.Count == 0) + return null; + if (customDebugInfos.Count > byte.MaxValue) { + Error("Too many custom debug infos. Count must be <= 255"); + return null; + } + + writer.Write((byte)CustomDebugInfoConstants.Version); + writer.Write((byte)customDebugInfos.Count); + writer.Write((ushort)0); + + for (int i = 0; i < customDebugInfos.Count; i++) { + var info = customDebugInfos[i]; + if (info == null) { + Error("Custom debug info is null"); + return null; + } + if ((uint)info.Kind > byte.MaxValue) { + Error("Invalid custom debug info kind"); + return null; + } + + var recordPos = writer.BaseStream.Position; + writer.Write((byte)CustomDebugInfoConstants.RecordVersion); + writer.Write((byte)info.Kind); + writer.Write((ushort)0); + writer.Write((uint)0); + + int count, j, k; + uint token; + switch (info.Kind) { + case PdbCustomDebugInfoKind.UsingGroups: + var usingRec = info as PdbUsingGroupsCustomDebugInfo; + if (usingRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + count = usingRec.UsingCounts.Count; + if (count > ushort.MaxValue) { + Error("UsingCounts contains more than 0xFFFF elements"); + return null; + } + writer.Write((ushort)count); + for (j = 0; j < count; j++) + writer.Write(usingRec.UsingCounts[j]); + break; + + case PdbCustomDebugInfoKind.ForwardMethodInfo: + var fwdMethodRec = info as PdbForwardMethodInfoCustomDebugInfo; + if (fwdMethodRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + token = GetMethodToken(fwdMethodRec.Method); + if (token == 0) + return null; + writer.Write(token); + break; + + case PdbCustomDebugInfoKind.ForwardModuleInfo: + var fwdModRec = info as PdbForwardModuleInfoCustomDebugInfo; + if (fwdModRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + token = GetMethodToken(fwdModRec.Method); + if (token == 0) + return null; + writer.Write(token); + break; + + case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: + var smLocalScopesRec = info as PdbStateMachineHoistedLocalScopesCustomDebugInfo; + if (smLocalScopesRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + count = smLocalScopesRec.Scopes.Count; + writer.Write(count); + for (j = 0; j < count; j++) { + var scope = smLocalScopesRec.Scopes[j]; + if (scope.IsSynthesizedLocal) { + writer.Write(0); + writer.Write(0); + } + else { + writer.Write(GetInstructionOffset(scope.Start, nullIsEndOfMethod: false)); + writer.Write(GetInstructionOffset(scope.End, nullIsEndOfMethod: true) - 1); + } + } + break; + + case PdbCustomDebugInfoKind.StateMachineTypeName: + var smTypeRec = info as PdbStateMachineTypeNameCustomDebugInfo; + if (smTypeRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + var type = smTypeRec.Type; + if (type == null) { + Error("State machine type is null"); + return null; + } + WriteUnicodeZ(MetadataNameToRoslynName(type.Name)); + break; + + case PdbCustomDebugInfoKind.DynamicLocals: + var dynLocListRec = info as PdbDynamicLocalsCustomDebugInfo; + if (dynLocListRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + count = dynLocListRec.Locals.Count; + writer.Write(count); + for (j = 0; j < count; j++) { + var dynLoc = dynLocListRec.Locals[j]; + if (dynLoc == null) { + Error("Dynamic local is null"); + return null; + } + if (dynLoc.Flags.Count > 64) { + Error("Dynamic local flags is longer than 64 bytes"); + return null; + } + var name = dynLoc.Name; + if (name == null) + name = string.Empty; + if (name.Length > 64) { + Error("Dynamic local name is longer than 64 chars"); + return null; + } + if (name.IndexOf('\0') >= 0) { + Error("Dynamic local name contains a NUL char"); + return null; + } + + for (k = 0; k < dynLoc.Flags.Count; k++) + writer.Write(dynLoc.Flags[k]); + while (k++ < 64) + writer.Write((byte)0); + writer.Write(dynLoc.Flags.Count); + + if (dynLoc.Local == null) + writer.Write(0); + else + writer.Write(dynLoc.Local.Index); + + for (k = 0; k < name.Length; k++) + writer.Write((ushort)name[k]); + while (k++ < 64) + writer.Write((ushort)0); + } + break; + + case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: + var encLocalMapRec = info as PdbEditAndContinueLocalSlotMapCustomDebugInfo; + if (encLocalMapRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + writer.Write(encLocalMapRec.Data); + break; + + case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: + var encLambdaRec = info as PdbEditAndContinueLambdaMapCustomDebugInfo; + if (encLambdaRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + writer.Write(encLambdaRec.Data); + break; + + case PdbCustomDebugInfoKind.TupleElementNames: + var tupleListRec = info as PdbTupleElementNamesCustomDebugInfo; + if (tupleListRec == null) { + Error("Unsupported custom debug info type {0}", info.GetType()); + return null; + } + count = tupleListRec.Names.Count; + writer.Write(count); + for (j = 0; j < count; j++) { + var tupleInfo = tupleListRec.Names[j]; + if (tupleInfo == null) { + Error("Tuple name info is null"); + return null; + } + writer.Write(tupleInfo.TupleElementNames.Count); + for (k = 0; k < tupleInfo.TupleElementNames.Count; k++) + WriteUTF8Z(tupleInfo.TupleElementNames[k]); + + if (tupleInfo.Local == null) { + writer.Write(-1); + writer.Write(GetInstructionOffset(tupleInfo.ScopeStart, nullIsEndOfMethod: false)); + writer.Write(GetInstructionOffset(tupleInfo.ScopeEnd, nullIsEndOfMethod: true)); + } + else { + writer.Write(tupleInfo.Local.Index); + writer.Write(0L); + } + WriteUTF8Z(tupleInfo.Name); + } + break; + + default: + var unkRec = info as PdbUnknownCustomDebugInfo; + if (unkRec == null) { + Error("Unsupported custom debug info class {0}", info.GetType()); + return null; + } + writer.Write(unkRec.Data); + break; + } + + var pos = writer.BaseStream.Position; + var recLen = (pos - recordPos); + var alignedLen = (recLen + 3) & ~3; + if (alignedLen > uint.MaxValue) { + Error("Custom debug info record is too big"); + return null; + } + writer.BaseStream.Position = recordPos + 3; + if (info.Kind <= PdbCustomDebugInfoKind.DynamicLocals) + writer.Write((byte)0); + else + writer.Write((byte)(alignedLen - recLen)); + writer.Write((uint)alignedLen); + + writer.BaseStream.Position = pos; + while (writer.BaseStream.Position < recordPos + alignedLen) + writer.Write((byte)0); + } + + return memoryStream.ToArray(); + } + + string MetadataNameToRoslynName(string name) { + if (name == null) + return name; + int index = name.LastIndexOf('`'); + if (index < 0) + return name; + return name.Substring(0, index); + } + + void WriteUnicodeZ(string s) { + if (s == null) { + Error("String is null"); + return; + } + + if (s.IndexOf('\0') >= 0) { + Error("String contains a NUL char: {0}", s); + return; + } + + for (int i = 0; i < s.Length; i++) + writer.Write((ushort)s[i]); + writer.Write((ushort)0); + } + + void WriteUTF8Z(string s) { + if (s == null) { + Error("String is null"); + return; + } + + if (s.IndexOf('\0') >= 0) { + Error("String contains a NUL char: {0}", s); + return; + } + + writer.Write(Encoding.UTF8.GetBytes(s)); + writer.Write((byte)0); + } + + uint GetMethodToken(IMethodDefOrRef method) { + if (method == null) { + Error("Method is null"); + return 0; + } + + var md = method as MethodDef; + if (md != null) { + uint rid = metaData.GetRid(md); + if (rid == 0) { + Error("Method {0} ({1:X8}) is not defined in this module ({2})", method, method.MDToken.Raw, metaData.Module); + return 0; + } + return new MDToken(md.MDToken.Table, rid).Raw; + } + + var mr = method as MemberRef; + if (mr != null && mr.IsMethodRef) + return metaData.GetToken(mr).Raw; + + Error("Not a method"); + return 0; + } + } +} diff --git a/src/DotNet/Pdb/PdbMethod.cs b/src/DotNet/Pdb/PdbMethod.cs new file mode 100644 index 000000000..5391d713c --- /dev/null +++ b/src/DotNet/Pdb/PdbMethod.cs @@ -0,0 +1,42 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + +namespace dnlib.DotNet.Pdb { + /// + /// A PDB method + /// + public sealed class PdbMethod { + readonly ThreadSafe.IList customDebugInfos; + + /// + /// Gets/sets the root scope. It contains all scopes of the method, using namespaces, variables and constants + /// + public PdbScope Scope { get; set; } + + /// + /// Gets/sets the async method info or null if there's none + /// + public PdbAsyncMethod AsyncMethod { get; set; } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { return customDebugInfos; } + } + + /// + /// Constructor + /// + public PdbMethod() { + customDebugInfos = ThreadSafeListCreator.Create(); + } + } +} diff --git a/src/DotNet/Pdb/PdbScope.cs b/src/DotNet/Pdb/PdbScope.cs index 7bc2c2579..89cd73f67 100644 --- a/src/DotNet/Pdb/PdbScope.cs +++ b/src/DotNet/Pdb/PdbScope.cs @@ -19,6 +19,7 @@ public sealed class PdbScope { readonly ThreadSafe.IList scopes = ThreadSafeListCreator.Create(); readonly ThreadSafe.IList locals = ThreadSafeListCreator.Create(); readonly ThreadSafe.IList namespaces = ThreadSafeListCreator.Create(); + readonly ThreadSafe.IList constants = ThreadSafeListCreator.Create(); /// /// Gets/sets the first instruction @@ -71,5 +72,19 @@ public ThreadSafe.IList Namespaces { public bool HasNamespaces { get { return namespaces.Count > 0; } } + + /// + /// Gets all constants + /// + public ThreadSafe.IList Constants { + get { return constants; } + } + + /// + /// true if is not empty + /// + public bool HasConstants { + get { return constants.Count > 0; } + } } } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 384885db3..244c828e4 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Emit; using dnlib.Threading; @@ -174,7 +175,13 @@ public List RemoveAllDocuments(bool returnDocs) { /// /// Method body /// Method row ID + [Obsolete("Don't use this method, the body gets initialied by dnlib", true)] public void InitializeDontCall(CilBody body, uint methodRid) { + InitializeMethodBody(null, null, body, methodRid); + } + + internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, uint methodRid) { + Debug.Assert((module == null) == (ownerMethod == null)); if (reader == null || body == null) return; var token = new SymbolToken((int)(0x06000000 + methodRid)); @@ -184,15 +191,96 @@ public void InitializeDontCall(CilBody body, uint methodRid) { #endif method = reader.GetMethod(token); if (method != null) { - body.Scope = CreateScope(body, method.RootScope); + var pdbMethod = new PdbMethod(); + pdbMethod.Scope = CreateScope(module, ownerMethod == null ? new GenericParamContext() : GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); + + var method2 = method as ISymbolMethod2; + Debug.Assert(method2 != null); + if (module != null && method2 != null && method2.IsAsyncMethod) + pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method2); + + if (ownerMethod != null) { + // Read the custom debug info last so eg. local names have been initialized + var cdiData = reader.GetSymAttribute(token, "MD2"); + if (cdiData != null && cdiData.Length != 0) + PdbCustomDebugInfoReader.Read(ownerMethod, body, pdbMethod.CustomDebugInfos, cdiData); + } + + body.PdbMethod = pdbMethod; } - //TODO: reader.GetSymAttribute() #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif } + PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, ISymbolMethod2 symMethod) { + var kickoffToken = new MDToken(symMethod.KickoffMethod); + if (kickoffToken.Table != MD.Table.Method) + return null; + var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); + + var rawStepInfos = symMethod.GetAsyncStepInfos(); + + var asyncMethod = new PdbAsyncMethod(rawStepInfos.Length); + asyncMethod.KickoffMethod = kickoffMethod; + + var catchHandlerILOffset = symMethod.CatchHandlerILOffset; + if (catchHandlerILOffset != null) { + asyncMethod.CatchHandlerInstruction = GetInstruction(body, catchHandlerILOffset.Value); + Debug.Assert(asyncMethod.CatchHandlerInstruction != null); + } + + foreach (var rawInfo in rawStepInfos) { + var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); + Debug.Assert(yieldInstruction != null); + if (yieldInstruction == null) + continue; + MethodDef breakpointMethod; + Instruction breakpointInstruction; + if (method.MDToken.Raw == rawInfo.BreakpointMethod) { + breakpointMethod = method; + breakpointInstruction = GetInstruction(body, rawInfo.BreakpointOffset); + } + else { + var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); + Debug.Assert(breakpointMethodToken.Table == MD.Table.Method); + if (breakpointMethodToken.Table != MD.Table.Method) + continue; + breakpointMethod = module.ResolveMethod(breakpointMethodToken.Rid); + Debug.Assert(breakpointMethod != null); + if (breakpointMethod == null) + continue; + breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); + } + Debug.Assert(breakpointInstruction != null); + if (breakpointInstruction == null) + continue; + + asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); + } + + return asyncMethod; + } + + Instruction GetInstruction(CilBody body, uint offset) { + if (body == null) + return null; + var instructions = body.Instructions; + int lo = 0, hi = instructions.Count - 1; + while (lo <= hi && hi != -1) { + int i = (lo + hi) / 2; + var instr = instructions[i]; + if (instr.Offset == offset) + return instr; + if (offset < instr.Offset) + hi = i - 1; + else + lo = i + 1; + } + return null; + } + void AddSequencePoints(CilBody body, ISymbolMethod method) { int numSeqs = method.SequencePointCount; var offsets = new int[numSeqs]; @@ -226,7 +314,7 @@ struct CreateScopeState { public int ChildrenIndex; } - static PdbScope CreateScope(CilBody body, ISymbolScope symScope) { + static PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, ISymbolScope symScope) { if (symScope == null) return null; @@ -258,6 +346,85 @@ static PdbScope CreateScope(CilBody body, ISymbolScope symScope) { foreach (var ns in state.SymScope.GetNamespaces()) state.PdbScope.Namespaces.Add(ns.Name); + var scope2 = state.SymScope as ISymbolScope2; + Debug.Assert(scope2 != null); + if (scope2 != null && module != null) { + var constants = scope2.GetConstants(module, gpContext); + for (int i = 0; i < constants.Length; i++) { + var constant = constants[i]; + var type = constant.Type.RemovePinnedAndModifiers(); + if (type != null) { + // Fix a few values since they're stored as some other type in the PDB + switch (type.ElementType) { + case ElementType.Boolean: + if (constant.Value is short) + constant.Value = (short)constant.Value != 0; + break; + case ElementType.Char: + if (constant.Value is ushort) + constant.Value = (char)(ushort)constant.Value; + break; + case ElementType.I1: + if (constant.Value is short) + constant.Value = (sbyte)(short)constant.Value; + break; + case ElementType.U1: + if (constant.Value is short) + constant.Value = (byte)(short)constant.Value; + break; + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + case ElementType.Void: + case ElementType.Ptr: + case ElementType.ByRef: + case ElementType.TypedByRef: + case ElementType.I: + case ElementType.U: + case ElementType.FnPtr: + case ElementType.ValueType: + break; + case ElementType.String: + // "" is stored as null, and null is stored as (int)0 + if (constant.Value is int && (int)constant.Value == 0) + constant.Value = null; + else if (constant.Value == null) + constant.Value = string.Empty; + break; + case ElementType.Object: + case ElementType.Class: + case ElementType.SZArray: + case ElementType.Array: + default: + if (constant.Value is int && (int)constant.Value == 0) + constant.Value = null; + break; + case ElementType.GenericInst: + var gis = (GenericInstSig)type; + if (gis.GenericType is ValueTypeSig) + break; + goto case ElementType.Class; + case ElementType.Var: + case ElementType.MVar: + var gp = ((GenericSig)type).GenericParam; + if (gp != null) { + if (gp.HasNotNullableValueTypeConstraint) + break; + if (gp.HasReferenceTypeConstraint) + goto case ElementType.Class; + } + break; + } + } + state.PdbScope.Constants.Add(constant); + } + } + // Here's the now somewhat obfuscated for loop state.ChildrenIndex = 0; state.Children = state.SymScope.GetChildren(); diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/PdbWriter.cs index 0df6d38a6..c4a032dd2 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/PdbWriter.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Emit; using dnlib.DotNet.Writer; @@ -13,24 +14,48 @@ namespace dnlib.DotNet.Pdb { /// This class is not thread safe because it's a writer class public sealed class PdbWriter : IDisposable { ISymbolWriter2 writer; + ISymbolWriter3 writer3; readonly PdbState pdbState; readonly ModuleDef module; readonly MetaData metaData; readonly Dictionary pdbDocs = new Dictionary(); readonly SequencePointHelper seqPointsHelper = new SequencePointHelper(); + readonly Dictionary instrToOffset; + readonly PdbCustomDebugInfoWriterContext customDebugInfoWriterContext; /// /// Gets/sets the logger /// public ILogger Logger { get; set; } + /// + /// Constructor + /// + /// Symbol writer, it should implement + /// PDB state + /// Meta data + public PdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) + : this(pdbState, metaData) { + if (writer == null) + throw new ArgumentNullException("writer"); + if (pdbState == null) + throw new ArgumentNullException("pdbState"); + if (metaData == null) + throw new ArgumentNullException("metaData"); + this.writer = writer; + this.writer3 = writer as ISymbolWriter3; + Debug.Assert(writer3 != null, "Symbol writer doesn't implement interface ISymbolWriter3"); + writer.Initialize(metaData); + } + /// /// Constructor /// /// Symbol writer /// PDB state /// Meta data - public PdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) { + public PdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) + : this(pdbState, metaData) { if (writer == null) throw new ArgumentNullException("writer"); if (pdbState == null) @@ -38,10 +63,16 @@ public PdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) { if (metaData == null) throw new ArgumentNullException("metaData"); this.writer = writer; + this.writer3 = writer; + writer.Initialize(metaData); + } + + PdbWriter(PdbState pdbState, MetaData metaData) { this.pdbState = pdbState; this.metaData = metaData; this.module = metaData.Module; - writer.Initialize(metaData); + this.instrToOffset = new Dictionary(); + this.customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); } /// @@ -83,7 +114,7 @@ bool ShouldAddMethod(MethodDef method) { if (body == null) return false; - if (body.HasScope) + if (body.HasPdbMethod) return true; foreach (var local in body.Variables) { @@ -160,6 +191,36 @@ public void Write(PdbWriter pdbWriter, IList instrs) { } } + struct CurrentMethod { + readonly PdbWriter pdbWriter; + public readonly MethodDef Method; + readonly Dictionary toOffset; + public readonly uint BodySize; + + public CurrentMethod(PdbWriter pdbWriter, MethodDef method, Dictionary toOffset) { + this.pdbWriter = pdbWriter; + Method = method; + this.toOffset = toOffset; + toOffset.Clear(); + uint offset = 0; + foreach (var instr in method.Body.Instructions) { + toOffset[instr] = offset; + offset += (uint)instr.GetSize(); + } + BodySize = offset; + } + + public int GetOffset(Instruction instr) { + if (instr == null) + return (int)BodySize; + uint offset; + if (toOffset.TryGetValue(instr, out offset)) + return (int)offset; + pdbWriter.Error("Instruction was removed from the body but is referenced from PdbScope: {0}", instr); + return (int)BodySize; + } + } + void Write(MethodDef method) { uint rid = metaData.GetRid(method); if (rid == 0) { @@ -167,48 +228,148 @@ void Write(MethodDef method) { return; } + var info = new CurrentMethod(this, method, instrToOffset); var body = method.Body; - uint methodSize = GetSizeOfBody(body); - - writer.OpenMethod(new SymbolToken((int)new MDToken(MD.Table.Method, metaData.GetRid(method)).Raw)); - writer.OpenScope(0); - AddLocals(method, body.Variables, 0, methodSize); - seqPointsHelper.Write(this, body.Instructions); - foreach (var scope in GetScopes(body.Scope)) { - foreach (var ns in scope.Namespaces) - writer.UsingNamespace(ns); + var symbolToken = new SymbolToken((int)new MDToken(MD.Table.Method, metaData.GetRid(method)).Raw); + writer.OpenMethod(symbolToken); + seqPointsHelper.Write(this, info.Method.Body.Instructions); + + var pdbMethod = body.PdbMethod; + var scope = pdbMethod.Scope; + if (scope.Namespaces.Count == 0 && scope.Variables.Count == 0 && scope.Constants.Count == 0) { + if (scope.Scopes.Count == 0) { + // We must open at least one sub scope (the sym writer creates the 'method' scope + // which covers the whole method) or the native PDB reader will fail to read all + // sequence points. + writer.OpenScope(0); + writer.CloseScope((int)info.BodySize); + } + else { + foreach (var childScope in scope.Scopes) + WriteScope(ref info, childScope, 0); + } + } + else { + Debug.Fail("Root scope isn't empty"); + WriteScope(ref info, scope, 0); + } + + if (pdbMethod.CustomDebugInfos.Count != 0) { + customDebugInfoWriterContext.Logger = GetLogger(); + var cdiData = PdbCustomDebugInfoWriter.Write(metaData, method, customDebugInfoWriterContext, pdbMethod.CustomDebugInfos); + if (cdiData != null) + writer.SetSymAttribute(symbolToken, "MD2", cdiData); } - writer.CloseScope((int)methodSize); + + var asyncMethod = pdbMethod.AsyncMethod; + if (asyncMethod != null) { + if (writer3 == null || !writer3.SupportsAsyncMethods) + Error("PDB symbol writer doesn't support writing async methods"); + else + WriteAsyncMethod(ref info, asyncMethod); + } + writer.CloseMethod(); } - IEnumerable GetScopes(PdbScope root) { - if (root == null) - return new PdbScope[0]; - return GetScopes(new PdbScope[1] { root }); + uint GetMethodToken(MethodDef method) { + uint rid = metaData.GetRid(method); + if (rid == 0) + Error("Method {0} ({1:X8}) is not defined in this module ({2})", method, method.MDToken.Raw, module); + return new MDToken(MD.Table.Method, rid).Raw; } - IEnumerable GetScopes(IEnumerable scopes) { - var visited = new Dictionary(); - var stack = new Stack>(); - if (scopes != null) - stack.Push(scopes.GetEnumerator()); - while (stack.Count > 0) { - var enumerator = stack.Pop(); - while (enumerator.MoveNext()) { - var type = enumerator.Current; - if (visited.ContainsKey(type)) { - Error("PdbScope present more than once"); - continue; - } - visited[type] = true; - yield return type; - if (type.Scopes.Count > 0) { - stack.Push(enumerator); - enumerator = type.Scopes.GetEnumerator(); + void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethod asyncMethod) { + if (asyncMethod.KickoffMethod == null) { + Error("KickoffMethod is null"); + return; + } + + uint kickoffMethod = GetMethodToken(asyncMethod.KickoffMethod); + writer3.DefineKickoffMethod(kickoffMethod); + + if (asyncMethod.CatchHandlerInstruction != null) { + int catchHandlerILOffset = info.GetOffset(asyncMethod.CatchHandlerInstruction); + writer3.DefineCatchHandlerILOffset((uint)catchHandlerILOffset); + } + + var stepInfos = asyncMethod.StepInfos; + var yieldOffsets = new uint[stepInfos.Count]; + var breakpointOffset = new uint[stepInfos.Count]; + var breakpointMethods = new uint[stepInfos.Count]; + for (int i = 0; i < yieldOffsets.Length; i++) { + var stepInfo = stepInfos[i]; + if (stepInfo.YieldInstruction == null) { + Error("YieldInstruction is null"); + return; + } + if (stepInfo.BreakpointMethod == null) { + Error("BreakpointInstruction is null"); + return; + } + if (stepInfo.BreakpointInstruction == null) { + Error("BreakpointInstruction is null"); + return; + } + yieldOffsets[i] = (uint)info.GetOffset(stepInfo.YieldInstruction); + breakpointOffset[i] = (uint)GetExternalInstructionOffset(ref info, stepInfo.BreakpointMethod, stepInfo.BreakpointInstruction); + breakpointMethods[i] = GetMethodToken(stepInfo.BreakpointMethod); + } + writer3.DefineAsyncStepInfo(yieldOffsets, breakpointOffset, breakpointMethods); + } + + int GetExternalInstructionOffset(ref CurrentMethod info, MethodDef method, Instruction instr) { + if (info.Method == method) + return info.GetOffset(instr); + var body = method.Body; + if (body == null) { + Error("Method body is null"); + return 0; + } + + var instrs = body.Instructions; + int offset = 0; + for (int i = 0; i < instrs.Count; i++) { + var currInstr = instrs[i]; + if (currInstr == instr) + return offset; + offset += currInstr.GetSize(); + } + if (instr == null) + return offset; + Error("Instruction has been removed but it's referenced by PDB info"); + return 0; + } + + void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { + if (recursionCounter >= 1000) { + Error("Too many PdbScopes"); + return; + } + + int startOffset = info.GetOffset(scope.Start); + int endOffset = info.GetOffset(scope.End); + writer.OpenScope(startOffset); + AddLocals(info.Method, scope.Variables, (uint)startOffset, (uint)endOffset); + if (scope.Constants.Count > 0) { + if (writer3 == null) + Error("Symbol writer doesn't implement ISymbolWriter3: no constants can be written to the PDB file"); + else { + var constants = scope.Constants; + var sig = new FieldSig(); + for (int i = 0; i < constants.Count; i++) { + var constant = constants[i]; + sig.Type = constant.Type; + var token = metaData.GetToken(sig); + writer3.DefineConstant2(constant.Name, constant.Value ?? 0, token.Raw); } } } + foreach (var ns in scope.Namespaces) + writer.UsingNamespace(ns); + foreach (var childScope in scope.Scopes) + WriteScope(ref info, childScope, recursionCounter + 1); + writer.CloseScope(endOffset); } void AddLocals(MethodDef method, IList locals, uint startOffset, uint endOffset) { @@ -227,13 +388,6 @@ void AddLocals(MethodDef method, IList locals, uint startOffset, uint end } } - uint GetSizeOfBody(CilBody body) { - uint offset = 0; - foreach (var instr in body.Instructions) - offset += (uint)instr.GetSize(); - return offset; - } - int GetUserEntryPointToken() { var ep = pdbState.UserEntryPoint; if (ep == null) diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 35efe238f..dc5232567 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -1597,6 +1597,10 @@ public MDToken GetToken(object o) { if (methodSig != null) return new MDToken(Table.StandAloneSig, AddStandAloneSig(methodSig, methodSig.OriginalToken)); + var fieldSig = o as FieldSig; + if (fieldSig != null) + return new MDToken(Table.StandAloneSig, AddStandAloneSig(fieldSig, 0)); + if (o == null) Error("Instruction operand is null"); else @@ -1633,6 +1637,24 @@ protected virtual uint AddStandAloneSig(MethodSig methodSig, uint origToken) { return rid; } + /// + /// Adds a + /// + /// FIeld signature + /// Original StandAloneSig token or 0 if none + /// Its new rid + protected virtual uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { + if (fieldSig == null) { + Error("StandAloneSig: FieldSig is null"); + return 0; + } + + var row = new RawStandAloneSigRow(GetSignature(fieldSig)); + uint rid = tablesHeap.StandAloneSigTable.Add(row); + //TODO: Add custom attributes + return rid; + } + uint AddMDTokenProvider(IMDTokenProvider tp) { if (tp != null) { switch (tp.MDToken.Table) { diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 49f625471..c1d1f4b3d 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -187,7 +187,7 @@ public bool IsExeFile { /// /// If or aren't enough, this can be used - /// to create a new instance. must be + /// to create a new instance. must be /// true or this property is ignored. /// public CreatePdbSymbolWriterDelegate CreatePdbSymbolWriter { get; set; } diff --git a/src/DotNet/Writer/PreserveTokensMetaData.cs b/src/DotNet/Writer/PreserveTokensMetaData.cs index 99c3b129f..2cda111dd 100644 --- a/src/DotNet/Writer/PreserveTokensMetaData.cs +++ b/src/DotNet/Writer/PreserveTokensMetaData.cs @@ -1175,6 +1175,17 @@ protected override uint AddStandAloneSig(MethodSig methodSig, uint origToken) { return rid; } + /// + protected override uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { + if (!PreserveStandAloneSigRids || !IsValidStandAloneSigToken(origToken)) + return base.AddStandAloneSig(fieldSig, origToken); + + uint rid = AddStandAloneSig(fieldSig, origToken); + if (rid == 0) + return base.AddStandAloneSig(fieldSig, origToken); + return rid; + } + uint AddStandAloneSig(CallingConventionSig callConvSig, uint origToken) { uint sig = GetSignature(callConvSig); uint otherSig; diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 30e7c5a3f..cf9b71a44 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -173,7 +173,18 @@ + + + + + + + + + + + From 74344ec857352f7fed14e15e046987efe4dc7ab5 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 25 Jun 2017 17:22:34 +0200 Subject: [PATCH 031/511] Make sure VS2010 can still compile the code --- src/DotNet/Pdb/PdbConstant.cs | 25 +++++++++++++++++++------ src/DotNet/Pdb/PdbCustomDebugInfo.cs | 4 ++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs index 4be90daa9..14ef2f0ca 100644 --- a/src/DotNet/Pdb/PdbConstant.cs +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -5,20 +5,33 @@ namespace dnlib.DotNet.Pdb { /// A constant in a method scope, eg. "const int SomeConstant = 123;" /// public struct PdbConstant { + string name; + TypeSig type; + object value; + /// /// Gets/sets the name /// - public string Name { get; set; } + public string Name { + get { return name; } + set { name = value; } + } /// /// Gets/sets the type of the constant /// - public TypeSig Type { get; set; } + public TypeSig Type { + get { return type; } + set { type = value; } + } /// /// Gets/sets the value of the constant /// - public object Value { get; set; } + public object Value { + get { return value; } + set { this.value = value; } + } /// /// Constructor @@ -27,9 +40,9 @@ public struct PdbConstant { /// Type of constant /// Constant value public PdbConstant(string name, TypeSig type, object value) { - Name = name; - Type = type; - Value = value; + this.name = name; + this.type = type; + this.value = value; } /// diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 11fc983fa..9e342b673 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -368,7 +368,7 @@ public ThreadSafe.IList Flags { /// /// Gets/sets the name of the local. The name must have at most 64 characters and no char can be NUL (0x0000). - /// If null is written, is returned instead. + /// If null is written, is returned instead. /// public string Name { get { @@ -527,7 +527,7 @@ public sealed class PdbTupleElementNames { Instruction scopeStart, scopeEnd; /// - /// Gets/sets the name of the local. If null is written, is returned instead. + /// Gets/sets the name of the local. If null is written, is returned instead. /// public string Name { get { From ad9df04b252d6dc81d17222e6fa0b6aca1cc020f Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 25 Jun 2017 21:23:55 +0200 Subject: [PATCH 032/511] Update PDB reader/writer, #94 --- src/DotNet/ModuleDef.cs | 2 +- src/DotNet/Pdb/PdbState.cs | 64 +++++++++++++++++++++++++++++++++++-- src/DotNet/Pdb/PdbWriter.cs | 4 ++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 8708e74d9..c8cb077f6 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1175,7 +1175,7 @@ public ResourceData FindWin32ResourceData(ResourceName type, ResourceName name, /// Creates a new /// public void CreatePdbState() { - SetPdbState(new PdbState()); + SetPdbState(new PdbState(this)); } /// diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 244c828e4..aa53557a8 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -15,6 +15,13 @@ public sealed class PdbState { readonly ISymbolReader reader; readonly Dictionary docDict = new Dictionary(); MethodDef userEntryPoint; + ThreeState isVisualBasicModule; + + enum ThreeState { + Unknown, + No, + Yes, + } #if THREAD_SAFE readonly Lock theLock = Lock.Create(); @@ -62,9 +69,21 @@ public bool HasDocuments { /// /// Default constructor /// + [Obsolete("Use PdbState(ModuleDef) constructor")] public PdbState() { } + /// + /// Constructor + /// + /// Module + public PdbState(ModuleDef module) { + if (module == null) + throw new ArgumentNullException("module"); + this.isVisualBasicModule = CalculateIsVisualBasicModule(module); + Debug.Assert(isVisualBasicModule != ThreeState.Unknown); + } + /// /// Constructor /// @@ -77,6 +96,9 @@ public PdbState(ISymbolReader reader, ModuleDefMD module) { throw new ArgumentNullException("module"); this.reader = reader; + this.isVisualBasicModule = CalculateIsVisualBasicModule(module); + Debug.Assert(isVisualBasicModule != ThreeState.Unknown); + this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint.GetToken()) as MethodDef; foreach (var doc in reader.GetDocuments()) @@ -180,10 +202,22 @@ public void InitializeDontCall(CilBody body, uint methodRid) { InitializeMethodBody(null, null, body, methodRid); } + internal bool IsVisualBasicModule { + get { + Debug.Assert(isVisualBasicModule != ThreeState.Unknown); + return isVisualBasicModule == ThreeState.Yes; + } + } + internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, uint methodRid) { Debug.Assert((module == null) == (ownerMethod == null)); if (reader == null || body == null) return; + + if (isVisualBasicModule == ThreeState.Unknown) + isVisualBasicModule = CalculateIsVisualBasicModule(module); + Debug.Assert(isVisualBasicModule != ThreeState.Unknown); + var token = new SymbolToken((int)(0x06000000 + methodRid)); ISymbolMethod method; #if THREAD_SAFE @@ -214,6 +248,27 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci #endif } + ThreeState CalculateIsVisualBasicModule(ModuleDef module) { + if (module == null) + return ThreeState.No; + foreach (var asmRef in module.GetAssemblyRefs()) { + if (asmRef.Name == nameAssemblyVisualBasic) + return ThreeState.Yes; + } + + // The VB runtime can also be embedded, and if so, it seems that "Microsoft.VisualBasic.Embedded" + // attribute is added to the assembly's custom attributes. + var asm = module.Assembly; + if (asm != null) { + var ca = asm.CustomAttributes.Find("Microsoft.VisualBasic.Embedded"); + if (ca != null) + return ThreeState.Yes; + } + + return ThreeState.No; + } + static readonly UTF8String nameAssemblyVisualBasic = new UTF8String("Microsoft.VisualBasic"); + PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, ISymbolMethod2 symMethod) { var kickoffToken = new MDToken(symMethod.KickoffMethod); if (kickoffToken.Table != MD.Table.Method) @@ -314,7 +369,7 @@ struct CreateScopeState { public int ChildrenIndex; } - static PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, ISymbolScope symScope) { + PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, ISymbolScope symScope) { if (symScope == null) return null; @@ -323,9 +378,10 @@ static PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, C var state = new CreateScopeState() { SymScope = symScope }; recursive_call: int instrIndex = 0; + int endIsInclusiveValue = isVisualBasicModule == ThreeState.Yes ? 1 : 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), - End = GetInstruction(body.Instructions, state.SymScope.EndOffset, ref instrIndex), + End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), }; foreach (var symLocal in state.SymScope.GetLocals()) { @@ -333,8 +389,10 @@ static PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, C continue; int localIndex = symLocal.AddressField1; - if ((uint)localIndex >= (uint)body.Variables.Count) + if ((uint)localIndex >= (uint)body.Variables.Count) { + // VB sometimes creates a PDB local without a metadata local continue; + } var local = body.Variables[localIndex]; local.Name = symLocal.Name; var attributes = symLocal.Attributes; diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/PdbWriter.cs index c4a032dd2..743977242 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/PdbWriter.cs @@ -22,6 +22,7 @@ public sealed class PdbWriter : IDisposable { readonly SequencePointHelper seqPointsHelper = new SequencePointHelper(); readonly Dictionary instrToOffset; readonly PdbCustomDebugInfoWriterContext customDebugInfoWriterContext; + readonly int localsEndScopeIncValue; /// /// Gets/sets the logger @@ -73,6 +74,7 @@ public PdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) this.module = metaData.Module; this.instrToOffset = new Dictionary(); this.customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); + this.localsEndScopeIncValue = pdbState.IsVisualBasicModule ? 1 : 0; } /// @@ -369,7 +371,7 @@ void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { writer.UsingNamespace(ns); foreach (var childScope in scope.Scopes) WriteScope(ref info, childScope, recursionCounter + 1); - writer.CloseScope(endOffset); + writer.CloseScope(startOffset == 0 && endOffset == info.BodySize ? endOffset : endOffset - localsEndScopeIncValue); } void AddLocals(MethodDef method, IList locals, uint startOffset, uint endOffset) { From 2e32db012d9ca8d67de1061b4be896ce42134569 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 26 Jun 2017 12:46:12 +0200 Subject: [PATCH 033/511] Change internal prop to a method --- src/DotNet/Pdb/PdbState.cs | 46 +++++++++++++++---------------------- src/DotNet/Pdb/PdbWriter.cs | 2 +- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index aa53557a8..b5daeee91 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -15,13 +15,7 @@ public sealed class PdbState { readonly ISymbolReader reader; readonly Dictionary docDict = new Dictionary(); MethodDef userEntryPoint; - ThreeState isVisualBasicModule; - - enum ThreeState { - Unknown, - No, - Yes, - } + Compiler compiler; #if THREAD_SAFE readonly Lock theLock = Lock.Create(); @@ -80,8 +74,7 @@ public PdbState() { public PdbState(ModuleDef module) { if (module == null) throw new ArgumentNullException("module"); - this.isVisualBasicModule = CalculateIsVisualBasicModule(module); - Debug.Assert(isVisualBasicModule != ThreeState.Unknown); + this.compiler = CalculateCompiler(module); } /// @@ -95,9 +88,7 @@ public PdbState(ISymbolReader reader, ModuleDefMD module) { if (module == null) throw new ArgumentNullException("module"); this.reader = reader; - - this.isVisualBasicModule = CalculateIsVisualBasicModule(module); - Debug.Assert(isVisualBasicModule != ThreeState.Unknown); + this.compiler = CalculateCompiler(module); this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint.GetToken()) as MethodDef; @@ -202,11 +193,10 @@ public void InitializeDontCall(CilBody body, uint methodRid) { InitializeMethodBody(null, null, body, methodRid); } - internal bool IsVisualBasicModule { - get { - Debug.Assert(isVisualBasicModule != ThreeState.Unknown); - return isVisualBasicModule == ThreeState.Yes; - } + internal Compiler GetCompiler(ModuleDef module) { + if (compiler == Compiler.Unknown) + compiler = CalculateCompiler(module); + return compiler; } internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, uint methodRid) { @@ -214,10 +204,6 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci if (reader == null || body == null) return; - if (isVisualBasicModule == ThreeState.Unknown) - isVisualBasicModule = CalculateIsVisualBasicModule(module); - Debug.Assert(isVisualBasicModule != ThreeState.Unknown); - var token = new SymbolToken((int)(0x06000000 + methodRid)); ISymbolMethod method; #if THREAD_SAFE @@ -248,12 +234,12 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci #endif } - ThreeState CalculateIsVisualBasicModule(ModuleDef module) { + Compiler CalculateCompiler(ModuleDef module) { if (module == null) - return ThreeState.No; + return Compiler.Other; foreach (var asmRef in module.GetAssemblyRefs()) { if (asmRef.Name == nameAssemblyVisualBasic) - return ThreeState.Yes; + return Compiler.VisualBasic; } // The VB runtime can also be embedded, and if so, it seems that "Microsoft.VisualBasic.Embedded" @@ -262,10 +248,10 @@ ThreeState CalculateIsVisualBasicModule(ModuleDef module) { if (asm != null) { var ca = asm.CustomAttributes.Find("Microsoft.VisualBasic.Embedded"); if (ca != null) - return ThreeState.Yes; + return Compiler.VisualBasic; } - return ThreeState.No; + return Compiler.Other; } static readonly UTF8String nameAssemblyVisualBasic = new UTF8String("Microsoft.VisualBasic"); @@ -378,7 +364,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody var state = new CreateScopeState() { SymScope = symScope }; recursive_call: int instrIndex = 0; - int endIsInclusiveValue = isVisualBasicModule == ThreeState.Yes ? 1 : 0; + int endIsInclusiveValue = GetCompiler(module) == Compiler.VisualBasic ? 1 : 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), @@ -531,4 +517,10 @@ static Instruction GetInstruction(IList instrs, int offset, ref int return null; } } + + enum Compiler { + Unknown, + Other, + VisualBasic, + } } diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/PdbWriter.cs index 743977242..7e480cf41 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/PdbWriter.cs @@ -74,7 +74,7 @@ public PdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) this.module = metaData.Module; this.instrToOffset = new Dictionary(); this.customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); - this.localsEndScopeIncValue = pdbState.IsVisualBasicModule ? 1 : 0; + this.localsEndScopeIncValue = pdbState.GetCompiler(metaData.module) == Compiler.VisualBasic ? 1 : 0; } /// From 6072d7e89f2ea6854f60c60da639b0bbf336ee5c Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 27 Jun 2017 20:44:53 +0200 Subject: [PATCH 034/511] Remove unused local --- src/DotNet/Pdb/PdbCustomDebugInfoReader.cs | 2 -- src/DotNet/Pdb/PdbState.cs | 8 +++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs index 0521d9108..556e26d6a 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs @@ -138,7 +138,6 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { if (count < 0) return null; var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); - int maxEndOffset = -1; for (int i = 0; i < count; i++) { uint startOffset = reader.ReadUInt32(); uint endOffset = reader.ReadUInt32(); @@ -156,7 +155,6 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { return null; smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); } - maxEndOffset = Math.Max(maxEndOffset, (int)endOffset + 1); } return smScope; diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index b5daeee91..a2ee74dbe 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -237,6 +237,7 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci Compiler CalculateCompiler(ModuleDef module) { if (module == null) return Compiler.Other; + foreach (var asmRef in module.GetAssemblyRefs()) { if (asmRef.Name == nameAssemblyVisualBasic) return Compiler.VisualBasic; @@ -245,11 +246,8 @@ Compiler CalculateCompiler(ModuleDef module) { // The VB runtime can also be embedded, and if so, it seems that "Microsoft.VisualBasic.Embedded" // attribute is added to the assembly's custom attributes. var asm = module.Assembly; - if (asm != null) { - var ca = asm.CustomAttributes.Find("Microsoft.VisualBasic.Embedded"); - if (ca != null) - return Compiler.VisualBasic; - } + if (asm != null && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) + return Compiler.VisualBasic; return Compiler.Other; } From 823254a64e2e11ebec770ad19f52d1c29e9224c6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 1 Jul 2017 13:34:45 +0200 Subject: [PATCH 035/511] Misc --- src/DotNet/Pdb/Managed/DbiScope.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 2c49b891e..40f97fdda 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -119,7 +119,7 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { case SymbolType.S_END: break; default: - Debug.Write("Unknown symbol type: " + type); + Debug.Fail("Unknown symbol type: " + type); break; } @@ -165,7 +165,7 @@ public PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpCont for (int i = 0; i < res.Length; i++) { var info = constants[i]; TypeSig signature; - var saSig = module.ResolveToken(info.SignatureToken) as StandAloneSig; + var saSig = module.ResolveToken(info.SignatureToken, gpContext) as StandAloneSig; var fieldSig = saSig == null ? null : saSig.Signature as FieldSig; if (fieldSig == null) { Debug.Fail("Constant without a signature"); From 85054f14674dc30430cc908c6395107e1229f33d Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 9 Jul 2017 11:18:42 +0200 Subject: [PATCH 036/511] Show an error if there are too many locals --- src/DotNet/Writer/SignatureWriter.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index c7dd1611b..9f915f5f2 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -292,6 +292,10 @@ void Write(LocalSig sig) { writer.Write((byte)sig.GetCallingConvention()); uint count = WriteCompressedUInt32((uint)sig.Locals.Count); + if (count >= 0x10000) { + // ldloc 0xFFFF is invalid, see the ldloc documentation + helper.Error("Too many locals, max number of locals is 65535 (0xFFFF)"); + } for (uint i = 0; i < count; i++) Write(sig.Locals[(int)i]); From 67ce9c5a4f16bf1e611e459d64e6f9dfb8b4c911 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Jul 2017 11:22:12 +0200 Subject: [PATCH 037/511] Avoid boxing --- src/DotNet/Writer/StringsHeap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index 0637711ee..cf19b93b1 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -94,7 +94,7 @@ public uint Create(UTF8String s) { } uint AddToCache(UTF8String s) { - if (Array.IndexOf(s.Data, 0) >= 0) + if (Array.IndexOf(s.Data, (byte)0) >= 0) throw new ArgumentException("Strings in the #Strings heap can't contain 00h bytes"); uint offset; From c0034e2864b3e44c26ff0c7c71588dd2c55fdf81 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Jul 2017 12:39:39 +0200 Subject: [PATCH 038/511] Alloc less --- src/DotNet/Writer/CustomAttributeWriter.cs | 29 ++++++++++++++++++++++ src/DotNet/Writer/DeclSecurityWriter.cs | 14 ++++++++--- src/DotNet/Writer/MaxStackCalculator.cs | 24 +++++++++++++++--- src/DotNet/Writer/MetaData.cs | 21 ++++++++++++---- src/DotNet/Writer/MethodBodyWriter.cs | 19 ++++++++++++-- src/DotNet/Writer/MethodBodyWriterBase.cs | 19 +++++++++++--- src/DotNet/Writer/SignatureWriter.cs | 28 +++++++++++++++++++++ 7 files changed, 138 insertions(+), 16 deletions(-) diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index 113452736..b47623b1f 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -19,6 +19,7 @@ public struct CustomAttributeWriter : IDisposable { RecursionCounter recursionCounter; readonly MemoryStream outStream; readonly BinaryWriter writer; + readonly bool disposeStream; GenericArguments genericArguments; /// @@ -34,6 +35,13 @@ public static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute } } + internal static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute ca, BinaryWriterContext context) { + using (var writer = new CustomAttributeWriter(helper, context)) { + writer.Write(ca); + return writer.GetResult(); + } + } + /// /// Writes custom attribute named arguments /// @@ -47,12 +55,31 @@ internal static byte[] Write(ICustomAttributeWriterHelper helper, IList namedArgs, BinaryWriterContext context) { + using (var writer = new CustomAttributeWriter(helper, context)) { + writer.Write(namedArgs); + return writer.GetResult(); + } + } + CustomAttributeWriter(ICustomAttributeWriterHelper helper) { this.helper = helper; this.recursionCounter = new RecursionCounter(); this.outStream = new MemoryStream(); this.writer = new BinaryWriter(outStream); this.genericArguments = null; + this.disposeStream = true; + } + + CustomAttributeWriter(ICustomAttributeWriterHelper helper, BinaryWriterContext context) { + this.helper = helper; + this.recursionCounter = new RecursionCounter(); + this.outStream = context.OutStream; + this.writer = context.Writer; + this.genericArguments = null; + this.disposeStream = false; + outStream.SetLength(0); + outStream.Position = 0; } byte[] GetResult() { @@ -742,6 +769,8 @@ void WriteUTF8String(UTF8String s) { /// public void Dispose() { + if (!disposeStream) + return; if (outStream != null) outStream.Dispose(); if (writer != null) diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 71d40c528..62680dc34 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -11,6 +11,7 @@ namespace dnlib.DotNet.Writer { public struct DeclSecurityWriter : ICustomAttributeWriterHelper { readonly ModuleDef module; readonly IWriterError helper; + readonly BinaryWriterContext context; /// /// Creates a DeclSecurity blob from @@ -20,12 +21,17 @@ public struct DeclSecurityWriter : ICustomAttributeWriterHelper { /// Helps this class /// A DeclSecurity blob public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper) { - return new DeclSecurityWriter(module, helper).Write(secAttrs); + return new DeclSecurityWriter(module, helper, null).Write(secAttrs); } - DeclSecurityWriter(ModuleDef module, IWriterError helper) { + internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, BinaryWriterContext context) { + return new DeclSecurityWriter(module, helper, context).Write(secAttrs); + } + + DeclSecurityWriter(ModuleDef module, IWriterError helper, BinaryWriterContext context) { this.module = module; this.helper = helper; + this.context = context; } byte[] Write(IList secAttrs) { @@ -66,7 +72,9 @@ byte[] WriteFormat2(IList secAttrs) { fqn = attrType.AssemblyQualifiedName; Write(writer, fqn); - var namedArgsBlob = CustomAttributeWriter.Write(this, sa.NamedArguments); + var namedArgsBlob = context == null ? + CustomAttributeWriter.Write(this, sa.NamedArguments) : + CustomAttributeWriter.Write(this, sa.NamedArguments, context); if (namedArgsBlob.Length > 0x1FFFFFFF) { helper.Error("Named arguments blob size doesn't fit in 29 bits"); namedArgsBlob = new byte[0]; diff --git a/src/DotNet/Writer/MaxStackCalculator.cs b/src/DotNet/Writer/MaxStackCalculator.cs index 7654194a8..91d0ccafa 100644 --- a/src/DotNet/Writer/MaxStackCalculator.cs +++ b/src/DotNet/Writer/MaxStackCalculator.cs @@ -10,8 +10,8 @@ namespace dnlib.DotNet.Writer { /// can be placed in the fat method header's MaxStack field. /// public struct MaxStackCalculator { - readonly IList instructions; - readonly IList exceptionHandlers; + IList instructions; + IList exceptionHandlers; readonly Dictionary stackHeights; int errors; @@ -38,6 +38,17 @@ public static bool GetMaxStack(IList instructions, IList(); + this.errors = 0; + } + MaxStackCalculator(IList instructions, IList exceptionHandlers) { this.instructions = instructions; this.exceptionHandlers = exceptionHandlers; @@ -45,7 +56,14 @@ public static bool GetMaxStack(IList instructions, IList instructions, IList exceptionHandlers) { + this.instructions = instructions; + this.exceptionHandlers = exceptionHandlers; + stackHeights.Clear(); + errors = 0; + } + + internal bool Calculate(out uint maxStack) { foreach (var eh in exceptionHandlers) { if (eh == null) continue; diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index dc5232567..8753042c8 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -231,6 +231,15 @@ public MetaDataOptions(MetaDataHeaderOptions mdhOptions, MetaDataFlags flags) { } } + sealed class BinaryWriterContext { + public readonly MemoryStream OutStream; + public readonly BinaryWriter Writer; + public BinaryWriterContext() { + OutStream = new MemoryStream(); + Writer = new BinaryWriter(OutStream); + } + } + /// /// .NET meta data /// @@ -280,6 +289,7 @@ public abstract class MetaData : IChunk, ISignatureWriterHelper, ITokenCreator, internal readonly Dictionary methodToNativeBody = new Dictionary(); internal readonly Dictionary embeddedResourceToByteArray = new Dictionary(); readonly Dictionary fieldToInitialValue = new Dictionary(); + readonly BinaryWriterContext binaryWriterContext = new BinaryWriterContext(); /// /// Gets/sets the listener @@ -1527,6 +1537,7 @@ void WriteMethodBodies() { int notifyAfter = numMethods / numNotifyEvents; bool keepMaxStack = KeepOldMaxStack; + var writer = new MethodBodyWriter(this); foreach (var type in allTypeDefs) { if (type == null) continue; @@ -1547,7 +1558,7 @@ void WriteMethodBodies() { if (cilBody != null) { if (cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0) continue; - var writer = new MethodBodyWriter(this, cilBody, keepMaxStack || cilBody.KeepOldMaxStack); + writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); writer.Write(); var mb = methodBodies.Add(new MethodBody(writer.Code, writer.ExtraSections, writer.LocalVarSigTok)); methodToBody[method] = mb; @@ -2291,7 +2302,7 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit continue; var row = new RawDeclSecurityRow((short)decl.Action, encodedParent, - blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this))); + blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this, binaryWriterContext))); declSecurityInfos.Add(decl, row); } } @@ -2532,7 +2543,7 @@ protected uint GetSignature(TypeSig ts, byte[] extraData) { blob = null; } else - blob = SignatureWriter.Write(this, ts); + blob = SignatureWriter.Write(this, ts, binaryWriterContext); AppendExtraData(ref blob, extraData); return blobHeap.Add(blob); } @@ -2548,7 +2559,7 @@ protected uint GetSignature(CallingConventionSig sig) { return 0; } - var blob = SignatureWriter.Write(this, sig); + var blob = SignatureWriter.Write(this, sig, binaryWriterContext); AppendExtraData(ref blob, sig.ExtraData); return blobHeap.Add(blob); } @@ -2587,7 +2598,7 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { Error("Can't encode HasCustomAttribute token {0:X8}", token.Raw); encodedToken = 0; } - var caBlob = CustomAttributeWriter.Write(this, ca); + var caBlob = CustomAttributeWriter.Write(this, ca, binaryWriterContext); var row = new RawCustomAttributeRow(encodedToken, AddCustomAttributeType(ca.Constructor), blobHeap.Add(caBlob)); diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 25aac1fc1..0430a20c6 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -32,8 +32,8 @@ public interface ITokenCreator : IWriterError { /// public sealed class MethodBodyWriter : MethodBodyWriterBase { readonly ITokenCreator helper; - readonly CilBody cilBody; - readonly bool keepMaxStack; + CilBody cilBody; + bool keepMaxStack; uint codeSize; uint maxStack; byte[] code; @@ -87,6 +87,21 @@ public MethodBodyWriter(ITokenCreator helper, CilBody cilBody, bool keepMaxStack this.keepMaxStack = keepMaxStack; } + internal MethodBodyWriter(ITokenCreator helper) { + this.helper = helper; + } + + internal void Reset(CilBody cilBody, bool keepMaxStack) { + Reset(cilBody.Instructions, cilBody.ExceptionHandlers); + this.cilBody = cilBody; + this.keepMaxStack = keepMaxStack; + codeSize = 0; + maxStack = 0; + code = null; + extraSections = null; + localVarSigTok = 0; + } + /// /// Writes the method body /// diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index af659c6f4..09fd5dddd 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -10,12 +10,13 @@ namespace dnlib.DotNet.Writer { /// public abstract class MethodBodyWriterBase { /// - protected readonly IList instructions; + protected IList instructions; /// - protected readonly IList exceptionHandlers; + protected IList exceptionHandlers; readonly Dictionary offsets = new Dictionary(); uint firstInstructionOffset; int errors; + MaxStackCalculator maxStackCalculator = MaxStackCalculator.Create(); /// /// true if there was at least one error @@ -24,6 +25,9 @@ public bool ErrorDetected { get { return errors > 0; } } + internal MethodBodyWriterBase() { + } + /// /// Constructor /// @@ -34,6 +38,14 @@ protected MethodBodyWriterBase(IList instructions, IList instructions, IList exceptionHandlers) { + this.instructions = instructions; + this.exceptionHandlers = exceptionHandlers; + offsets.Clear(); + firstInstructionOffset = 0; + errors = 0; + } + /// /// Called when an error is detected (eg. a null pointer). The error can be /// ignored but the method won't be valid. @@ -59,7 +71,8 @@ protected uint GetMaxStack() { if (instructions.Count == 0) return 0; uint maxStack; - if (!MaxStackCalculator.GetMaxStack(instructions, exceptionHandlers, out maxStack)) { + maxStackCalculator.Reset(instructions, exceptionHandlers); + if (!maxStackCalculator.Calculate(out maxStack)) { Error("Error calculating max stack value. If the method's obfuscated, set CilBody.KeepOldMaxStack or MetaDataOptions.Flags (KeepOldMaxStack, global option) to ignore this error. Otherwise fix your generated CIL code so it conforms to the ECMA standard."); maxStack += 8; } diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index 9f915f5f2..cf4b4384b 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -23,6 +23,7 @@ public struct SignatureWriter : IDisposable { RecursionCounter recursionCounter; readonly MemoryStream outStream; readonly BinaryWriter writer; + readonly bool disposeStream; /// /// Write a signature @@ -37,6 +38,13 @@ public static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig) { } } + internal static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig, BinaryWriterContext context) { + using (var writer = new SignatureWriter(helper, context)) { + writer.Write(typeSig); + return writer.GetResult(); + } + } + /// /// Write a signature /// @@ -50,11 +58,29 @@ public static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig s } } + internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig sig, BinaryWriterContext context) { + using (var writer = new SignatureWriter(helper, context)) { + writer.Write(sig); + return writer.GetResult(); + } + } + SignatureWriter(ISignatureWriterHelper helper) { this.helper = helper; this.recursionCounter = new RecursionCounter(); this.outStream = new MemoryStream(); this.writer = new BinaryWriter(outStream); + this.disposeStream = true; + } + + SignatureWriter(ISignatureWriterHelper helper, BinaryWriterContext context) { + this.helper = helper; + this.recursionCounter = new RecursionCounter(); + this.outStream = context.OutStream; + this.writer = context.Writer; + this.disposeStream = false; + outStream.SetLength(0); + outStream.Position = 0; } byte[] GetResult() { @@ -322,6 +348,8 @@ void Write(GenericInstMethodSig sig) { /// public void Dispose() { + if (!disposeStream) + return; if (outStream != null) outStream.Dispose(); if (writer != null) From 61e789f1c96cbcc5d6ee691ecb501219ca6666f2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 18 Jul 2017 03:53:30 +0200 Subject: [PATCH 039/511] Misc --- src/DotNet/TypeNameParser.cs | 2 +- src/DotNet/Writer/MethodBodyWriter.cs | 7 ++++--- src/IO/MemoryImageStream.cs | 12 +++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index 628351d74..b2e6573fd 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -608,7 +608,7 @@ TypeDef Resolve(AssemblyRef asmRef, TypeRef typeRef) { var asm = ownerModule.Assembly; if (asm == null) return null; - if (asmRef.FullName != asm.GetFullNameWithPublicKey() && asmRef.FullName != asm.GetFullNameWithPublicKeyToken()) + if (!(AssemblyNameComparer.CompareAll.Equals(asmRef, asm) && asmRef.IsRetargetable == asm.IsRetargetable)) return null; var td = typeRef.Resolve(); return td != null && td.Module == ownerModule ? td : null; diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 0430a20c6..77d6f36ff 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using dnlib.DotNet.Emit; namespace dnlib.DotNet.Writer { @@ -151,7 +152,7 @@ void WriteFatHeader() { flags |= 0x10; code = new byte[12 + codeSize]; - var writer = new BinaryWriter(new MemoryStream(code)); + var writer = new BinaryWriter(new MemoryStream(code), Encoding.UTF8); writer.Write(flags); writer.Write((ushort)maxStack); writer.Write(codeSize); @@ -170,7 +171,7 @@ IList GetLocals() { void WriteTinyHeader() { localVarSigTok = 0; code = new byte[1 + codeSize]; - var writer = new BinaryWriter(new MemoryStream(code)); + var writer = new BinaryWriter(new MemoryStream(code), Encoding.UTF8); writer.Write((byte)((codeSize << 2) | 2)); if (WriteInstructions(writer) != codeSize) Error("Didn't write all code bytes"); @@ -178,7 +179,7 @@ void WriteTinyHeader() { void WriteExceptionHandlers() { var outStream = new MemoryStream(); - var writer = new BinaryWriter(outStream); + var writer = new BinaryWriter(outStream, Encoding.UTF8); if (NeedFatExceptionClauses()) WriteFatExceptionClauses(writer); else diff --git a/src/IO/MemoryImageStream.cs b/src/IO/MemoryImageStream.cs index b32a9cf17..6b1b50269 100644 --- a/src/IO/MemoryImageStream.cs +++ b/src/IO/MemoryImageStream.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Text; namespace dnlib.IO { /// @@ -237,15 +238,16 @@ public double ReadDouble() { } /// - public string ReadString(int chars) { + public unsafe string ReadString(int chars) { if ((uint)chars > (uint)int.MaxValue) throw new IOException("Not enough space to read the string"); if (position + chars * 2 < position || (chars != 0 && position + chars * 2 - 1 >= dataEnd)) throw new IOException("Not enough space to read the string"); - var array = new char[chars]; - for (int i = 0; i < chars; i++) - array[i] = (char)(data[position++] | (data[position++] << 8)); - return new string(array); + string res; + fixed (byte* p = data) + res = new string((char*)(p + position), 0, chars); + position += chars * 2; + return res; } /// From ff5862d911695ff3c243f752717ae0372751cb8d Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 26 Jul 2017 11:16:23 +0200 Subject: [PATCH 040/511] Add exception ctors used by serialization, fixes #132 --- src/DotNet/CustomAttributeReader.cs | 10 ++++++ src/DotNet/Emit/InvalidMethodException.cs | 10 ++++++ src/DotNet/Pdb/Managed/PdbException.cs | 16 ++++++++++ src/DotNet/ResolveException.cs | 37 ++++++++++++++++++++++ src/DotNet/Resources/ResourceReader.cs | 16 ++++++++++ src/DotNet/StrongNameKey.cs | 10 ++++++ src/DotNet/TypeNameParser.cs | 10 ++++++ src/DotNet/Writer/ModuleWriterException.cs | 10 ++++++ src/IO/MemoryMappedFileStreamCreator.cs | 8 +++++ src/Threading/Lock.cs | 5 +++ 10 files changed, 132 insertions(+) diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 0ea158d49..06abc6593 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.Serialization; using dnlib.IO; using dnlib.Threading; @@ -73,6 +74,15 @@ public CABlobParserException(string message) public CABlobParserException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected CABlobParserException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// diff --git a/src/DotNet/Emit/InvalidMethodException.cs b/src/DotNet/Emit/InvalidMethodException.cs index bd903180e..35ffaf40f 100644 --- a/src/DotNet/Emit/InvalidMethodException.cs +++ b/src/DotNet/Emit/InvalidMethodException.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Runtime.Serialization; namespace dnlib.DotNet.Emit { /// @@ -30,5 +31,14 @@ public InvalidMethodException(string msg) public InvalidMethodException(string msg, Exception innerException) : base(msg, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected InvalidMethodException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } } diff --git a/src/DotNet/Pdb/Managed/PdbException.cs b/src/DotNet/Pdb/Managed/PdbException.cs index 74bd308ec..be14e2823 100644 --- a/src/DotNet/Pdb/Managed/PdbException.cs +++ b/src/DotNet/Pdb/Managed/PdbException.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Runtime.Serialization; namespace dnlib.DotNet.Pdb.Managed { /// @@ -8,6 +9,12 @@ namespace dnlib.DotNet.Pdb.Managed { /// [Serializable] public sealed class PdbException : Exception { + /// + /// Constructor + /// + public PdbException() { + } + /// /// Constructor /// @@ -23,5 +30,14 @@ public PdbException(string message) public PdbException(Exception innerException) : base("Failed to read PDB: " + innerException.Message, innerException) { } + + /// + /// Constructor + /// + /// + /// + public PdbException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } } \ No newline at end of file diff --git a/src/DotNet/ResolveException.cs b/src/DotNet/ResolveException.cs index 34d1c6bde..812151a12 100644 --- a/src/DotNet/ResolveException.cs +++ b/src/DotNet/ResolveException.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Runtime.Serialization; namespace dnlib.DotNet { /// @@ -30,6 +31,15 @@ public ResolveException(string message) public ResolveException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected ResolveException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// @@ -59,6 +69,15 @@ public AssemblyResolveException(string message) public AssemblyResolveException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected AssemblyResolveException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// @@ -88,6 +107,15 @@ public TypeResolveException(string message) public TypeResolveException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected TypeResolveException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// @@ -117,5 +145,14 @@ public MemberRefResolveException(string message) public MemberRefResolveException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected MemberRefResolveException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 5ec9794d9..2de6dc436 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Runtime.Serialization; using System.Text; using System.Text.RegularExpressions; using dnlib.IO; @@ -12,6 +13,12 @@ namespace dnlib.DotNet.Resources { /// [Serializable] public sealed class ResourceReaderException : Exception { + /// + /// Constructor + /// + public ResourceReaderException() { + } + /// /// Constructor /// @@ -19,6 +26,15 @@ public sealed class ResourceReaderException : Exception { public ResourceReaderException(string msg) : base(msg) { } + + /// + /// Constructor + /// + /// + /// + public ResourceReaderException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// diff --git a/src/DotNet/StrongNameKey.cs b/src/DotNet/StrongNameKey.cs index e91ea8e1e..1f110eafd 100644 --- a/src/DotNet/StrongNameKey.cs +++ b/src/DotNet/StrongNameKey.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using System.Runtime.Serialization; using System.Security.Cryptography; using dnlib.Threading; @@ -33,6 +34,15 @@ public InvalidKeyException(string message) public InvalidKeyException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected InvalidKeyException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index b2e6573fd..9122c9063 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.Serialization; using System.Text; namespace dnlib.DotNet { @@ -33,6 +34,15 @@ public TypeNameParserException(string message) public TypeNameParserException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected TypeNameParserException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// diff --git a/src/DotNet/Writer/ModuleWriterException.cs b/src/DotNet/Writer/ModuleWriterException.cs index 50975f8fc..2a6375900 100644 --- a/src/DotNet/Writer/ModuleWriterException.cs +++ b/src/DotNet/Writer/ModuleWriterException.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Runtime.Serialization; namespace dnlib.DotNet.Writer { /// @@ -30,5 +31,14 @@ public ModuleWriterException(string message) public ModuleWriterException(string message, Exception innerException) : base(message, innerException) { } + + /// + /// Constructor + /// + /// + /// + protected ModuleWriterException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } } diff --git a/src/IO/MemoryMappedFileStreamCreator.cs b/src/IO/MemoryMappedFileStreamCreator.cs index efb7d1eee..5b77b368d 100644 --- a/src/IO/MemoryMappedFileStreamCreator.cs +++ b/src/IO/MemoryMappedFileStreamCreator.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; +using System.Runtime.Serialization; using System.Threading; using Microsoft.Win32.SafeHandles; @@ -29,9 +30,16 @@ enum OSType : byte { [Serializable] sealed class MemoryMappedIONotSupportedException : IOException { + public MemoryMappedIONotSupportedException() { + } + public MemoryMappedIONotSupportedException(string s) : base(s) { } + + public MemoryMappedIONotSupportedException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } static class Windows { diff --git a/src/Threading/Lock.cs b/src/Threading/Lock.cs index 5bbebc177..5fb1f1422 100644 --- a/src/Threading/Lock.cs +++ b/src/Threading/Lock.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Runtime.Serialization; using System.Threading; namespace dnlib.Threading { @@ -13,6 +14,10 @@ public LockException() { public LockException(string msg) : base(msg) { } + + protected LockException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } } /// From c2185edf73fa347c84d760f4defb075288857a9e Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 8 Aug 2017 23:56:32 +0200 Subject: [PATCH 041/511] Created PDB method if needed --- src/DotNet/Pdb/PdbWriter.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/PdbWriter.cs index 7e480cf41..479e3a6e0 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/PdbWriter.cs @@ -237,7 +237,11 @@ void Write(MethodDef method) { seqPointsHelper.Write(this, info.Method.Body.Instructions); var pdbMethod = body.PdbMethod; + if (pdbMethod == null) + body.PdbMethod = pdbMethod = new PdbMethod(); var scope = pdbMethod.Scope; + if (scope == null) + pdbMethod.Scope = scope = new PdbScope(); if (scope.Namespaces.Count == 0 && scope.Variables.Count == 0 && scope.Constants.Count == 0) { if (scope.Scopes.Count == 0) { // We must open at least one sub scope (the sym writer creates the 'method' scope From 8546dcf0bd812b84cb7669e6b370fa02d0e2dab9 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 9 Aug 2017 22:49:51 +0200 Subject: [PATCH 042/511] Include BP method/instr in error message --- src/DotNet/Pdb/PdbWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/PdbWriter.cs index 479e3a6e0..e5344eb12 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/PdbWriter.cs @@ -343,7 +343,7 @@ int GetExternalInstructionOffset(ref CurrentMethod info, MethodDef method, Instr } if (instr == null) return offset; - Error("Instruction has been removed but it's referenced by PDB info"); + Error("Async method instruction has been removed but it's still being referenced by PDB info: BP Instruction: {0}, BP Method: {1} (0x{2:X8}), Current Method: {3} (0x{4:X8})", instr, method, method.MDToken.Raw, info.Method, info.Method.MDToken.Raw); return 0; } From 068f29a4242e7198f69f67c594b1e7189bee91d8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 19 Oct 2017 13:11:49 +0200 Subject: [PATCH 043/511] Ignore other symbol types --- src/DotNet/Pdb/Managed/DbiScope.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 40f97fdda..a556c0484 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -119,7 +119,6 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { case SymbolType.S_END: break; default: - Debug.Fail("Unknown symbol type: " + type); break; } From 64e2c815ac35a7242c4f819b805acde4cde0456d Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 28 Oct 2017 22:01:59 +0200 Subject: [PATCH 044/511] Add method that returns original TargetFrameworkAttribute values --- src/DotNet/AssemblyDef.cs | 160 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index c37ac9569..68c816f64 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -8,6 +8,7 @@ using dnlib.DotNet.MD; using dnlib.DotNet.Writer; using dnlib.Threading; +using System.Text.RegularExpressions; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -736,6 +737,22 @@ CustomAttribute CreateAssemblySignatureKeyAttribute() { return ca; } + /// + /// Gets the original System.Runtime.Versioning.TargetFrameworkAttribute custom attribute information if possible. + /// It reads this from the original metadata and doesn't use . + /// Returns false if the custom attribute isn't present or if it is invalid. + /// + /// Framework name + /// Version + /// Profile + /// + public virtual bool TryGetOriginalTargetFrameworkAttribute(out string framework, out Version version, out string profile) { + framework = null; + version = null; + profile = null; + return false; + } + /// void IListListener.OnLazyAdd(int index, ref ModuleDef module) { if (module == null) @@ -917,6 +934,149 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + public override bool TryGetOriginalTargetFrameworkAttribute(out string framework, out Version version, out string profile) { + if (!hasInitdTFA) + InitializeTargetFrameworkAttribute(); + framework = tfaFramework; + version = tfaVersion; + profile = tfaProfile; + return tfaReturnValue; + } + volatile bool hasInitdTFA; + string tfaFramework; + Version tfaVersion; + string tfaProfile; + bool tfaReturnValue; + + void InitializeTargetFrameworkAttribute() { + if (hasInitdTFA) + return; + + var list = readerModule.MetaData.GetCustomAttributeRidList(Table.Assembly, origRid); + var gpContext = new GenericParamContext(); + for (int i = 0; i < list.Count; i++) { + var caRid = list[i]; + var caRow = readerModule.TablesStream.ReadCustomAttributeRow(caRid); + if (caRow == null) + continue; + var caType = readerModule.ResolveCustomAttributeType(caRow.Type, gpContext); + UTF8String ns, name; + if (!TryGetName(caType, out ns, out name)) + continue; + if (ns != nameSystemRuntimeVersioning || name != nameTargetFrameworkAttribute) + continue; + var ca = CustomAttributeReader.Read(readerModule, caType, caRow.Value, gpContext); + if (ca == null || ca.ConstructorArguments.Count != 1) + continue; + var s = ca.ConstructorArguments[0].Value as UTF8String; + if ((object)s == null) + continue; + string tmpFramework, tmpProfile; + Version tmpVersion; + if (TryCreateTargetFrameworkInfo(s, out tmpFramework, out tmpVersion, out tmpProfile)) { + tfaFramework = tmpFramework; + tfaVersion = tmpVersion; + tfaProfile = tmpProfile; + tfaReturnValue = true; + break; + } + } + + hasInitdTFA = true; + } + static readonly UTF8String nameSystemRuntimeVersioning = new UTF8String("System.Runtime.Versioning"); + static readonly UTF8String nameTargetFrameworkAttribute = new UTF8String("TargetFrameworkAttribute"); + + static bool TryGetName(ICustomAttributeType caType, out UTF8String ns, out UTF8String name) { + var type = (caType as MemberRef)?.DeclaringType ?? (caType as MethodDef)?.DeclaringType; + var tr = type as TypeRef; + if (tr != null) { + ns = tr.Namespace; + name = tr.Name; + return true; + } + var td = type as TypeDef; + if (td != null) { + ns = td.Namespace; + name = td.Name; + return true; + } + ns = null; + name = null; + return false; + } + + static bool TryCreateTargetFrameworkInfo(string attrString, out string framework, out Version version, out string profile) { + framework = null; + version = null; + profile = null; + + // See corclr/src/mscorlib/src/System/Runtime/Versioning/BinaryCompatibility.cs + var values = attrString.Split(new char[] { ',' }); + if (values.Length < 2 || values.Length > 3) + return false; + var frameworkRes = values[0].Trim(); + if (frameworkRes.Length == 0) + return false; + + Version versionRes = null; + string profileRes = null; + for (int i = 1; i < values.Length; i++) { + var kvp = values[i].Split('='); + if (kvp.Length != 2) + return false; + + var key = kvp[0].Trim(); + var value = kvp[1].Trim(); + + if (key.Equals("Version", StringComparison.OrdinalIgnoreCase)) { + if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase)) + value = value.Substring(1); + if (!TryParse(value, out versionRes)) + return false; + versionRes = new Version(versionRes.Major, versionRes.Minor, versionRes.Build == -1 ? 0 : versionRes.Build, 0); + } + else if (key.Equals("Profile", StringComparison.OrdinalIgnoreCase)) { + if (!string.IsNullOrEmpty(value)) + profileRes = value; + } + } + if (versionRes == null) + return false; + + framework = frameworkRes; + version = versionRes; + profile = profileRes; + return true; + } + + static int ParseInt32(string s) => int.TryParse(s, out var res) ? res : 0; + static bool TryParse(string s, out Version version) { + Match m; + + m = Regex.Match(s, @"^(\d+)\.(\d+)$"); + if (m.Groups.Count == 3) { + version = new Version(ParseInt32(m.Groups[1].Value), ParseInt32(m.Groups[2].Value)); + return true; + } + + m = Regex.Match(s, @"^(\d+)\.(\d+)\.(\d+)$"); + if (m.Groups.Count == 4) { + version = new Version(ParseInt32(m.Groups[1].Value), ParseInt32(m.Groups[2].Value), ParseInt32(m.Groups[3].Value)); + return true; + } + + m = Regex.Match(s, @"^(\d+)\.(\d+)\.(\d+)\.(\d+)$"); + if (m.Groups.Count == 5) { + version = new Version(ParseInt32(m.Groups[1].Value), ParseInt32(m.Groups[2].Value), ParseInt32(m.Groups[3].Value), ParseInt32(m.Groups[4].Value)); + return true; + } + + version = null; + return false; + } + /// /// Constructor /// From 55bbaed2b7766e92099377447d6838a7fbda6189 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 28 Oct 2017 22:11:31 +0200 Subject: [PATCH 045/511] Remove C#7 code --- src/DotNet/AssemblyDef.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 68c816f64..23bc4ddb7 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -1051,7 +1051,11 @@ static bool TryCreateTargetFrameworkInfo(string attrString, out string framework return true; } - static int ParseInt32(string s) => int.TryParse(s, out var res) ? res : 0; + static int ParseInt32(string s) { + int res; + return int.TryParse(s, out res) ? res : 0; + } + static bool TryParse(string s, out Version version) { Match m; From a392ccbd7716457f0012270b85ee7887ca852e85 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 4 Nov 2017 18:09:24 +0100 Subject: [PATCH 046/511] Refactor PDB reader code --- src/DotNet/MD/CompressedMetaData.cs | 35 +++- src/DotNet/MD/ENCMetaData.cs | 26 ++- src/DotNet/MD/MetaData.cs | 16 +- src/DotNet/MD/MetaDataCreator.cs | 44 ++++- src/DotNet/MD/TablesStream.cs | 13 +- src/DotNet/ModuleCreationOptions.cs | 8 +- src/DotNet/ModuleDefMD.cs | 14 +- src/DotNet/Pdb/Dss/SymbolDocument.cs | 100 ---------- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 72 ++++++++ src/DotNet/Pdb/Dss/SymbolMethod.cs | 171 ------------------ src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 120 ++++++++++++ src/DotNet/Pdb/Dss/SymbolNamespace.cs | 47 ----- src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs | 25 +++ src/DotNet/Pdb/Dss/SymbolReader.cs | 126 ------------- src/DotNet/Pdb/Dss/SymbolReaderCreator.cs | 52 +++--- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 76 ++++++++ src/DotNet/Pdb/Dss/SymbolScope.cs | 133 -------------- src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 149 +++++++++++++++ src/DotNet/Pdb/Dss/SymbolVariable.cs | 89 --------- src/DotNet/Pdb/Dss/SymbolVariableImpl.cs | 44 +++++ src/DotNet/Pdb/Dss/SymbolWriterCreator.cs | 2 +- src/DotNet/Pdb/ISymbolMethod2.cs | 23 --- src/DotNet/Pdb/ISymbolScope2.cs | 19 -- src/DotNet/Pdb/Managed/DbiDocument.cs | 92 ++++------ src/DotNet/Pdb/Managed/DbiFunction.cs | 134 ++++++-------- src/DotNet/Pdb/Managed/DbiModule.cs | 17 +- src/DotNet/Pdb/Managed/DbiNamespace.cs | 29 +-- src/DotNet/Pdb/Managed/DbiScope.cs | 123 ++++++------- src/DotNet/Pdb/Managed/DbiSourceLine.cs | 12 -- src/DotNet/Pdb/Managed/DbiVariable.cs | 71 +++----- src/DotNet/Pdb/Managed/PdbException.cs | 4 +- src/DotNet/Pdb/Managed/PdbReader.cs | 96 ++++------ src/DotNet/Pdb/Managed/SymbolReaderCreator.cs | 36 ++-- src/DotNet/Pdb/ManagedSymbolReaderCreator.cs | 77 ++++++++ src/DotNet/Pdb/PdbDocument.cs | 7 +- src/DotNet/Pdb/PdbImplType.cs | 6 +- src/DotNet/Pdb/PdbState.cs | 94 ++++------ .../Pdb/Portable/SymbolReaderCreator.cs | 42 +++++ src/DotNet/Pdb/SymbolReaderCreator.cs | 105 +++++++---- src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs | 35 ++++ src/DotNet/Pdb/Symbols/SymbolDocument.cs | 40 ++++ src/DotNet/Pdb/Symbols/SymbolMethod.cs | 45 +++++ src/DotNet/Pdb/Symbols/SymbolNamespace.cs | 13 ++ src/DotNet/Pdb/Symbols/SymbolReader.cs | 38 ++++ src/DotNet/Pdb/Symbols/SymbolScope.cs | 53 ++++++ src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs | 38 ++++ src/DotNet/Pdb/Symbols/SymbolVariable.cs | 41 +++++ src/dnlib.csproj | 25 ++- 48 files changed, 1430 insertions(+), 1247 deletions(-) delete mode 100644 src/DotNet/Pdb/Dss/SymbolDocument.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolMethod.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolMethodImpl.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolNamespace.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolReader.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolReaderImpl.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolScope.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolScopeImpl.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolVariable.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolVariableImpl.cs delete mode 100644 src/DotNet/Pdb/ISymbolMethod2.cs delete mode 100644 src/DotNet/Pdb/ISymbolScope2.cs delete mode 100644 src/DotNet/Pdb/Managed/DbiSourceLine.cs create mode 100644 src/DotNet/Pdb/ManagedSymbolReaderCreator.cs create mode 100644 src/DotNet/Pdb/Portable/SymbolReaderCreator.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolDocument.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolMethod.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolNamespace.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolReader.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolScope.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs create mode 100644 src/DotNet/Pdb/Symbols/SymbolVariable.cs diff --git a/src/DotNet/MD/CompressedMetaData.cs b/src/DotNet/MD/CompressedMetaData.cs index 0be9d94e9..612cdc472 100644 --- a/src/DotNet/MD/CompressedMetaData.cs +++ b/src/DotNet/MD/CompressedMetaData.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using dnlib.IO; using dnlib.PE; @@ -22,6 +23,11 @@ public CompressedMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDa : base(peImage, cor20Header, mdHeader) { } + /// + internal CompressedMetaData(MetaDataHeader mdHeader) + : base(mdHeader) { + } + static CompressedMetaData() { var windir = Environment.GetEnvironmentVariable("WINDIR"); if (!string.IsNullOrEmpty(windir)) { @@ -46,21 +52,28 @@ static HotHeapVersion GetHotHeapVersion(string fileName, string version) { } /// - protected override void InitializeInternal() { - var hotHeapVersion = GetHotHeapVersion(peImage.FileName, mdHeader.VersionString); + protected override void InitializeInternal(IImageStream mdStream) { + var hotHeapVersion = peImage == null ? HotHeapVersion.CLR20 : GetHotHeapVersion(peImage.FileName, mdHeader.VersionString); + bool disposeOfMdStream = false; IImageStream imageStream = null, fullStream = null; DotNetStream dns = null; List hotStreams = null; HotStream hotStream = null; var newAllStreams = new List(allStreams); try { - var mdRva = cor20Header.MetaData.VirtualAddress; + if (peImage != null) { + Debug.Assert(mdStream == null); + Debug.Assert(cor20Header != null); + var mdOffset = peImage.ToFileOffset(cor20Header.MetaData.VirtualAddress); + mdStream = peImage.CreateStream(mdOffset, cor20Header.MetaData.Size); + disposeOfMdStream = true; + } + else + Debug.Assert(mdStream != null); for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--) { var sh = mdHeader.StreamHeaders[i]; - var rva = mdRva + sh.Offset; - var fileOffset = peImage.ToFileOffset(rva); - imageStream = peImage.CreateStream(fileOffset, sh.StreamSize); + imageStream = mdStream.Create((FileOffset)sh.Offset, sh.StreamSize); switch (sh.Name) { case "#Strings": if (stringsStream == null) { @@ -108,10 +121,12 @@ protected override void InitializeInternal() { break; case "#!": + if (peImage == null) + break; if (hotStreams == null) hotStreams = new List(); fullStream = peImage.CreateFullStream(); - hotStream = HotStream.Create(hotHeapVersion, imageStream, sh, fullStream, fileOffset); + hotStream = HotStream.Create(hotHeapVersion, imageStream, sh, fullStream, mdStream.FileOffset + sh.Offset); fullStream = null; hotStreams.Add(hotStream); newAllStreams.Add(hotStream); @@ -126,6 +141,8 @@ protected override void InitializeInternal() { } } finally { + if (disposeOfMdStream) + mdStream.Dispose(); if (imageStream != null) imageStream.Dispose(); if (fullStream != null) @@ -146,10 +163,12 @@ protected override void InitializeInternal() { InitializeHotStreams(hotStreams); } - tablesStream.Initialize(peImage); + tablesStream.Initialize(); } int GetPointerSize() { + if (peImage == null) + return 4; return peImage.ImageNTHeaders.OptionalHeader.Magic == 0x10B ? 4 : 8; } diff --git a/src/DotNet/MD/ENCMetaData.cs b/src/DotNet/MD/ENCMetaData.cs index 465e5501f..e0322c9cb 100644 --- a/src/DotNet/MD/ENCMetaData.cs +++ b/src/DotNet/MD/ENCMetaData.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using dnlib.IO; using dnlib.PE; using dnlib.Threading; @@ -30,14 +31,27 @@ public ENCMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeade } /// - protected override void InitializeInternal() { + internal ENCMetaData(MetaDataHeader mdHeader) + : base(mdHeader) { + } + + /// + protected override void InitializeInternal(IImageStream mdStream) { + bool disposeOfMdStream = false; IImageStream imageStream = null; DotNetStream dns = null; try { - var mdRva = cor20Header.MetaData.VirtualAddress; + if (peImage != null) { + Debug.Assert(mdStream == null); + Debug.Assert(cor20Header != null); + var mdOffset = peImage.ToFileOffset(cor20Header.MetaData.VirtualAddress); + mdStream = peImage.CreateStream(mdOffset, cor20Header.MetaData.Size); + disposeOfMdStream = true; + } + else + Debug.Assert(mdStream != null); foreach (var sh in mdHeader.StreamHeaders) { - var rva = mdRva + sh.Offset; - imageStream = peImage.CreateStream(rva, sh.StreamSize); + imageStream = mdStream.Create((FileOffset)sh.Offset, sh.StreamSize); switch (sh.Name.ToUpperInvariant()) { case "#STRINGS": if (stringsStream == null) { @@ -92,6 +106,8 @@ protected override void InitializeInternal() { } } finally { + if (disposeOfMdStream) + mdStream.Dispose(); if (imageStream != null) imageStream.Dispose(); if (dns != null) @@ -100,7 +116,7 @@ protected override void InitializeInternal() { if (tablesStream == null) throw new BadImageFormatException("Missing MD stream"); - tablesStream.Initialize(peImage); + tablesStream.Initialize(); // The pointer tables are used iff row count != 0 hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty; diff --git a/src/DotNet/MD/MetaData.cs b/src/DotNet/MD/MetaData.cs index fd5b03eb8..58ceedd8c 100644 --- a/src/DotNet/MD/MetaData.cs +++ b/src/DotNet/MD/MetaData.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; +using dnlib.IO; using dnlib.PE; using dnlib.Threading; @@ -264,11 +265,18 @@ protected MetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeade } } + internal MetaData(MetaDataHeader mdHeader) { + this.allStreams = ThreadSafeListCreator.Create(); + this.peImage = null; + this.cor20Header = null; + this.mdHeader = mdHeader; + } + /// /// Initializes the metadata, tables, streams /// - public void Initialize() { - InitializeInternal(); + public void Initialize(IImageStream mdStream) { + InitializeInternal(mdStream); if (tablesStream == null) throw new BadImageFormatException("Missing MD stream"); @@ -290,9 +298,9 @@ protected void InitializeNonExistentHeaps() { } /// - /// Called by + /// Called by /// - protected abstract void InitializeInternal(); + protected abstract void InitializeInternal(IImageStream mdStream); /// public virtual RidList GetTypeDefRidList() { diff --git a/src/DotNet/MD/MetaDataCreator.cs b/src/DotNet/MD/MetaDataCreator.cs index 735379423..31bba7905 100644 --- a/src/DotNet/MD/MetaDataCreator.cs +++ b/src/DotNet/MD/MetaDataCreator.cs @@ -130,7 +130,7 @@ public static IMetaData CreateMetaData(IPEImage peImage, bool verify) { /// The PE image /// true if we should verify that it's a .NET PE file /// A new instance - internal static MetaData Create(IPEImage peImage, bool verify) { + static MetaData Create(IPEImage peImage, bool verify) { IImageStream cor20HeaderStream = null, mdHeaderStream = null; MetaData md = null; try { @@ -166,7 +166,7 @@ internal static MetaData Create(IPEImage peImage, bool verify) { default: throw new BadImageFormatException("No #~ or #- stream found"); } - md.Initialize(); + md.Initialize(null); return md; } @@ -183,6 +183,46 @@ internal static MetaData Create(IPEImage peImage, bool verify) { } } + /// + /// Create a instance + /// + /// Metadata stream + /// true if we should verify that it's a .NET PE file + /// A new instance + internal static MetaData Create(IImageStream mdStream, bool verify) { + MetaData md = null; + try { + var mdHeader = new MetaDataHeader(mdStream, verify); + if (verify) { + foreach (var sh in mdHeader.StreamHeaders) { + if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > mdStream.Length) + throw new BadImageFormatException("Invalid stream header"); + } + } + + switch (GetMetaDataType(mdHeader.StreamHeaders)) { + case MetaDataType.Compressed: + md = new CompressedMetaData(mdHeader); + break; + + case MetaDataType.ENC: + md = new ENCMetaData(mdHeader); + break; + + default: + throw new BadImageFormatException("No #~ or #- stream found"); + } + md.Initialize(mdStream); + + return md; + } + catch { + if (md != null) + md.Dispose(); + throw; + } + } + static MetaDataType GetMetaDataType(IList streamHeaders) { MetaDataType? mdType = null; foreach (var sh in streamHeaders) { diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 864d2faa3..252e2a12f 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -219,8 +219,7 @@ public TablesStream(IImageStream imageStream, StreamHeader streamHeader) /// /// Initializes MD tables /// - /// The PEImage - public void Initialize(IPEImage peImage) { + public void Initialize() { if (initialized) throw new Exception("Initialize() has already been called"); initialized = true; @@ -254,14 +253,14 @@ public void Initialize(IPEImage peImage) { dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes); - var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position; + var currentPos = (FileOffset)imageStream.Position; foreach (var mdTable in mdTables) { var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows; - mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen); - var newRva = currentRva + (uint)dataLen; - if (newRva < currentRva) + mdTable.ImageStream = imageStream.Create(currentPos, dataLen); + var newPos = currentPos + (uint)dataLen; + if (newPos < currentPos) throw new BadImageFormatException("Too big MD table"); - currentRva = newRva; + currentPos = newPos; } InitializeTables(); diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 8172d1a80..84567d693 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -1,8 +1,8 @@ // dnlib: See LICENSE.txt for more info -using System.Diagnostics.SymbolStore; using dnlib.IO; using dnlib.DotNet.Pdb; +using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet { /// @@ -65,10 +65,10 @@ public ModuleCreationOptions(ModuleContext context) { } /// - /// Creates a + /// Creates a /// /// Module - /// A instance for (and now owned by) + /// A instance for (and now owned by) /// or null. - public delegate ISymbolReader CreateSymbolReaderDelegate(ModuleDefMD module); + public delegate SymbolReader CreateSymbolReaderDelegate(ModuleDefMD module); } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 560b706b2..d5b58b516 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.SymbolStore; using System.IO; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; @@ -17,6 +16,7 @@ using dnlib.W32Resources; using DNW = dnlib.DotNet.Writer; +using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet { /// @@ -423,7 +423,7 @@ void InitializePdb(ModuleCreationOptions options) { LoadPdb(CreateSymbolReader(options)); } - ISymbolReader CreateSymbolReader(ModuleCreationOptions options) { + SymbolReader CreateSymbolReader(ModuleCreationOptions options) { if (options.CreateSymbolReader != null) { var symReader = options.CreateSymbolReader(this); if (symReader != null) @@ -447,8 +447,12 @@ ISymbolReader CreateSymbolReader(ModuleCreationOptions options) { return SymbolReaderCreator.Create(options.PdbImplementation, metaData, pdbStream); } - if (options.TryToLoadPdbFromDisk && !string.IsNullOrEmpty(location)) - return SymbolReaderCreator.Create(options.PdbImplementation, location); + if (options.TryToLoadPdbFromDisk) { + if (!string.IsNullOrEmpty(location)) + return SymbolReaderCreator.CreateFromAssemblyFile(options.PdbImplementation, metaData, location); + else + return SymbolReaderCreator.Create(options.PdbImplementation, metaData); + } return null; } @@ -457,7 +461,7 @@ ISymbolReader CreateSymbolReader(ModuleCreationOptions options) { /// Loads symbols using /// /// PDB symbol reader - public void LoadPdb(ISymbolReader symbolReader) { + public void LoadPdb(SymbolReader symbolReader) { if (symbolReader == null) return; if (pdbState != null) diff --git a/src/DotNet/Pdb/Dss/SymbolDocument.cs b/src/DotNet/Pdb/Dss/SymbolDocument.cs deleted file mode 100644 index 09a257cbc..000000000 --- a/src/DotNet/Pdb/Dss/SymbolDocument.cs +++ /dev/null @@ -1,100 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolDocument : ISymbolDocument { - readonly ISymUnmanagedDocument document; - - public ISymUnmanagedDocument SymUnmanagedDocument { - get { return document; } - } - - public SymbolDocument(ISymUnmanagedDocument document) { - this.document = document; - } - - public Guid CheckSumAlgorithmId { - get { - Guid guid; - document.GetCheckSumAlgorithmId(out guid); - return guid; - } - } - - public Guid DocumentType { - get { - Guid guid; - document.GetDocumentType(out guid); - return guid; - } - } - - public bool HasEmbeddedSource { - get { - bool result; - document.HasEmbeddedSource(out result); - return result; - } - } - - public Guid Language { - get { - Guid guid; - document.GetLanguage(out guid); - return guid; - } - } - - public Guid LanguageVendor { - get { - Guid guid; - document.GetLanguageVendor(out guid); - return guid; - } - } - - public int SourceLength { - get { - uint result; - document.GetSourceLength(out result); - return (int)result; - } - } - - public string URL { - get { - uint count; - document.GetURL(0, out count, null); - var chars = new char[count]; - document.GetURL((uint)chars.Length, out count, chars); - if (chars.Length == 0) - return string.Empty; - return new string(chars, 0, chars.Length - 1); - } - } - - public int FindClosestLine(int line) { - uint result; - document.FindClosestLine((uint)line, out result); - return (int)result; - } - - public byte[] GetCheckSum() { - uint bufSize; - document.GetCheckSum(0, out bufSize, null); - var buffer = new byte[bufSize]; - document.GetCheckSum((uint)buffer.Length, out bufSize, buffer); - return buffer; - } - - public byte[] GetSourceRange(int startLine, int startColumn, int endLine, int endColumn) { - uint bufSize; - document.GetSourceRange((uint)startLine, (uint)startColumn, (uint)endLine, (uint)endColumn, 0, out bufSize, null); - var buffer = new byte[bufSize]; - document.GetSourceRange((uint)startLine, (uint)startColumn, (uint)endLine, (uint)endColumn, (uint)buffer.Length, out bufSize, buffer); - return buffer; - } - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs new file mode 100644 index 000000000..7d0040ffc --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -0,0 +1,72 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Dss { + sealed class SymbolDocumentImpl : SymbolDocument { + readonly ISymUnmanagedDocument document; + + public ISymUnmanagedDocument SymUnmanagedDocument { + get { return document; } + } + + public SymbolDocumentImpl(ISymUnmanagedDocument document) { + this.document = document; + } + + public override Guid CheckSumAlgorithmId { + get { + Guid guid; + document.GetCheckSumAlgorithmId(out guid); + return guid; + } + } + + public override Guid DocumentType { + get { + Guid guid; + document.GetDocumentType(out guid); + return guid; + } + } + + public override Guid Language { + get { + Guid guid; + document.GetLanguage(out guid); + return guid; + } + } + + public override Guid LanguageVendor { + get { + Guid guid; + document.GetLanguageVendor(out guid); + return guid; + } + } + + public override string URL { + get { + uint count; + document.GetURL(0, out count, null); + var chars = new char[count]; + document.GetURL((uint)chars.Length, out count, chars); + if (chars.Length == 0) + return string.Empty; + return new string(chars, 0, chars.Length - 1); + } + } + + public override byte[] CheckSum { + get { + uint bufSize; + document.GetCheckSum(0, out bufSize, null); + var buffer = new byte[bufSize]; + document.GetCheckSum((uint)buffer.Length, out bufSize, buffer); + return buffer; + } + } + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolMethod.cs b/src/DotNet/Pdb/Dss/SymbolMethod.cs deleted file mode 100644 index 0c752ce3b..000000000 --- a/src/DotNet/Pdb/Dss/SymbolMethod.cs +++ /dev/null @@ -1,171 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolMethod : ISymbolMethod2 { - readonly ISymUnmanagedMethod method; - readonly ISymUnmanagedAsyncMethod asyncMethod; - - public SymbolMethod(ISymUnmanagedMethod method) { - this.method = method; - this.asyncMethod = method as ISymUnmanagedAsyncMethod; - } - - public ISymbolScope RootScope { - get { - ISymUnmanagedScope scope; - method.GetRootScope(out scope); - return scope == null ? null : new SymbolScope(scope); - } - } - - public int SequencePointCount { - get { - uint result; - method.GetSequencePointCount(out result); - return (int)result; - } - } - - public SymbolToken Token { - get { - uint result; - method.GetToken(out result); - return new SymbolToken((int)result); - } - } - - public ISymbolNamespace GetNamespace() { - ISymUnmanagedNamespace ns; - method.GetNamespace(out ns); - return ns == null ? null : new SymbolNamespace(ns); - } - - public int GetOffset(ISymbolDocument document, int line, int column) { - var symDoc = document as SymbolDocument; - if (symDoc == null) - throw new ArgumentException("document is not a non-null SymbolDocument instance"); - uint result; - method.GetOffset(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, out result); - return (int)result; - } - - public ISymbolVariable[] GetParameters() { - uint numVars; - method.GetParameters(0, out numVars, null); - var unVars = new ISymUnmanagedVariable[numVars]; - method.GetParameters((uint)unVars.Length, out numVars, unVars); - var vars = new ISymbolVariable[numVars]; - for (uint i = 0; i < numVars; i++) - vars[i] = new SymbolVariable(unVars[i]); - return vars; - } - - public int[] GetRanges(ISymbolDocument document, int line, int column) { - var symDoc = document as SymbolDocument; - if (symDoc == null) - throw new ArgumentException("document is not a non-null SymbolDocument instance"); - uint arySize; - method.GetRanges(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, 0, out arySize, null); - var ary = new int[arySize]; - method.GetRanges(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, (uint)ary.Length, out arySize, ary); - return ary; - } - - public ISymbolScope GetScope(int offset) { - ISymUnmanagedScope scope; - method.GetScopeFromOffset((uint)offset, out scope); - return scope == null ? null : new SymbolScope(scope); - } - - public void GetSequencePoints(int[] offsets, ISymbolDocument[] documents, int[] lines, int[] columns, int[] endLines, int[] endColumns) { - // Any array can be null, and the documentation says we must verify the sizes. - - int arySize = -1; - if (offsets != null) arySize = offsets.Length; - else if (documents != null) arySize = documents.Length; - else if (lines != null) arySize = lines.Length; - else if (columns != null) arySize = columns.Length; - else if (endLines != null) arySize = endLines.Length; - else if (endColumns != null)arySize = endColumns.Length; - - if (offsets != null && offsets.Length != arySize) throw new ArgumentException("Invalid array length: offsets"); - if (documents != null && documents.Length != arySize) throw new ArgumentException("Invalid array length: documents"); - if (lines != null && lines.Length != arySize) throw new ArgumentException("Invalid array length: lines"); - if (columns != null && columns.Length != arySize) throw new ArgumentException("Invalid array length: columns"); - if (endLines != null && endLines.Length != arySize) throw new ArgumentException("Invalid array length: endLines"); - if (endColumns != null && endColumns.Length != arySize) throw new ArgumentException("Invalid array length: endColumns"); - - if (arySize <= 0) - return; - - var unDocs = documents == null ? null : new ISymUnmanagedDocument[documents.Length]; - uint size; - method.GetSequencePoints((uint)arySize, out size, offsets, unDocs, lines, columns, endLines, endColumns); - - if (unDocs != null) { - for (int i = 0; i < unDocs.Length; i++) - documents[i] = unDocs[i] == null ? null : new SymbolDocument(unDocs[i]); - } - } - - public bool GetSourceStartEnd(ISymbolDocument[] docs, int[] lines, int[] columns) { - if (docs != null && docs.Length < 2) throw new ArgumentException("Invalid array: length < 2: docs"); - if (lines != null && lines.Length < 2) throw new ArgumentException("Invalid array: length < 2: lines"); - if (columns != null && columns.Length < 2) throw new ArgumentException("Invalid array: length < 2: columns"); - - var unDocs = docs == null ? null : new ISymUnmanagedDocument[docs.Length]; - bool result; - method.GetSourceStartEnd(unDocs, lines, columns, out result); - - if (unDocs != null) { - for (int i = 0; i < unDocs.Length; i++) - docs[i] = unDocs[i] == null ? null : new SymbolDocument(unDocs[i]); - } - - return result; - } - - public bool IsAsyncMethod { - get { return asyncMethod != null && asyncMethod.IsAsyncMethod(); } - } - - public uint KickoffMethod { - get { - Debug.Assert(IsAsyncMethod); - if (asyncMethod == null) - throw new InvalidOperationException(); - return asyncMethod.GetKickoffMethod(); - } - } - - public uint? CatchHandlerILOffset { - get { - Debug.Assert(IsAsyncMethod); - if (asyncMethod == null) - throw new InvalidOperationException(); - if (!asyncMethod.HasCatchHandlerILOffset()) - return null; - return asyncMethod.GetCatchHandlerILOffset(); - } - } - - public RawAsyncStepInfo[] GetAsyncStepInfos() { - Debug.Assert(IsAsyncMethod); - if (asyncMethod == null) - throw new InvalidOperationException(); - var stepInfoCount = asyncMethod.GetAsyncStepInfoCount(); - var yieldOffsets = new uint[stepInfoCount]; - var breakpointOffsets = new uint[stepInfoCount]; - var breakpointMethods = new uint[stepInfoCount]; - asyncMethod.GetAsyncStepInfo(stepInfoCount, out stepInfoCount, yieldOffsets, breakpointOffsets, breakpointMethods); - var res = new RawAsyncStepInfo[stepInfoCount]; - for (int i = 0; i < res.Length; i++) - res[i] = new RawAsyncStepInfo(yieldOffsets[i], breakpointOffsets[i], breakpointMethods[i]); - return res; - } - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs new file mode 100644 index 000000000..4beec1f4b --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -0,0 +1,120 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Diagnostics.SymbolStore; +using System.Threading; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Dss { + sealed class SymbolMethodImpl : SymbolMethod { + readonly ISymUnmanagedMethod method; + readonly ISymUnmanagedAsyncMethod asyncMethod; + + public SymbolMethodImpl(ISymUnmanagedMethod method) { + this.method = method; + this.asyncMethod = method as ISymUnmanagedAsyncMethod; + } + + public override int Token { + get { + uint result; + method.GetToken(out result); + return (int)result; + } + } + + public override SymbolScope RootScope { + get { + if (rootScope == null) { + ISymUnmanagedScope scope; + method.GetRootScope(out scope); + Interlocked.CompareExchange(ref rootScope, scope == null ? null : new SymbolScopeImpl(scope, this, null), null); + } + return rootScope; + } + } + volatile SymbolScope rootScope; + + public override ReadOnlyCollection SequencePoints { + get { + if (sequencePoints == null) { + uint seqPointCount; + method.GetSequencePointCount(out seqPointCount); + var seqPoints = new SymbolSequencePoint[seqPointCount]; + + int[] offsets = new int[seqPoints.Length]; + ISymbolDocument[] documents = new ISymbolDocument[seqPoints.Length]; + int[] lines = new int[seqPoints.Length]; + int[] columns = new int[seqPoints.Length]; + int[] endLines = new int[seqPoints.Length]; + int[] endColumns = new int[seqPoints.Length]; + var unDocs = new ISymUnmanagedDocument[seqPoints.Length]; + if (seqPoints.Length != 0) { + uint size; + method.GetSequencePoints((uint)seqPoints.Length, out size, offsets, unDocs, lines, columns, endLines, endColumns); + } + for (int i = 0; i < seqPoints.Length; i++) { + seqPoints[i] = new SymbolSequencePoint { + Offset = offsets[i], + Document = new SymbolDocumentImpl(unDocs[i]), + Line = lines[i], + Column = columns[i], + EndLine = endLines[i], + EndColumn = endColumns[i], + }; + } + Interlocked.CompareExchange(ref sequencePoints, new ReadOnlyCollection(seqPoints), null); + } + return sequencePoints; + } + } + volatile ReadOnlyCollection sequencePoints; + + public override bool IsAsyncMethod { + get { return asyncMethod != null && asyncMethod.IsAsyncMethod(); } + } + + public override int KickoffMethod { + get { + Debug.Assert(IsAsyncMethod); + if (asyncMethod == null) + throw new InvalidOperationException(); + return (int)asyncMethod.GetKickoffMethod(); + } + } + + public override uint? CatchHandlerILOffset { + get { + Debug.Assert(IsAsyncMethod); + if (asyncMethod == null) + throw new InvalidOperationException(); + if (!asyncMethod.HasCatchHandlerILOffset()) + return null; + return asyncMethod.GetCatchHandlerILOffset(); + } + } + + public override ReadOnlyCollection AsyncStepInfos { + get { + if (asyncStepInfos == null) { + Debug.Assert(IsAsyncMethod); + if (asyncMethod == null) + throw new InvalidOperationException(); + var stepInfoCount = asyncMethod.GetAsyncStepInfoCount(); + var yieldOffsets = new uint[stepInfoCount]; + var breakpointOffsets = new uint[stepInfoCount]; + var breakpointMethods = new uint[stepInfoCount]; + asyncMethod.GetAsyncStepInfo(stepInfoCount, out stepInfoCount, yieldOffsets, breakpointOffsets, breakpointMethods); + var res = new SymbolAsyncStepInfo[stepInfoCount]; + for (int i = 0; i < res.Length; i++) + res[i] = new SymbolAsyncStepInfo(yieldOffsets[i], breakpointOffsets[i], breakpointMethods[i]); + Interlocked.CompareExchange(ref asyncStepInfos, new ReadOnlyCollection(res), null); + } + return asyncStepInfos; + } + } + volatile ReadOnlyCollection asyncStepInfos; + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolNamespace.cs b/src/DotNet/Pdb/Dss/SymbolNamespace.cs deleted file mode 100644 index 15c24daed..000000000 --- a/src/DotNet/Pdb/Dss/SymbolNamespace.cs +++ /dev/null @@ -1,47 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolNamespace : ISymbolNamespace { - readonly ISymUnmanagedNamespace ns; - - public SymbolNamespace(ISymUnmanagedNamespace @namespace) { - this.ns = @namespace; - } - - public string Name { - get { - uint count; - ns.GetName(0, out count, null); - var chars = new char[count]; - ns.GetName((uint)chars.Length, out count, chars); - if (chars.Length == 0) - return string.Empty; - return new string(chars, 0, chars.Length - 1); - } - } - - public ISymbolNamespace[] GetNamespaces() { - uint numNss; - ns.GetNamespaces(0, out numNss, null); - var unNss = new ISymUnmanagedNamespace[numNss]; - ns.GetNamespaces((uint)unNss.Length, out numNss, unNss); - var nss = new ISymbolNamespace[numNss]; - for (uint i = 0; i < numNss; i++) - nss[i] = new SymbolNamespace(unNss[i]); - return nss; - } - - public ISymbolVariable[] GetVariables() { - uint numVars; - ns.GetVariables(0, out numVars, null); - var unVars = new ISymUnmanagedVariable[numVars]; - ns.GetVariables((uint)unVars.Length, out numVars, unVars); - var vars = new ISymbolVariable[numVars]; - for (uint i = 0; i < numVars; i++) - vars[i] = new SymbolVariable(unVars[i]); - return vars; - } - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs b/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs new file mode 100644 index 000000000..e6c5cd4de --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs @@ -0,0 +1,25 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Dss { + sealed class SymbolNamespaceImpl : SymbolNamespace { + readonly ISymUnmanagedNamespace ns; + + public SymbolNamespaceImpl(ISymUnmanagedNamespace @namespace) { + this.ns = @namespace; + } + + public override string Name { + get { + uint count; + ns.GetName(0, out count, null); + var chars = new char[count]; + ns.GetName((uint)chars.Length, out count, chars); + if (chars.Length == 0) + return string.Empty; + return new string(chars, 0, chars.Length - 1); + } + } + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolReader.cs b/src/DotNet/Pdb/Dss/SymbolReader.cs deleted file mode 100644 index 7e546f76f..000000000 --- a/src/DotNet/Pdb/Dss/SymbolReader.cs +++ /dev/null @@ -1,126 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics.SymbolStore; -using System.Runtime.InteropServices; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolReader : ISymbolReader { - readonly ISymUnmanagedReader reader; - - const int E_FAIL = unchecked((int)0x80004005); - - /// - /// Constructor - /// - /// An unmanaged symbol reader - public SymbolReader(ISymUnmanagedReader reader) { - if (reader == null) - throw new ArgumentNullException("reader"); - this.reader = reader; - } - - public SymbolToken UserEntryPoint { - get { - uint token; - int hr = reader.GetUserEntryPoint(out token); - if (hr == E_FAIL) - token = 0; - else - Marshal.ThrowExceptionForHR(hr); - return new SymbolToken((int)token); - } - } - - public ISymbolDocument GetDocument(string url, Guid language, Guid languageVendor, Guid documentType) { - ISymUnmanagedDocument document; - reader.GetDocument(url, language, languageVendor, documentType, out document); - return document == null ? null : new SymbolDocument(document); - } - - public ISymbolDocument[] GetDocuments() { - uint numDocs; - reader.GetDocuments(0, out numDocs, null); - var unDocs = new ISymUnmanagedDocument[numDocs]; - reader.GetDocuments((uint)unDocs.Length, out numDocs, unDocs); - var docs = new ISymbolDocument[numDocs]; - for (uint i = 0; i < numDocs; i++) - docs[i] = new SymbolDocument(unDocs[i]); - return docs; - } - - public ISymbolVariable[] GetGlobalVariables() { - uint numVars; - reader.GetGlobalVariables(0, out numVars, null); - var unVars = new ISymUnmanagedVariable[numVars]; - reader.GetGlobalVariables((uint)unVars.Length, out numVars, unVars); - var vars = new ISymbolVariable[numVars]; - for (uint i = 0; i < numVars; i++) - vars[i] = new SymbolVariable(unVars[i]); - return vars; - } - - public ISymbolMethod GetMethod(SymbolToken method) { - ISymUnmanagedMethod unMethod; - int hr = reader.GetMethod((uint)method.GetToken(), out unMethod); - if (hr == E_FAIL) - return null; - Marshal.ThrowExceptionForHR(hr); - return unMethod == null ? null : new SymbolMethod(unMethod); - } - - public ISymbolMethod GetMethod(SymbolToken method, int version) { - ISymUnmanagedMethod unMethod; - int hr = reader.GetMethodByVersion((uint)method.GetToken(), version, out unMethod); - if (hr == E_FAIL) - return null; - Marshal.ThrowExceptionForHR(hr); - return unMethod == null ? null : new SymbolMethod(unMethod); - } - - public ISymbolMethod GetMethodFromDocumentPosition(ISymbolDocument document, int line, int column) { - var symDoc = document as SymbolDocument; - if (symDoc == null) - throw new ArgumentException("document is not a non-null SymbolDocument instance"); - ISymUnmanagedMethod unMethod; - int hr = reader.GetMethodFromDocumentPosition(symDoc.SymUnmanagedDocument, (uint)line, (uint)column, out unMethod); - if (hr == E_FAIL) - return null; - Marshal.ThrowExceptionForHR(hr); - return unMethod == null ? null : new SymbolMethod(unMethod); - } - - public ISymbolNamespace[] GetNamespaces() { - uint numNss; - reader.GetNamespaces(0, out numNss, null); - var unNss = new ISymUnmanagedNamespace[numNss]; - reader.GetNamespaces((uint)unNss.Length, out numNss, unNss); - var nss = new ISymbolNamespace[numNss]; - for (uint i = 0; i < numNss; i++) - nss[i] = new SymbolNamespace(unNss[i]); - return nss; - } - - public byte[] GetSymAttribute(SymbolToken parent, string name) { - uint bufSize; - reader.GetSymAttribute((uint)parent.GetToken(), name, 0, out bufSize, null); - if (bufSize == 0) - return emptyBytes; - var buffer = new byte[bufSize]; - reader.GetSymAttribute((uint)parent.GetToken(), name, (uint)buffer.Length, out bufSize, buffer); - return buffer; - } - static readonly byte[] emptyBytes = new byte[0]; - - public ISymbolVariable[] GetVariables(SymbolToken parent) { - uint numVars; - reader.GetVariables((uint)parent.GetToken(), 0, out numVars, null); - var unVars = new ISymUnmanagedVariable[numVars]; - reader.GetVariables((uint)parent.GetToken(), (uint)unVars.Length, out numVars, unVars); - var vars = new ISymbolVariable[numVars]; - for (uint i = 0; i < numVars; i++) - vars[i] = new SymbolVariable(unVars[i]); - return vars; - } - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs index e71ab9eb5..9904b4f9a 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs @@ -2,30 +2,30 @@ using System; using System.IO; -using System.Diagnostics.SymbolStore; using System.Runtime.InteropServices; using System.Security; using dnlib.DotNet.MD; using dnlib.IO; using dnlib.PE; +using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Dss { /// - /// Creates a instance + /// Creates a instance /// - public static class SymbolReaderCreator { + static class SymbolReaderCreator { [DllImport("ole32")] static extern int CoCreateInstance([In] ref Guid rclsid, IntPtr pUnkOuter, [In] uint dwClsContext, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppv); static readonly Guid CLSID_CorSymBinder_SxS = new Guid(0x0A29FF9E, 0x7F9C, 0x4437, 0x8B, 0x11, 0xF4, 0x24, 0x49, 0x1E, 0x39, 0x31); /// - /// Creates a new instance + /// Creates a new instance /// /// Path to assembly - /// A new instance or null if there's no PDB + /// A new instance or null if there's no PDB /// file on disk or if any of the COM methods fail. - public static ISymbolReader Create(string assemblyFileName) { + public static SymbolReader Create(string assemblyFileName) { try { object mdDispObj; Guid CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); @@ -46,7 +46,7 @@ public static ISymbolReader Create(string assemblyFileName) { Marshal.FinalReleaseComObject(mdImportObj); Marshal.FinalReleaseComObject(binder); if (hr >= 0) - return new SymbolReader(symReader); + return new SymbolReaderImpl(symReader); } catch (IOException) { } @@ -77,13 +77,13 @@ static IImageStream OpenImageStream(string fileName) { } /// - /// Creates a new instance + /// Creates a new instance /// /// .NET metadata /// Path to PDB file - /// A new instance or null if there's no PDB + /// A new instance or null if there's no PDB /// file on disk or if any of the COM methods fail. - public static ISymbolReader Create(IMetaData metaData, string pdbFileName) { + public static SymbolReader Create(IMetaData metaData, string pdbFileName) { var mdStream = CreateMetaDataStream(metaData); try { return Create(mdStream, OpenImageStream(pdbFileName)); @@ -96,13 +96,13 @@ public static ISymbolReader Create(IMetaData metaData, string pdbFileName) { } /// - /// Creates a new instance + /// Creates a new instance /// /// .NET metadata /// PDB file data - /// A new instance or null if any of the COM + /// A new instance or null if any of the COM /// methods fail. - public static ISymbolReader Create(IMetaData metaData, byte[] pdbData) { + public static SymbolReader Create(IMetaData metaData, byte[] pdbData) { if (pdbData == null) return null; var mdStream = CreateMetaDataStream(metaData); @@ -117,13 +117,13 @@ public static ISymbolReader Create(IMetaData metaData, byte[] pdbData) { } /// - /// Creates a new instance + /// Creates a new instance /// /// .NET metadata /// PDB file stream which is now owned by this method - /// A new instance or null if any of the COM + /// A new instance or null if any of the COM /// methods fail. - public static ISymbolReader Create(IMetaData metaData, IImageStream pdbStream) { + public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { try { return Create(CreateMetaDataStream(metaData), pdbStream); } @@ -135,13 +135,13 @@ public static ISymbolReader Create(IMetaData metaData, IImageStream pdbStream) { } /// - /// Creates a new instance + /// Creates a new instance /// /// .NET metadata stream which is now owned by this method /// Path to PDB file - /// A new instance or null if there's no PDB + /// A new instance or null if there's no PDB /// file on disk or if any of the COM methods fail. - public static ISymbolReader Create(IImageStream mdStream, string pdbFileName) { + public static SymbolReader Create(IImageStream mdStream, string pdbFileName) { try { return Create(mdStream, OpenImageStream(pdbFileName)); } @@ -153,13 +153,13 @@ public static ISymbolReader Create(IImageStream mdStream, string pdbFileName) { } /// - /// Creates a new instance + /// Creates a new instance /// /// .NET metadata stream which is now owned by this method /// PDB file data - /// A new instance or null if any of the COM + /// A new instance or null if any of the COM /// methods fail. - public static ISymbolReader Create(IImageStream mdStream, byte[] pdbData) { + public static SymbolReader Create(IImageStream mdStream, byte[] pdbData) { if (pdbData == null) { if (mdStream != null) mdStream.Dispose(); @@ -176,13 +176,13 @@ public static ISymbolReader Create(IImageStream mdStream, byte[] pdbData) { } /// - /// Creates a new instance + /// Creates a new instance /// /// .NET metadata stream which is now owned by this method /// PDB file stream which is now owned by this method - /// A new instance or null if any of the COM + /// A new instance or null if any of the COM /// methods fail. - public static ISymbolReader Create(IImageStream mdStream, IImageStream pdbStream) { + public static SymbolReader Create(IImageStream mdStream, IImageStream pdbStream) { ImageStreamIStream stream = null; PinnedMetaData pinnedMd = null; bool error = true; @@ -212,7 +212,7 @@ public static ISymbolReader Create(IImageStream mdStream, IImageStream pdbStream Marshal.FinalReleaseComObject(binder); if (hr >= 0) { error = false; - return new SymbolReader(symReader); + return new SymbolReaderImpl(symReader); } } catch (IOException) { diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs new file mode 100644 index 000000000..be7efd5b3 --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -0,0 +1,76 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.InteropServices; +using System.Threading; +using dnlib.DotNet.Emit; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Dss { + sealed class SymbolReaderImpl : SymbolReader { + readonly ISymUnmanagedReader reader; + + const int E_FAIL = unchecked((int)0x80004005); + + /// + /// Constructor + /// + /// An unmanaged symbol reader + public SymbolReaderImpl(ISymUnmanagedReader reader) { + if (reader == null) + throw new ArgumentNullException("reader"); + this.reader = reader; + } + + public override int UserEntryPoint { + get { + uint token; + int hr = reader.GetUserEntryPoint(out token); + if (hr == E_FAIL) + token = 0; + else + Marshal.ThrowExceptionForHR(hr); + return (int)token; + } + } + + public override ReadOnlyCollection Documents { + get { + if (documents == null) { + uint numDocs; + reader.GetDocuments(0, out numDocs, null); + var unDocs = new ISymUnmanagedDocument[numDocs]; + reader.GetDocuments((uint)unDocs.Length, out numDocs, unDocs); + var docs = new SymbolDocument[numDocs]; + for (uint i = 0; i < numDocs; i++) + docs[i] = new SymbolDocumentImpl(unDocs[i]); + Interlocked.CompareExchange(ref documents, new ReadOnlyCollection(docs), null); + } + return documents; + } + } + volatile ReadOnlyCollection documents; + + public override SymbolMethod GetMethod(int method, int version) { + ISymUnmanagedMethod unMethod; + int hr = reader.GetMethodByVersion((uint)method, version, out unMethod); + if (hr == E_FAIL) + return null; + Marshal.ThrowExceptionForHR(hr); + return unMethod == null ? null : new SymbolMethodImpl(unMethod); + } + + public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + const string CDI_NAME = "MD2"; + uint bufSize; + reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, 0, out bufSize, null); + if (bufSize == 0) + return; + var cdiData = new byte[bufSize]; + reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, (uint)cdiData.Length, out bufSize, cdiData); + PdbCustomDebugInfoReader.Read(method, body, result, cdiData); + } + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolScope.cs b/src/DotNet/Pdb/Dss/SymbolScope.cs deleted file mode 100644 index 07cc70c94..000000000 --- a/src/DotNet/Pdb/Dss/SymbolScope.cs +++ /dev/null @@ -1,133 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolScope : ISymbolScope2 { - readonly ISymUnmanagedScope scope; - - public SymbolScope(ISymUnmanagedScope scope) { - this.scope = scope; - } - - public int EndOffset { - get { - uint result; - scope.GetEndOffset(out result); - return (int)result; - } - } - - public ISymbolMethod Method { - get { - ISymUnmanagedMethod method; - scope.GetMethod(out method); - return method == null ? null : new SymbolMethod(method); - } - } - - public ISymbolScope Parent { - get { - ISymUnmanagedScope parentScope; - scope.GetParent(out parentScope); - return parentScope == null ? null : new SymbolScope(parentScope); - } - } - - public int StartOffset { - get { - uint result; - scope.GetStartOffset(out result); - return (int)result; - } - } - - public ISymbolScope[] GetChildren() { - uint numScopes; - scope.GetChildren(0, out numScopes, null); - var unScopes = new ISymUnmanagedScope[numScopes]; - scope.GetChildren((uint)unScopes.Length, out numScopes, unScopes); - var scopes = new ISymbolScope[numScopes]; - for (uint i = 0; i < numScopes; i++) - scopes[i] = new SymbolScope(unScopes[i]); - return scopes; - } - - public ISymbolVariable[] GetLocals() { - uint numVars; - scope.GetLocals(0, out numVars, null); - var unVars = new ISymUnmanagedVariable[numVars]; - scope.GetLocals((uint)unVars.Length, out numVars, unVars); - var vars = new ISymbolVariable[numVars]; - for (uint i = 0; i < numVars; i++) - vars[i] = new SymbolVariable(unVars[i]); - return vars; - } - - public ISymbolNamespace[] GetNamespaces() { - uint numNss; - scope.GetNamespaces(0, out numNss, null); - var unNss = new ISymUnmanagedNamespace[numNss]; - scope.GetNamespaces((uint)unNss.Length, out numNss, unNss); - var nss = new ISymbolNamespace[numNss]; - for (uint i = 0; i < numNss; i++) - nss[i] = new SymbolNamespace(unNss[i]); - return nss; - } - - public PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { - var scope2 = scope as ISymUnmanagedScope2; - if (scope2 == null) - return emptySymbolConstants; - uint numCs; - scope2.GetConstants(0, out numCs, null); - if (numCs == 0) - return emptySymbolConstants; - var unCs = new ISymUnmanagedConstant[numCs]; - scope2.GetConstants((uint)unCs.Length, out numCs, unCs); - var nss = new PdbConstant[numCs]; - for (uint i = 0; i < numCs; i++) { - var unc = unCs[i]; - var name = GetName(unc); - object value; - unc.GetValue(out value); - var sigBytes = GetSignatureBytes(unc); - TypeSig signature; - if (sigBytes.Length == 0) - signature = null; - else - signature = SignatureReader.ReadTypeSig(module, module.CorLibTypes, sigBytes, gpContext); - nss[i] = new PdbConstant(name, signature, value); - } - return nss; - } - static readonly PdbConstant[] emptySymbolConstants = new PdbConstant[0]; - - string GetName(ISymUnmanagedConstant unc) { - uint count; - unc.GetName(0, out count, null); - var chars = new char[count]; - unc.GetName((uint)chars.Length, out count, chars); - if (chars.Length == 0) - return string.Empty; - return new string(chars, 0, chars.Length - 1); - } - - byte[] GetSignatureBytes(ISymUnmanagedConstant unc) { - const int E_FAIL = unchecked((int)0x80004005); - const int E_NOTIMPL = unchecked((int)0x80004001); - uint bufSize; - int hr = unc.GetSignature(0, out bufSize, null); - if (bufSize == 0 || (hr < 0 && hr != E_FAIL && hr != E_NOTIMPL)) - return emptyByteArray; - var buffer = new byte[bufSize]; - hr = unc.GetSignature((uint)buffer.Length, out bufSize, buffer); - Debug.Assert(hr == 0); - if (hr != 0) - return emptyByteArray; - return buffer; - } - static readonly byte[] emptyByteArray = new byte[0]; - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs new file mode 100644 index 000000000..23b635311 --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -0,0 +1,149 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Threading; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Dss { + sealed class SymbolScopeImpl : SymbolScope { + readonly ISymUnmanagedScope scope; + readonly SymbolMethod method; + readonly SymbolScope parent; + + public SymbolScopeImpl(ISymUnmanagedScope scope, SymbolMethod method, SymbolScope parent) { + this.scope = scope; + this.method = method; + this.parent = parent; + } + + public override SymbolMethod Method { + get { return method; } + } + + public override SymbolScope Parent { + get { return parent; } + } + + public override int StartOffset { + get { + uint result; + scope.GetStartOffset(out result); + return (int)result; + } + } + + public override int EndOffset { + get { + uint result; + scope.GetEndOffset(out result); + return (int)result; + } + } + + public override ReadOnlyCollection Children { + get { + if (children == null) { + uint numScopes; + scope.GetChildren(0, out numScopes, null); + var unScopes = new ISymUnmanagedScope[numScopes]; + scope.GetChildren((uint)unScopes.Length, out numScopes, unScopes); + var scopes = new SymbolScope[numScopes]; + for (uint i = 0; i < numScopes; i++) + scopes[i] = new SymbolScopeImpl(unScopes[i], method, this); + Interlocked.CompareExchange(ref children, new ReadOnlyCollection(scopes), null); + } + return children; + } + } + volatile ReadOnlyCollection children; + + public override ReadOnlyCollection Locals { + get { + if (locals == null) { + uint numVars; + scope.GetLocals(0, out numVars, null); + var unVars = new ISymUnmanagedVariable[numVars]; + scope.GetLocals((uint)unVars.Length, out numVars, unVars); + var vars = new SymbolVariable[numVars]; + for (uint i = 0; i < numVars; i++) + vars[i] = new SymbolVariableImpl(unVars[i]); + Interlocked.CompareExchange(ref locals, new ReadOnlyCollection(vars), null); + } + return locals; + } + } + volatile ReadOnlyCollection locals; + + public override ReadOnlyCollection Namespaces { + get { + if (namespaces == null) { + uint numNss; + scope.GetNamespaces(0, out numNss, null); + var unNss = new ISymUnmanagedNamespace[numNss]; + scope.GetNamespaces((uint)unNss.Length, out numNss, unNss); + var nss = new SymbolNamespace[numNss]; + for (uint i = 0; i < numNss; i++) + nss[i] = new SymbolNamespaceImpl(unNss[i]); + Interlocked.CompareExchange(ref namespaces, new ReadOnlyCollection(nss), null); + } + return namespaces; + } + } + volatile ReadOnlyCollection namespaces; + + public override PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { + var scope2 = scope as ISymUnmanagedScope2; + if (scope2 == null) + return emptySymbolConstants; + uint numCs; + scope2.GetConstants(0, out numCs, null); + if (numCs == 0) + return emptySymbolConstants; + var unCs = new ISymUnmanagedConstant[numCs]; + scope2.GetConstants((uint)unCs.Length, out numCs, unCs); + var nss = new PdbConstant[numCs]; + for (uint i = 0; i < numCs; i++) { + var unc = unCs[i]; + var name = GetName(unc); + object value; + unc.GetValue(out value); + var sigBytes = GetSignatureBytes(unc); + TypeSig signature; + if (sigBytes.Length == 0) + signature = null; + else + signature = SignatureReader.ReadTypeSig(module, module.CorLibTypes, sigBytes, gpContext); + nss[i] = new PdbConstant(name, signature, value); + } + return nss; + } + static readonly PdbConstant[] emptySymbolConstants = new PdbConstant[0]; + + string GetName(ISymUnmanagedConstant unc) { + uint count; + unc.GetName(0, out count, null); + var chars = new char[count]; + unc.GetName((uint)chars.Length, out count, chars); + if (chars.Length == 0) + return string.Empty; + return new string(chars, 0, chars.Length - 1); + } + + byte[] GetSignatureBytes(ISymUnmanagedConstant unc) { + const int E_FAIL = unchecked((int)0x80004005); + const int E_NOTIMPL = unchecked((int)0x80004001); + uint bufSize; + int hr = unc.GetSignature(0, out bufSize, null); + if (bufSize == 0 || (hr < 0 && hr != E_FAIL && hr != E_NOTIMPL)) + return emptyByteArray; + var buffer = new byte[bufSize]; + hr = unc.GetSignature((uint)buffer.Length, out bufSize, buffer); + Debug.Assert(hr == 0); + if (hr != 0) + return emptyByteArray; + return buffer; + } + static readonly byte[] emptyByteArray = new byte[0]; + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolVariable.cs b/src/DotNet/Pdb/Dss/SymbolVariable.cs deleted file mode 100644 index 7baa48894..000000000 --- a/src/DotNet/Pdb/Dss/SymbolVariable.cs +++ /dev/null @@ -1,89 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolVariable : ISymbolVariable { - readonly ISymUnmanagedVariable variable; - - public SymbolVariable(ISymUnmanagedVariable variable) { - this.variable = variable; - } - - public int AddressField1 { - get { - uint result; - variable.GetAddressField1(out result); - return (int)result; - } - } - - public int AddressField2 { - get { - uint result; - variable.GetAddressField2(out result); - return (int)result; - } - } - - public int AddressField3 { - get { - uint result; - variable.GetAddressField3(out result); - return (int)result; - } - } - - public SymAddressKind AddressKind { - get { - uint result; - variable.GetAddressKind(out result); - return (SymAddressKind)result; - } - } - - public object Attributes { - get { - uint result; - variable.GetAttributes(out result); - return (int)result; - } - } - - public int EndOffset { - get { - uint result; - variable.GetEndOffset(out result); - return (int)result; - } - } - - public string Name { - get { - uint count; - variable.GetName(0, out count, null); - var chars = new char[count]; - variable.GetName((uint)chars.Length, out count, chars); - if (chars.Length == 0) - return string.Empty; - return new string(chars, 0, chars.Length - 1); - } - } - - public int StartOffset { - get { - uint result; - variable.GetStartOffset(out result); - return (int)result; - } - } - - public byte[] GetSignature() { - uint bufSize; - variable.GetSignature(0, out bufSize, null); - var buffer = new byte[bufSize]; - variable.GetSignature((uint)buffer.Length, out bufSize, buffer); - return buffer; - } - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs new file mode 100644 index 000000000..4efd7afa4 --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs @@ -0,0 +1,44 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Dss { + sealed class SymbolVariableImpl : SymbolVariable { + readonly ISymUnmanagedVariable variable; + + public SymbolVariableImpl(ISymUnmanagedVariable variable) { + this.variable = variable; + } + + public override int Index { + get { + uint result; + variable.GetAddressField1(out result); + return (int)result; + } + } + + public override SymbolVariableAttributes Attributes { + get { + uint result; + variable.GetAttributes(out result); + const int VAR_IS_COMP_GEN = 1; + if ((result & VAR_IS_COMP_GEN) != 0) + return SymbolVariableAttributes.CompilerGenerated; + return SymbolVariableAttributes.None; + } + } + + public override string Name { + get { + uint count; + variable.GetName(0, out count, null); + var chars = new char[count]; + variable.GetName((uint)chars.Length, out count, chars); + if (chars.Length == 0) + return string.Empty; + return new string(chars, 0, chars.Length - 1); + } + } + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs index fcb965a10..c06b76e08 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet.Pdb.Dss { /// /// Creates a /// - public static class SymbolWriterCreator { + static class SymbolWriterCreator { static readonly Guid CLSID_CorSymWriter_SxS = new Guid(0x0AE2DEB0, 0xF901, 0x478B, 0xBB, 0x9F, 0x88, 0x1E, 0xE8, 0x06, 0x67, 0x88); /// diff --git a/src/DotNet/Pdb/ISymbolMethod2.cs b/src/DotNet/Pdb/ISymbolMethod2.cs deleted file mode 100644 index 402b9a181..000000000 --- a/src/DotNet/Pdb/ISymbolMethod2.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb { - interface ISymbolMethod2 : ISymbolMethod { - bool IsAsyncMethod { get; } - uint KickoffMethod { get; } - uint? CatchHandlerILOffset { get; } - RawAsyncStepInfo[] GetAsyncStepInfos(); - } - - struct RawAsyncStepInfo { - public uint YieldOffset; - public uint BreakpointOffset; - public uint BreakpointMethod; - public RawAsyncStepInfo(uint yieldOffset, uint breakpointOffset, uint breakpointMethod) { - YieldOffset = yieldOffset; - BreakpointOffset = breakpointOffset; - BreakpointMethod = breakpointMethod; - } - } -} diff --git a/src/DotNet/Pdb/ISymbolScope2.cs b/src/DotNet/Pdb/ISymbolScope2.cs deleted file mode 100644 index 699c4a896..000000000 --- a/src/DotNet/Pdb/ISymbolScope2.cs +++ /dev/null @@ -1,19 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb { - /// - /// The managed version of ISymUnmanagedScope2 - /// - interface ISymbolScope2 : ISymbolScope { - /// - /// Gets all the constants - /// - /// Owner module if a signature must be read from the #Blob - /// Generic parameter context - /// - PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext); - } -} diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index 1e0f8fbe0..f0f9040d9 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -2,78 +2,54 @@ using System; using System.Diagnostics.SymbolStore; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiDocument : ISymbolDocument { - public string URL { get; private set; } - public Guid Language { get; private set; } - public Guid LanguageVendor { get; private set; } - public Guid DocumentType { get; private set; } - public Guid CheckSumAlgorithmId { get; private set; } - public byte[] CheckSum { get; private set; } + sealed class DbiDocument : SymbolDocument { + readonly string url; + Guid language; + Guid languageVendor; + Guid documentType; + Guid checkSumAlgorithmId; + byte[] checkSum; - public DbiDocument(string url) { - URL = url; - DocumentType = SymDocumentType.Text; + public override string URL { + get { return url; } } - - public void Read(IImageStream stream) { - stream.Position = 0; - Language = new Guid(stream.ReadBytes(0x10)); - LanguageVendor = new Guid(stream.ReadBytes(0x10)); - DocumentType = new Guid(stream.ReadBytes(0x10)); - CheckSumAlgorithmId = new Guid(stream.ReadBytes(0x10)); - - var len = stream.ReadInt32(); - if (stream.ReadUInt32() != 0) - throw new PdbException("Unexpected value"); - - CheckSum = stream.ReadBytes(len); + public override Guid Language { + get { return language; } } - - #region ISymbolDocument - - Guid ISymbolDocument.CheckSumAlgorithmId { - get { return CheckSumAlgorithmId; } + public override Guid LanguageVendor { + get { return languageVendor; } } - - Guid ISymbolDocument.DocumentType { - get { return DocumentType; } + public override Guid DocumentType { + get { return documentType; } } - - byte[] ISymbolDocument.GetCheckSum() { - return CheckSum; + public override Guid CheckSumAlgorithmId { + get { return checkSumAlgorithmId; } } - - Guid ISymbolDocument.Language { - get { return Language; } + public override byte[] CheckSum { + get { return checkSum; } } - Guid ISymbolDocument.LanguageVendor { - get { return LanguageVendor; } - } - - string ISymbolDocument.URL { - get { return URL; } - } - - int ISymbolDocument.FindClosestLine(int line) { - throw new NotImplementedException(); + public DbiDocument(string url) { + this.url = url; + documentType = SymDocumentType.Text; } - byte[] ISymbolDocument.GetSourceRange(int startLine, int startColumn, int endLine, int endColumn) { - throw new NotImplementedException(); - } + public void Read(IImageStream stream) { + stream.Position = 0; + language = new Guid(stream.ReadBytes(0x10)); + languageVendor = new Guid(stream.ReadBytes(0x10)); + documentType = new Guid(stream.ReadBytes(0x10)); + checkSumAlgorithmId = new Guid(stream.ReadBytes(0x10)); - bool ISymbolDocument.HasEmbeddedSource { - get { throw new NotImplementedException(); } - } + var len = stream.ReadInt32(); + if (stream.ReadUInt32() != 0) + throw new PdbException("Unexpected value"); - int ISymbolDocument.SourceLength { - get { throw new NotImplementedException(); } + checkSum = stream.ReadBytes(len); } - - #endregion } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index f1baf6a8c..9cb30acda 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -2,17 +2,36 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; -using System.Diagnostics.SymbolStore; +using System.Threading; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiFunction : ISymbolMethod2 { - public uint Token { get; internal set; } + sealed class DbiFunction : SymbolMethod { + public override int Token { + get { return token; } + } + internal int token; + public string Name { get; private set; } public PdbAddress Address { get; private set; } public DbiScope Root { get; private set; } - public IList Lines { get; internal set; } + public List Lines { + get { return lines; } + set { + lines = value; + sequencePoints = new ReadOnlyCollection(lines); + } + } + List lines; + + static readonly ReadOnlyCollection emptySymbolSequencePoints = new ReadOnlyCollection(new SymbolSequencePoint[0]); + + public DbiFunction() { + sequencePoints = emptySymbolSequencePoints; + } public void Read(IImageStream stream, long recEnd) { stream.Position += 4; @@ -20,13 +39,13 @@ public void Read(IImageStream stream, long recEnd) { stream.Position += 4; var len = stream.ReadUInt32(); stream.Position += 8; - Token = stream.ReadUInt32(); + token = stream.ReadInt32(); Address = PdbAddress.ReadAddress(stream); stream.Position += 1 + 2; Name = PdbReader.ReadCString(stream); stream.Position = recEnd; - Root = new DbiScope("", Address.Offset, len); + Root = new DbiScope(this, null, "", Address.Offset, len); Root.Read(new RecursionCounter(), stream, end); FixOffsets(new RecursionCounter(), Root); } @@ -35,100 +54,42 @@ void FixOffsets(RecursionCounter counter, DbiScope scope) { if (!counter.Increment()) return; - scope.BeginOffset -= Address.Offset; - scope.EndOffset -= Address.Offset; + scope.startOffset -= (int)Address.Offset; + scope.endOffset -= (int)Address.Offset; foreach (var child in scope.Children) - FixOffsets(counter, child); + FixOffsets(counter, (DbiScope)child); counter.Decrement(); } - ISymbolScope ISymbolMethod.RootScope { + public override SymbolScope RootScope { get { return Root; } } - int ISymbolMethod.SequencePointCount { - get { return Lines == null ? 0 : Lines.Count; } - } - - void ISymbolMethod.GetSequencePoints(int[] offsets, ISymbolDocument[] documents, int[] lines, int[] columns, - int[] endLines, int[] endColumns) { - int count = Lines == null ? 0 : Lines.Count; - if (offsets != null && offsets.Length != count) - throw new ArgumentException("Invalid array length: offsets"); - if (documents != null && documents.Length != count) - throw new ArgumentException("Invalid array length: documents"); - if (lines != null && lines.Length != count) - throw new ArgumentException("Invalid array length: lines"); - if (columns != null && columns.Length != count) - throw new ArgumentException("Invalid array length: columns"); - if (endLines != null && endLines.Length != count) - throw new ArgumentException("Invalid array length: endLines"); - if (endColumns != null && endColumns.Length != count) - throw new ArgumentException("Invalid array length: endColumns"); - - if (count <= 0) - return; - - int i = 0; - foreach (var line in Lines) { - offsets[i] = (int)line.Offset; - documents[i] = line.Document; - lines[i] = (int)line.LineBegin; - columns[i] = (int)line.ColumnBegin; - endLines[i] = (int)line.LineEnd; - endColumns[i] = (int)line.ColumnEnd; - i++; - } - } - - ISymbolNamespace ISymbolMethod.GetNamespace() { - throw new NotImplementedException(); - } - - int ISymbolMethod.GetOffset(ISymbolDocument document, int line, int column) { - throw new NotImplementedException(); - } - - ISymbolVariable[] ISymbolMethod.GetParameters() { - throw new NotImplementedException(); - } - - int[] ISymbolMethod.GetRanges(ISymbolDocument document, int line, int column) { - throw new NotImplementedException(); - } - - ISymbolScope ISymbolMethod.GetScope(int offset) { - throw new NotImplementedException(); - } - - bool ISymbolMethod.GetSourceStartEnd(ISymbolDocument[] docs, int[] lines, int[] columns) { - throw new NotImplementedException(); - } - - SymbolToken ISymbolMethod.Token { - get { throw new NotImplementedException(); } + public override ReadOnlyCollection SequencePoints { + get { return sequencePoints; } } + ReadOnlyCollection sequencePoints; const string asyncMethodInfoAttributeName = "asyncMethodInfo"; - public bool IsAsyncMethod { + public override bool IsAsyncMethod { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); return data != null && data.Length >= 0x0C; } } - uint ISymbolMethod2.KickoffMethod { + public override int KickoffMethod { get { Debug.Assert(IsAsyncMethod); var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) throw new InvalidOperationException(); - return BitConverter.ToUInt32(data, 0); + return BitConverter.ToInt32(data, 0); } } - uint? ISymbolMethod2.CatchHandlerILOffset { + public override uint? CatchHandlerILOffset { get { Debug.Assert(IsAsyncMethod); var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); @@ -139,7 +100,16 @@ uint ISymbolMethod2.KickoffMethod { } } - RawAsyncStepInfo[] ISymbolMethod2.GetAsyncStepInfos() { + public override ReadOnlyCollection AsyncStepInfos { + get { + if (asyncStepInfos == null) + Interlocked.CompareExchange(ref asyncStepInfos, new ReadOnlyCollection(CreateSymbolAsyncStepInfos()), null); + return asyncStepInfos; + } + } + volatile ReadOnlyCollection asyncStepInfos; + + SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { Debug.Assert(IsAsyncMethod); var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) @@ -148,16 +118,16 @@ RawAsyncStepInfo[] ISymbolMethod2.GetAsyncStepInfos() { int count = BitConverter.ToInt32(data, pos); pos += 4; if (pos + (long)count * 12 > data.Length) - return emptyRawAsyncStepInfo; + return emptySymbolAsyncStepInfos; if (count == 0) - return emptyRawAsyncStepInfo; - var res = new RawAsyncStepInfo[count]; + return emptySymbolAsyncStepInfos; + var res = new SymbolAsyncStepInfo[count]; for (int i = 0; i < res.Length; i++) { - res[i] = new RawAsyncStepInfo(BitConverter.ToUInt32(data, pos), BitConverter.ToUInt32(data, pos + 8), BitConverter.ToUInt32(data, pos + 4)); + res[i] = new SymbolAsyncStepInfo(BitConverter.ToUInt32(data, pos), BitConverter.ToUInt32(data, pos + 8), BitConverter.ToUInt32(data, pos + 4)); pos += 12; } return res; } - static readonly RawAsyncStepInfo[] emptyRawAsyncStepInfo = new RawAsyncStepInfo[0]; + static readonly SymbolAsyncStepInfo[] emptySymbolAsyncStepInfos = new SymbolAsyncStepInfo[0]; } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index ba894f8e1..db90c02b4 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { @@ -174,7 +175,7 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, IIm var func = funcs[found]; if (func.Lines != null) return; - func.Lines = new List(); + func.Lines = new List(); while (stream.Position < end) { var document = documents[stream.ReadUInt32()]; @@ -189,18 +190,18 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, IIm for (uint i = 0; i < count; i++) { stream.Position = lineTablePos + i * LINE_ENTRY_SIZE; - var line = new DbiSourceLine { + var line = new SymbolSequencePoint { Document = document }; - line.Offset = stream.ReadUInt32(); + line.Offset = stream.ReadInt32(); var lineFlags = stream.ReadUInt32(); - line.LineBegin = lineFlags & 0x00ffffff; - line.LineEnd = line.LineBegin + ((lineFlags >> 24) & 0x7F); + line.Line = (int)(lineFlags & 0x00ffffff); + line.EndLine = line.Line + (int)((lineFlags >> 24) & 0x7F); if ((flags & 1) != 0) { stream.Position = colTablePos + i * COL_ENTRY_SIZE; - line.ColumnBegin = stream.ReadUInt16(); - line.ColumnEnd = stream.ReadUInt16(); + line.Column = stream.ReadUInt16(); + line.EndColumn = stream.ReadUInt16(); } func.Lines.Add(line); @@ -208,4 +209,4 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, IIm } } } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/DbiNamespace.cs b/src/DotNet/Pdb/Managed/DbiNamespace.cs index 8bcd235c5..54fb02a24 100644 --- a/src/DotNet/Pdb/Managed/DbiNamespace.cs +++ b/src/DotNet/Pdb/Managed/DbiNamespace.cs @@ -1,30 +1,17 @@ // dnlib: See LICENSE.txt for more info using System; -using System.Diagnostics.SymbolStore; +using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiNamespace : ISymbolNamespace { - public string Namespace { get; private set; } - - public DbiNamespace(string ns) { - Namespace = ns; - } - - #region ISymbolNamespace - - public string Name { - get { return Namespace; } + sealed class DbiNamespace : SymbolNamespace { + public override string Name { + get { return name; } } + readonly string name; - public ISymbolNamespace[] GetNamespaces() { - throw new NotImplementedException(); - } - - public ISymbolVariable[] GetVariables() { - throw new NotImplementedException(); + public DbiNamespace(string ns) { + name = ns; } - - #endregion } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index a556c0484..c66402dbe 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -1,31 +1,69 @@ // dnlib: See LICENSE.txt for more info -using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; -using System.Diagnostics.SymbolStore; using System.Text; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiScope : ISymbolScope2 { - public DbiScope(string name, uint offset, uint length) { - Name = name; - BeginOffset = offset; - EndOffset = offset + length; + sealed class DbiScope : SymbolScope { + readonly SymbolMethod method; + readonly SymbolScope parent; + internal int startOffset; + internal int endOffset; + readonly List childrenList; + readonly List localsList; + readonly List namespacesList; + readonly ReadOnlyCollection children; + readonly ReadOnlyCollection locals; + readonly ReadOnlyCollection namespaces; + + public override SymbolMethod Method { + get { return method; } + } - Namespaces = new List(); - Variables = new List(); - Children = new List(); + public override SymbolScope Parent { + get { return parent; } } - public string Name { get; private set; } - public uint BeginOffset { get; internal set; } - public uint EndOffset { get; internal set; } + public override int StartOffset { + get { return startOffset; } + } + + public override int EndOffset { + get { return endOffset; } + } + + public override ReadOnlyCollection Children { + get { return children; } + } - public IList Namespaces { get; private set; } - public IList Variables { get; private set; } - public IList Children { get; private set; } + public override ReadOnlyCollection Locals { + get { return locals; } + } + + public override ReadOnlyCollection Namespaces { + get { return namespaces; } + } + + public DbiScope(SymbolMethod method, SymbolScope parent, string name, uint offset, uint length) { + this.method = method; + this.parent = parent; + Name = name; + startOffset = (int)offset; + endOffset = (int)(offset + length); + + childrenList = new List(); + children = new ReadOnlyCollection(childrenList); + localsList = new List(); + locals = new ReadOnlyCollection(localsList); + namespacesList = new List(); + namespaces = new ReadOnlyCollection(namespacesList); + } + + public string Name { get; private set; } List oemInfos; List constants; @@ -77,16 +115,16 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { var len = stream.ReadUInt32(); var addr = PdbAddress.ReadAddress(stream); name = PdbReader.ReadCString(stream); - child = new DbiScope(name, addr.Offset, len); + child = new DbiScope(method, this, name, addr.Offset, len); break; } case SymbolType.S_UNAMESPACE: - Namespaces.Add(new DbiNamespace(PdbReader.ReadCString(stream))); + namespacesList.Add(new DbiNamespace(PdbReader.ReadCString(stream))); break; case SymbolType.S_MANSLOT: { var variable = new DbiVariable(); variable.Read(stream); - Variables.Add(variable); + localsList.Add(variable); break; } case SymbolType.S_OEM: @@ -125,7 +163,7 @@ public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) { stream.Position = end; if (child != null) { child.Read(counter, stream, childEnd.Value); - Children.Add(child); + childrenList.Add(child); child = null; } } @@ -157,7 +195,7 @@ static bool ReadAndCompareBytes(IImageStream stream, long end, byte[] bytes) { return true; } - public PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { + public override PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { if (constants == null) return emptySymbolConstants; var res = new PdbConstant[constants.Count]; @@ -187,46 +225,5 @@ internal byte[] GetSymAttribute(string name) { } return null; } - - #region ISymbolScope - - int ISymbolScope.StartOffset { - get { return (int)BeginOffset; } - } - - int ISymbolScope.EndOffset { - get { return (int)EndOffset; } - } - - ISymbolScope[] ISymbolScope.GetChildren() { - var scopes = new ISymbolScope[Children.Count]; - for (int i = 0; i < scopes.Length; i++) - scopes[i] = Children[i]; - return scopes; - } - - ISymbolVariable[] ISymbolScope.GetLocals() { - var vars = new ISymbolVariable[Variables.Count]; - for (int i = 0; i < vars.Length; i++) - vars[i] = Variables[i]; - return vars; - } - - ISymbolNamespace[] ISymbolScope.GetNamespaces() { - var nss = new ISymbolNamespace[Namespaces.Count]; - for (int i = 0; i < nss.Length; i++) - nss[i] = Namespaces[i]; - return nss; - } - - ISymbolMethod ISymbolScope.Method { - get { throw new NotImplementedException(); } - } - - ISymbolScope ISymbolScope.Parent { - get { throw new NotImplementedException(); } - } - - #endregion } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/DbiSourceLine.cs b/src/DotNet/Pdb/Managed/DbiSourceLine.cs deleted file mode 100644 index 3a5aea924..000000000 --- a/src/DotNet/Pdb/Managed/DbiSourceLine.cs +++ /dev/null @@ -1,12 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb.Managed { - struct DbiSourceLine { - public DbiDocument Document; - public uint Offset; - public uint LineBegin; - public uint LineEnd; - public uint ColumnBegin; - public uint ColumnEnd; - } -} \ No newline at end of file diff --git a/src/DotNet/Pdb/Managed/DbiVariable.cs b/src/DotNet/Pdb/Managed/DbiVariable.cs index e3b886bab..082167cad 100644 --- a/src/DotNet/Pdb/Managed/DbiVariable.cs +++ b/src/DotNet/Pdb/Managed/DbiVariable.cs @@ -1,63 +1,38 @@ // dnlib: See LICENSE.txt for more info -using System; -using System.Diagnostics.SymbolStore; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiVariable : ISymbolVariable { - public uint Addr1 { get; private set; } - public string Name { get; private set; } - public ushort Flags { get; private set; } - - public void Read(IImageStream stream) { - Addr1 = stream.ReadUInt32(); - stream.Position += 10; - Flags = stream.ReadUInt16(); - Name = PdbReader.ReadCString(stream); - } - - #region ISymbolVariable - - public int AddressField1 { - get { return (int)Addr1; } - } - - public SymAddressKind AddressKind { - get { return SymAddressKind.ILOffset; } + sealed class DbiVariable : SymbolVariable { + public override string Name { + get { return name; } } + string name; - public object Attributes { - get { - const int fCompGenx = 4; - const int VAR_IS_COMP_GEN = 1; - if ((Flags & fCompGenx) != 0) - return VAR_IS_COMP_GEN; - else - return 0; - } + public override SymbolVariableAttributes Attributes { + get { return attributes; } } + SymbolVariableAttributes attributes; - public int AddressField2 { - get { throw new NotImplementedException(); } + public override int Index { + get { return index; } } + int index; - public int AddressField3 { - get { throw new NotImplementedException(); } - } - - public int EndOffset { - get { throw new NotImplementedException(); } - } - - public byte[] GetSignature() { - throw new NotImplementedException(); + public void Read(IImageStream stream) { + index = stream.ReadInt32(); + stream.Position += 10; + attributes = GetAttributes(stream.ReadUInt16()); + name = PdbReader.ReadCString(stream); } - public int StartOffset { - get { throw new NotImplementedException(); } + static SymbolVariableAttributes GetAttributes(uint flags) { + SymbolVariableAttributes res = 0; + const int fCompGenx = 4; + if ((flags & fCompGenx) != 0) + res |= SymbolVariableAttributes.CompilerGenerated; + return res; } - - #endregion } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/PdbException.cs b/src/DotNet/Pdb/Managed/PdbException.cs index be14e2823..390e498a0 100644 --- a/src/DotNet/Pdb/Managed/PdbException.cs +++ b/src/DotNet/Pdb/Managed/PdbException.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Pdb.Managed { /// Exception that is thrown when encounters an error. /// [Serializable] - public sealed class PdbException : Exception { + sealed class PdbException : Exception { /// /// Constructor /// @@ -40,4 +40,4 @@ public PdbException(SerializationInfo info, StreamingContext context) : base(info, context) { } } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 4e426fecf..b5a28e24e 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -3,16 +3,19 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; -using System.Diagnostics.SymbolStore; using System.Text; +using System.Threading; +using dnlib.DotNet.Emit; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { /// /// A managed PDB reader implementation for .NET modules. /// - public sealed class PdbReader : ISymbolReader { + sealed class PdbReader : SymbolReader { MsfStream[] streams; Dictionary names; Dictionary strings; @@ -25,7 +28,7 @@ public sealed class PdbReader : ISymbolReader { const ushort STREAM_INVALID_INDEX = ushort.MaxValue; Dictionary documents; - Dictionary functions; + Dictionary functions; uint entryPt; /// @@ -110,18 +113,20 @@ void ReadInternal(IImageStream stream) { var tokenMapStream = ReadModules(); documents = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var module in modules) + foreach (var module in modules) { if (IsValidStreamIndex(module.StreamId)) module.LoadFunctions(this, streams[module.StreamId].Content); + } if (IsValidStreamIndex(tokenMapStream ?? STREAM_INVALID_INDEX)) ApplyRidMap(streams[tokenMapStream.Value].Content); - functions = new Dictionary(); - foreach (var module in modules) + functions = new Dictionary(); + foreach (var module in modules) { foreach (var func in module.Functions) { functions.Add(func.Token, func); } + } } bool IsValidStreamIndex(ushort index) { @@ -289,12 +294,13 @@ void ApplyRidMap(IImageStream stream) { for (int i = 0; i < map.Length; i++) map[i] = stream.ReadUInt32(); - foreach (var module in modules) + foreach (var module in modules) { foreach (var func in module.Functions) { - var rid = func.Token & 0x00ffffff; + var rid = (uint)func.Token & 0x00ffffff; rid = map[rid]; - func.Token = (func.Token & 0xff000000) | rid; + func.token = (int)((func.Token & 0xff000000) | rid); } + } if (entryPt != 0) { var rid = entryPt & 0x00ffffff; @@ -312,64 +318,42 @@ internal static string ReadCString(IImageStream stream) { return value; } - #region ISymbolReader - - ISymbolMethod ISymbolReader.GetMethod(SymbolToken method) { + public override SymbolMethod GetMethod(int method, int version) { DbiFunction symMethod; - if (functions.TryGetValue((uint)method.GetToken(), out symMethod)) + if (functions.TryGetValue(method, out symMethod)) return symMethod; return null; } - ISymbolDocument[] ISymbolReader.GetDocuments() { - var docs = new ISymbolDocument[documents.Count]; - int i = 0; - foreach (var doc in documents.Values) - docs[i++] = doc; - return docs; - } - - SymbolToken ISymbolReader.UserEntryPoint { - get { return new SymbolToken((int)entryPt); } - } - - ISymbolDocument ISymbolReader.GetDocument(string url, Guid language, Guid languageVendor, Guid documentType) { - throw new NotImplementedException(); - } - - ISymbolVariable[] ISymbolReader.GetGlobalVariables() { - throw new NotImplementedException(); - } - - ISymbolMethod ISymbolReader.GetMethod(SymbolToken method, int version) { - throw new NotImplementedException(); - } - - ISymbolMethod ISymbolReader.GetMethodFromDocumentPosition(ISymbolDocument document, int line, int column) { - throw new NotImplementedException(); + public override ReadOnlyCollection Documents { + get { + if (documentsResult == null) { + var docs = new SymbolDocument[documents.Count]; + int i = 0; + foreach (var doc in documents.Values) + docs[i++] = doc; + Interlocked.CompareExchange(ref documentsResult, new ReadOnlyCollection(docs), null); + } + return documentsResult; + } } + volatile ReadOnlyCollection documentsResult; - ISymbolNamespace[] ISymbolReader.GetNamespaces() { - throw new NotImplementedException(); + public override int UserEntryPoint { + get { return (int)entryPt; } } - byte[] ISymbolReader.GetSymAttribute(SymbolToken parent, string name) { + public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + const string CDI_NAME = "MD2"; DbiFunction func; - bool b = functions.TryGetValue((uint)parent.GetToken(), out func); + bool b = functions.TryGetValue(method.MDToken.ToInt32(), out func); Debug.Assert(b); if (!b) - return emptyByteArray; - var res = func.Root.GetSymAttribute(name); - if (res == null) - return emptyByteArray; - return res; - } - static readonly byte[] emptyByteArray = new byte[0]; - - ISymbolVariable[] ISymbolReader.GetVariables(SymbolToken parent) { - throw new NotImplementedException(); + return; + var cdiData = func.Root.GetSymAttribute(CDI_NAME); + if (cdiData == null) + return; + PdbCustomDebugInfoReader.Read(method, body, result, cdiData); } - - #endregion } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs index 37a237e11..d9b6ca063 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs @@ -1,51 +1,51 @@ // dnlib: See LICENSE.txt for more info using System; -using System.Diagnostics.SymbolStore; using System.IO; using System.Security; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { /// - /// Creates a instance + /// Creates a instance /// - public static class SymbolReaderCreator { + static class SymbolReaderCreator { /// - /// Creates a new instance + /// Creates a new instance /// /// Path to assembly - /// A new instance or null if there's no PDB + /// A new instance or null if there's no PDB /// file. - public static ISymbolReader CreateFromAssemblyFile(string assemblyFileName) { + public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { return Create(Path.ChangeExtension(assemblyFileName, "pdb")); } /// - /// Creates a new instance + /// Creates a new instance /// /// Path to PDB file - /// A new instance or null if there's no PDB + /// A new instance or null if there's no PDB /// file on disk. - public static ISymbolReader Create(string pdbFileName) { + public static SymbolReader Create(string pdbFileName) { return Create(OpenImageStream(pdbFileName)); } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB file data - /// A new instance or null. - public static ISymbolReader Create(byte[] pdbData) { + /// A new instance or null. + public static SymbolReader Create(byte[] pdbData) { return Create(MemoryImageStream.Create(pdbData)); } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB file stream which is now owned by this method - /// A new instance or null. - public static ISymbolReader Create(IImageStream pdbStream) { + /// A new instance or null. + public static SymbolReader Create(IImageStream pdbStream) { if (pdbStream == null) return null; try { @@ -53,11 +53,9 @@ public static ISymbolReader Create(IImageStream pdbStream) { pdbReader.Read(pdbStream); return pdbReader; } - catch (IOException) { - } - catch (UnauthorizedAccessException) { + catch (PdbException) { } - catch (SecurityException) { + catch (IOException) { } finally { if (pdbStream != null) diff --git a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs new file mode 100644 index 000000000..e06ffaf52 --- /dev/null +++ b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs @@ -0,0 +1,77 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; +using System.Security; +using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb.Symbols; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb { + static class ManagedSymbolReaderCreator { + public static SymbolReader CreateFromAssemblyFile(IMetaData metaData, string assemblyFileName) { + return Create(metaData, Path.ChangeExtension(assemblyFileName, "pdb")); + } + + public static SymbolReader Create(IMetaData metaData, string pdbFileName) { + return Create(metaData, OpenImageStream(pdbFileName)); + } + + public static SymbolReader Create(IMetaData metaData, byte[] pdbData) { + return Create(metaData, MemoryImageStream.Create(pdbData)); + } + + public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { + try { + // Embedded pdbs have priority + var res = Create(metaData); + if (res != null) + return res; + + return CreateCore(metaData, pdbStream); + } + finally { + if (pdbStream != null) + pdbStream.Dispose(); + } + } + + static SymbolReader CreateCore(IMetaData metaData, IImageStream pdbStream) { + if (pdbStream == null) + return null; + try { + uint sig = pdbStream.ReadUInt32(); + pdbStream.Position = 0; + if (sig == 0x424A5342) + return Portable.SymbolReaderCreator.TryCreate(metaData, pdbStream); + return Managed.SymbolReaderCreator.Create(pdbStream); + } + catch (IOException) { + } + finally { + if (pdbStream != null) + pdbStream.Dispose(); + } + return null; + } + + internal static SymbolReader Create(IMetaData metaData) { + return Portable.SymbolReaderCreator.TryCreate(metaData); + } + + static IImageStream OpenImageStream(string fileName) { + try { + if (!File.Exists(fileName)) + return null; + return ImageStreamCreator.CreateImageStream(fileName); + } + catch (IOException) { + } + catch (UnauthorizedAccessException) { + } + catch (SecurityException) { + } + return null; + } + } +} diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index 0cafda3d1..e539d6ffc 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.Diagnostics.SymbolStore; +using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb { /// @@ -49,8 +50,8 @@ public PdbDocument() { /// /// Constructor /// - /// A instance - public PdbDocument(ISymbolDocument symDoc) { + /// A instance + public PdbDocument(SymbolDocument symDoc) { if (symDoc == null) throw new ArgumentNullException("symDoc"); this.Url = symDoc.URL; @@ -58,7 +59,7 @@ public PdbDocument(ISymbolDocument symDoc) { this.LanguageVendor = symDoc.LanguageVendor; this.DocumentType = symDoc.DocumentType; this.CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId; - this.CheckSum = symDoc.GetCheckSum(); + this.CheckSum = symDoc.CheckSum; } /// diff --git a/src/DotNet/Pdb/PdbImplType.cs b/src/DotNet/Pdb/PdbImplType.cs index 90e9a94c5..147bd24f3 100644 --- a/src/DotNet/Pdb/PdbImplType.cs +++ b/src/DotNet/Pdb/PdbImplType.cs @@ -6,12 +6,14 @@ namespace dnlib.DotNet.Pdb { /// public enum PdbImplType { /// - /// Use Microsoft's COM DLL (diasymreader.dll) + /// Use Microsoft's COM DLL (diasymreader.dll). It's not recommended to use this reader since it can only be accessed on the COM thread. + /// + /// This reader can only read the old PDB files (aka Windows PDB files). It does not support portable PDB files. /// MicrosoftCOM, /// - /// Use the managed PDB reader + /// Use the managed PDB reader. It supports Windows PDB files and portable PDB files and is the default PDB reader. /// Managed, diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index a2ee74dbe..1e0cb46ac 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -2,9 +2,10 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; -using System.Diagnostics.SymbolStore; using dnlib.DotNet.Emit; +using dnlib.DotNet.Pdb.Symbols; using dnlib.Threading; namespace dnlib.DotNet.Pdb { @@ -12,7 +13,7 @@ namespace dnlib.DotNet.Pdb { /// PDB state for a /// public sealed class PdbState { - readonly ISymbolReader reader; + readonly SymbolReader reader; readonly Dictionary docDict = new Dictionary(); MethodDef userEntryPoint; Compiler compiler; @@ -80,9 +81,9 @@ public PdbState(ModuleDef module) { /// /// Constructor /// - /// A instance + /// A instance /// Owner module - public PdbState(ISymbolReader reader, ModuleDefMD module) { + public PdbState(SymbolReader reader, ModuleDefMD module) { if (reader == null) throw new ArgumentNullException("reader"); if (module == null) @@ -90,9 +91,9 @@ public PdbState(ISymbolReader reader, ModuleDefMD module) { this.reader = reader; this.compiler = CalculateCompiler(module); - this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint.GetToken()) as MethodDef; + this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; - foreach (var doc in reader.GetDocuments()) + foreach (var doc in reader.Documents) Add_NoLock(new PdbDocument(doc)); } @@ -204,27 +205,23 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci if (reader == null || body == null) return; - var token = new SymbolToken((int)(0x06000000 + methodRid)); - ISymbolMethod method; + var token = (int)(0x06000000 + methodRid); + SymbolMethod method; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - method = reader.GetMethod(token); + method = reader.GetMethod(token, 1); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, ownerMethod == null ? new GenericParamContext() : GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); - var method2 = method as ISymbolMethod2; - Debug.Assert(method2 != null); - if (module != null && method2 != null && method2.IsAsyncMethod) - pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method2); + if (module != null && method.IsAsyncMethod) + pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method); if (ownerMethod != null) { // Read the custom debug info last so eg. local names have been initialized - var cdiData = reader.GetSymAttribute(token, "MD2"); - if (cdiData != null && cdiData.Length != 0) - PdbCustomDebugInfoReader.Read(ownerMethod, body, pdbMethod.CustomDebugInfos, cdiData); + reader.GetCustomDebugInfo(ownerMethod, body, pdbMethod.CustomDebugInfos); } body.PdbMethod = pdbMethod; @@ -253,15 +250,15 @@ Compiler CalculateCompiler(ModuleDef module) { } static readonly UTF8String nameAssemblyVisualBasic = new UTF8String("Microsoft.VisualBasic"); - PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, ISymbolMethod2 symMethod) { + PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { var kickoffToken = new MDToken(symMethod.KickoffMethod); if (kickoffToken.Table != MD.Table.Method) return null; var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); - var rawStepInfos = symMethod.GetAsyncStepInfos(); + var asyncStepInfos = symMethod.AsyncStepInfos; - var asyncMethod = new PdbAsyncMethod(rawStepInfos.Length); + var asyncMethod = new PdbAsyncMethod(asyncStepInfos.Count); asyncMethod.KickoffMethod = kickoffMethod; var catchHandlerILOffset = symMethod.CatchHandlerILOffset; @@ -270,7 +267,7 @@ PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody b Debug.Assert(asyncMethod.CatchHandlerInstruction != null); } - foreach (var rawInfo in rawStepInfos) { + foreach (var rawInfo in asyncStepInfos) { var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); Debug.Assert(yieldInstruction != null); if (yieldInstruction == null) @@ -320,40 +317,31 @@ Instruction GetInstruction(CilBody body, uint offset) { return null; } - void AddSequencePoints(CilBody body, ISymbolMethod method) { - int numSeqs = method.SequencePointCount; - var offsets = new int[numSeqs]; - var documents = new ISymbolDocument[numSeqs]; - var lines = new int[numSeqs]; - var columns = new int[numSeqs]; - var endLines = new int[numSeqs]; - var endColumns = new int[numSeqs]; - method.GetSequencePoints(offsets, documents, lines, columns, endLines, endColumns); - + void AddSequencePoints(CilBody body, SymbolMethod method) { int instrIndex = 0; - for (int i = 0; i < numSeqs; i++) { - var instr = GetInstruction(body.Instructions, offsets[i], ref instrIndex); + foreach (var sp in method.SequencePoints) { + var instr = GetInstruction(body.Instructions, sp.Offset, ref instrIndex); if (instr == null) continue; var seqPoint = new SequencePoint() { - Document = Add_NoLock(new PdbDocument(documents[i])), - StartLine = lines[i], - StartColumn = columns[i], - EndLine = endLines[i], - EndColumn = endColumns[i], + Document = Add_NoLock(new PdbDocument(sp.Document)), + StartLine = sp.Line, + StartColumn = sp.Column, + EndLine = sp.EndLine, + EndColumn = sp.EndColumn, }; instr.SequencePoint = seqPoint; } } struct CreateScopeState { - public ISymbolScope SymScope; + public SymbolScope SymScope; public PdbScope PdbScope; - public ISymbolScope[] Children; + public ReadOnlyCollection Children; public int ChildrenIndex; } - PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, ISymbolScope symScope) { + PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, SymbolScope symScope) { if (symScope == null) return null; @@ -368,11 +356,8 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), }; - foreach (var symLocal in state.SymScope.GetLocals()) { - if (symLocal.AddressKind != SymAddressKind.ILOffset) - continue; - - int localIndex = symLocal.AddressField1; + foreach (var symLocal in state.SymScope.Locals) { + int localIndex = symLocal.Index; if ((uint)localIndex >= (uint)body.Variables.Count) { // VB sometimes creates a PDB local without a metadata local continue; @@ -380,18 +365,19 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody var local = body.Variables[localIndex]; local.Name = symLocal.Name; var attributes = symLocal.Attributes; - if (attributes is int) - local.PdbAttributes = (int)attributes; + int pdbAttributes = 0; + const int VAR_IS_COMP_GEN = 1; + if ((attributes & SymbolVariableAttributes.CompilerGenerated) != 0) + pdbAttributes |= VAR_IS_COMP_GEN; + local.PdbAttributes = pdbAttributes; state.PdbScope.Variables.Add(local); } - foreach (var ns in state.SymScope.GetNamespaces()) + foreach (var ns in state.SymScope.Namespaces) state.PdbScope.Namespaces.Add(ns.Name); - var scope2 = state.SymScope as ISymbolScope2; - Debug.Assert(scope2 != null); - if (scope2 != null && module != null) { - var constants = scope2.GetConstants(module, gpContext); + if (module != null) { + var constants = state.SymScope.GetConstants(module, gpContext); for (int i = 0; i < constants.Length; i++) { var constant = constants[i]; var type = constant.Type.RemovePinnedAndModifiers(); @@ -469,9 +455,9 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody // Here's the now somewhat obfuscated for loop state.ChildrenIndex = 0; - state.Children = state.SymScope.GetChildren(); + state.Children = state.SymScope.Children; do_return: - if (state.ChildrenIndex < state.Children.Length) { + if (state.ChildrenIndex < state.Children.Count) { var child = state.Children[state.ChildrenIndex]; stack.Push(state); state = new CreateScopeState() { SymScope = child }; diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs new file mode 100644 index 000000000..a3e17eb10 --- /dev/null +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -0,0 +1,42 @@ +// dnlib: See LICENSE.txt for more info + +using System.IO; +using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb.Symbols; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Portable { + static class SymbolReaderCreator { + public static SymbolReader TryCreate(IMetaData metaData, IImageStream pdbStream) { + if (metaData == null) + return null; + if (pdbStream == null) + return null; + try { + pdbStream.Position = 0; + if (pdbStream.ReadUInt32() != 0x424A5342) + return null; + pdbStream.Position = 0; + return null;//TODO: + } + catch (IOException) { + } + finally { + if (pdbStream != null) + pdbStream.Dispose(); + } + return null; + } + + public static SymbolReader TryCreate(IMetaData metaData) { + if (metaData == null) + return null; + try { + //TODO: + } + catch (IOException) { + } + return null; + } + } +} diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderCreator.cs index c811726de..1a837d24c 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderCreator.cs @@ -1,89 +1,101 @@ // dnlib: See LICENSE.txt for more info using System; -using System.Diagnostics.SymbolStore; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb { /// - /// Creates a instance + /// Creates a instance /// public static class SymbolReaderCreator { /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use /// Path to assembly - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, string assemblyFileName) { + /// A new instance or null if there's no PDB + /// file on disk or if it's not possible to create a . + public static SymbolReader Create(PdbImplType pdbImpl, string assemblyFileName) { + return CreateFromAssemblyFile(pdbImpl, null, assemblyFileName); + } + + /// + /// Creates a new instance + /// + /// PDB implementation to use + /// .NET metadata or null + /// Path to assembly + /// A new instance or null if there's no PDB + /// file on disk or if it's not possible to create a . + public static SymbolReader CreateFromAssemblyFile(PdbImplType pdbImpl, IMetaData metaData, string assemblyFileName) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(assemblyFileName); case PdbImplType.Managed: - return Managed.SymbolReaderCreator.CreateFromAssemblyFile(assemblyFileName); + return ManagedSymbolReaderCreator.CreateFromAssemblyFile(metaData, assemblyFileName); default: throw new InvalidOperationException(); } } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use - /// .NET metadata. Only need to be non-null if MS COM API should be used + /// .NET metadata or null /// Path to PDB file - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, string pdbFileName) { + /// A new instance or null if there's no PDB + /// file on disk or if it's not possible to create a . + public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, string pdbFileName) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(metaData, pdbFileName); case PdbImplType.Managed: - return Managed.SymbolReaderCreator.Create(pdbFileName); + return ManagedSymbolReaderCreator.Create(metaData, pdbFileName); default: throw new InvalidOperationException(); } } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use - /// .NET metadata. Only need to be non-null if MS COM API should be used + /// .NET metadata or null /// PDB file data - /// A new instance or null if it's not possible - /// to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, byte[] pdbData) { + /// A new instance or null if it's not possible + /// to create a . + public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, byte[] pdbData) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(metaData, pdbData); case PdbImplType.Managed: - return Managed.SymbolReaderCreator.Create(pdbData); + return ManagedSymbolReaderCreator.Create(metaData, pdbData); default: throw new InvalidOperationException(); } } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use - /// .NET metadata. Only need to be non-null if MS COM API should be used + /// .NET metadata or null /// PDB file stream which is now owned by us - /// A new instance or null if it's not possible - /// to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, IImageStream pdbStream) { + /// A new instance or null if it's not possible + /// to create a . + public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, IImageStream pdbStream) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(metaData, pdbStream); case PdbImplType.Managed: - return Managed.SymbolReaderCreator.Create(pdbStream); + return ManagedSymbolReaderCreator.Create(metaData, pdbStream); default: if (pdbStream != null) @@ -93,15 +105,15 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, IIma } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use /// .NET metadata stream which is now owned by us. Only need to be /// non-null if MS COM API should be used /// Path to PDB file - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, string pdbFileName) { + /// A new instance or null if there's no PDB + /// file on disk or if it's not possible to create a . + public static SymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, string pdbFileName) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(mdStream, pdbFileName); @@ -109,7 +121,7 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, s case PdbImplType.Managed: if (mdStream != null) mdStream.Dispose(); - return Managed.SymbolReaderCreator.Create(pdbFileName); + return ManagedSymbolReaderCreator.Create(null, pdbFileName); default: if (mdStream != null) @@ -119,15 +131,15 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, s } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use /// .NET metadata stream which is now owned by us. Only need to be /// non-null if MS COM API should be used /// PDB file data - /// A new instance or null if it's not possible - /// to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, byte[] pdbData) { + /// A new instance or null if it's not possible + /// to create a . + public static SymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, byte[] pdbData) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(mdStream, pdbData); @@ -135,7 +147,7 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, b case PdbImplType.Managed: if (mdStream != null) mdStream.Dispose(); - return Managed.SymbolReaderCreator.Create(pdbData); + return ManagedSymbolReaderCreator.Create(null, pdbData); default: if (mdStream != null) @@ -145,15 +157,15 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, b } /// - /// Creates a new instance + /// Creates a new instance /// /// PDB implementation to use /// .NET metadata stream which is now owned by us. Only need to be /// non-null if MS COM API should be used /// PDB file stream which is now owned by us - /// A new instance or null if it's not possible - /// to create a . - public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, IImageStream pdbStream) { + /// A new instance or null if it's not possible + /// to create a . + public static SymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, IImageStream pdbStream) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(mdStream, pdbStream); @@ -161,7 +173,7 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, I case PdbImplType.Managed: if (mdStream != null) mdStream.Dispose(); - return Managed.SymbolReaderCreator.Create(pdbStream); + return ManagedSymbolReaderCreator.Create(null, pdbStream); default: if (mdStream != null) @@ -171,5 +183,18 @@ public static ISymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, I throw new InvalidOperationException(); } } + + internal static SymbolReader Create(PdbImplType pdbImpl, MetaData metaData) { + switch (pdbImpl) { + case PdbImplType.MicrosoftCOM: + return null; + + case PdbImplType.Managed: + return ManagedSymbolReaderCreator.Create(metaData); + + default: + throw new InvalidOperationException(); + } + } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs b/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs new file mode 100644 index 000000000..5a6514808 --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs @@ -0,0 +1,35 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// Async step info + /// + public struct SymbolAsyncStepInfo { + /// + /// Yield offset + /// + public uint YieldOffset; + + /// + /// Breakpoint offset + /// + public uint BreakpointOffset; + + /// + /// Breakpoint method token + /// + public uint BreakpointMethod; + + /// + /// Constructor + /// + /// Yield offset + /// Breakpoint offset + /// Breakpoint method token + public SymbolAsyncStepInfo(uint yieldOffset, uint breakpointOffset, uint breakpointMethod) { + YieldOffset = yieldOffset; + BreakpointOffset = breakpointOffset; + BreakpointMethod = breakpointMethod; + } + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolDocument.cs b/src/DotNet/Pdb/Symbols/SymbolDocument.cs new file mode 100644 index 000000000..ad85350eb --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolDocument.cs @@ -0,0 +1,40 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// A document + /// + public abstract class SymbolDocument { + /// + /// Gets the URL + /// + public abstract string URL { get; } + + /// + /// Gets the language + /// + public abstract Guid Language { get; } + + /// + /// Gets the language vendor + /// + public abstract Guid LanguageVendor { get; } + + /// + /// Gets the document type + /// + public abstract Guid DocumentType { get; } + + /// + /// Gets the checksum algorithm id + /// + public abstract Guid CheckSumAlgorithmId { get; } + + /// + /// Gets the checksum + /// + public abstract byte[] CheckSum { get; } + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolMethod.cs b/src/DotNet/Pdb/Symbols/SymbolMethod.cs new file mode 100644 index 000000000..a9146879a --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolMethod.cs @@ -0,0 +1,45 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.ObjectModel; + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// A method + /// + public abstract class SymbolMethod { + /// + /// Gets the method token + /// + public abstract int Token { get; } + + /// + /// Gets the root scope + /// + public abstract SymbolScope RootScope { get; } + + /// + /// Gets all sequence points + /// + public abstract ReadOnlyCollection SequencePoints { get; } + + /// + /// true if this is an async method + /// + public abstract bool IsAsyncMethod { get; } + + /// + /// Gets the kick off method if it's an async method () + /// + public abstract int KickoffMethod { get; } + + /// + /// Gets the catch handler IL offset if it's an async method () + /// + public abstract uint? CatchHandlerILOffset { get; } + + /// + /// Gets the async step infos if it's an async method () + /// + public abstract ReadOnlyCollection AsyncStepInfos { get; } + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolNamespace.cs b/src/DotNet/Pdb/Symbols/SymbolNamespace.cs new file mode 100644 index 000000000..1b2bcff97 --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolNamespace.cs @@ -0,0 +1,13 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// A namespace + /// + public abstract class SymbolNamespace { + /// + /// Gets the name + /// + public abstract string Name { get; } + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs new file mode 100644 index 000000000..28b1b273a --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -0,0 +1,38 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using dnlib.DotNet.Emit; + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// Reads symbols from a PDB file + /// + public abstract class SymbolReader { + /// + /// Gets the user entry point token or 0 if none + /// + public abstract int UserEntryPoint { get; } + + /// + /// Gets all documents + /// + public abstract ReadOnlyCollection Documents { get; } + + /// + /// Gets a method + /// + /// Method token + /// Edit and continue version + /// + public abstract SymbolMethod GetMethod(int method, int version); + + /// + /// Reads custom debug info + /// + /// Method + /// Method body + /// Updated with custom debug info + public abstract void GetCustomDebugInfo(MethodDef method, CilBody body, IList result); + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolScope.cs b/src/DotNet/Pdb/Symbols/SymbolScope.cs new file mode 100644 index 000000000..91a572511 --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolScope.cs @@ -0,0 +1,53 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.ObjectModel; + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// A scope + /// + public abstract class SymbolScope { + /// + /// Gets the method + /// + public abstract SymbolMethod Method { get; } + + /// + /// Gets the parent scope + /// + public abstract SymbolScope Parent { get; } + + /// + /// Gets the start offset of the scope in the method + /// + public abstract int StartOffset { get; } + + /// + /// Gets the end offset of the scope in the method + /// + public abstract int EndOffset { get; } + + /// + /// Gets all child scopes + /// + public abstract ReadOnlyCollection Children { get; } + + /// + /// Gets all locals defined in this scope + /// + public abstract ReadOnlyCollection Locals { get; } + + /// + /// Gets all namespaces in this scope + /// + public abstract ReadOnlyCollection Namespaces { get; } + + /// + /// Gets all the constants + /// + /// Owner module if a signature must be read from the #Blob + /// Generic parameter context + /// + public abstract PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext); + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs new file mode 100644 index 000000000..7b5c91fc5 --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs @@ -0,0 +1,38 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// Sequence point + /// + public struct SymbolSequencePoint { + /// + /// IL offset + /// + public int Offset; + + /// + /// Document + /// + public SymbolDocument Document; + + /// + /// Start line + /// + public int Line; + + /// + /// Start column + /// + public int Column; + + /// + /// End line + /// + public int EndLine; + + /// + /// End column + /// + public int EndColumn; + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolVariable.cs b/src/DotNet/Pdb/Symbols/SymbolVariable.cs new file mode 100644 index 000000000..71e70ae8b --- /dev/null +++ b/src/DotNet/Pdb/Symbols/SymbolVariable.cs @@ -0,0 +1,41 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb.Symbols { + /// + /// A variable + /// + public abstract class SymbolVariable { + /// + /// Gets the name + /// + public abstract string Name { get; } + + /// + /// Gets the attributes + /// + public abstract SymbolVariableAttributes Attributes { get; } + + /// + /// Gets the index of the variable + /// + public abstract int Index { get; } + } + + /// + /// Variable flags + /// + [Flags] + public enum SymbolVariableAttributes { + /// + /// No bit is set + /// + None = 0, + + /// + /// It's a compiler generated variable + /// + CompilerGenerated = 0x00000001, + } +} diff --git a/src/dnlib.csproj b/src/dnlib.csproj index cf9b71a44..301b5681f 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -174,8 +174,8 @@ - - + + @@ -185,6 +185,15 @@ + + + + + + + + + @@ -194,14 +203,13 @@ - + - - - + + - - + + @@ -210,7 +218,6 @@ - From 7143727adabd44d0e9702b5b9f55d8518534544e Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 4 Nov 2017 21:01:33 +0100 Subject: [PATCH 047/511] More PDB updates --- src/DotNet/ModuleDef.cs | 4 + src/DotNet/ModuleDefMD.cs | 7 +- src/DotNet/Pdb/Dss/SymbolReaderCreator.cs | 21 +--- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 2 +- src/DotNet/Pdb/ImageStreamUtils.cs | 25 +++++ src/DotNet/Pdb/Managed/PdbReader.cs | 2 +- src/DotNet/Pdb/Managed/SymbolReaderCreator.cs | 19 +--- src/DotNet/Pdb/ManagedSymbolReaderCreator.cs | 28 +---- src/DotNet/Pdb/PdbState.cs | 7 +- src/DotNet/Pdb/SymbolReaderCreator.cs | 101 +----------------- src/DotNet/Pdb/Symbols/SymbolReader.cs | 14 ++- src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs | 24 +++++ src/dnlib.csproj | 1 + 13 files changed, 91 insertions(+), 164 deletions(-) create mode 100644 src/DotNet/Pdb/ImageStreamUtils.cs diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index c8cb077f6..77429dc0e 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -924,6 +924,10 @@ protected virtual void Dispose(bool disposing) { tdf.Dispose(); typeDefFinder = null; } + var ps = pdbState; + if (ps != null) + ps.Dispose(); + pdbState = null; } /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index d5b58b516..eb3145069 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -538,7 +538,7 @@ public void LoadPdb(PdbImplType pdbImpl) { var loc = location; if (string.IsNullOrEmpty(loc)) return; - LoadPdb(SymbolReaderCreator.Create(pdbImpl, loc)); + LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, loc)); } ModuleKind GetKind() { @@ -1878,8 +1878,9 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// Method rid /// Returns originak value CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body, uint rid) { - if (pdbState != null) - pdbState.InitializeMethodBody(this, method, body, rid); + var ps = pdbState; + if (ps != null) + ps.InitializeMethodBody(this, method, body, rid); return body; } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs index 9904b4f9a..035ea6739 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs @@ -25,7 +25,7 @@ static class SymbolReaderCreator { /// Path to assembly /// A new instance or null if there's no PDB /// file on disk or if any of the COM methods fail. - public static SymbolReader Create(string assemblyFileName) { + public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { try { object mdDispObj; Guid CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); @@ -61,21 +61,6 @@ public static SymbolReader Create(string assemblyFileName) { return null; } - static IImageStream OpenImageStream(string fileName) { - try { - if (!File.Exists(fileName)) - return null; - return ImageStreamCreator.CreateImageStream(fileName); - } - catch (IOException) { - } - catch (UnauthorizedAccessException) { - } - catch (SecurityException) { - } - return null; - } - /// /// Creates a new instance /// @@ -86,7 +71,7 @@ static IImageStream OpenImageStream(string fileName) { public static SymbolReader Create(IMetaData metaData, string pdbFileName) { var mdStream = CreateMetaDataStream(metaData); try { - return Create(mdStream, OpenImageStream(pdbFileName)); + return Create(mdStream, ImageStreamUtils.OpenImageStream(pdbFileName)); } catch { if (mdStream != null) @@ -143,7 +128,7 @@ public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { /// file on disk or if any of the COM methods fail. public static SymbolReader Create(IImageStream mdStream, string pdbFileName) { try { - return Create(mdStream, OpenImageStream(pdbFileName)); + return Create(mdStream, ImageStreamUtils.OpenImageStream(pdbFileName)); } catch { if (mdStream != null) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index be7efd5b3..a7e898c07 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -53,7 +53,7 @@ public override ReadOnlyCollection Documents { } volatile ReadOnlyCollection documents; - public override SymbolMethod GetMethod(int method, int version) { + public override SymbolMethod GetMethod(ModuleDef module, int method, int version) { ISymUnmanagedMethod unMethod; int hr = reader.GetMethodByVersion((uint)method, version, out unMethod); if (hr == E_FAIL) diff --git a/src/DotNet/Pdb/ImageStreamUtils.cs b/src/DotNet/Pdb/ImageStreamUtils.cs new file mode 100644 index 000000000..1538154a2 --- /dev/null +++ b/src/DotNet/Pdb/ImageStreamUtils.cs @@ -0,0 +1,25 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; +using System.Security; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb { + static class ImageStreamUtils { + public static IImageStream OpenImageStream(string fileName) { + try { + if (!File.Exists(fileName)) + return null; + return ImageStreamCreator.CreateImageStream(fileName); + } + catch (IOException) { + } + catch (UnauthorizedAccessException) { + } + catch (SecurityException) { + } + return null; + } + } +} diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index b5a28e24e..4f0b807a5 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -318,7 +318,7 @@ internal static string ReadCString(IImageStream stream) { return value; } - public override SymbolMethod GetMethod(int method, int version) { + public override SymbolMethod GetMethod(ModuleDef module, int method, int version) { DbiFunction symMethod; if (functions.TryGetValue(method, out symMethod)) return symMethod; diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs index d9b6ca063..1865e7dbc 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs @@ -1,8 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; using System.IO; -using System.Security; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; @@ -28,7 +26,7 @@ public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { /// A new instance or null if there's no PDB /// file on disk. public static SymbolReader Create(string pdbFileName) { - return Create(OpenImageStream(pdbFileName)); + return Create(ImageStreamUtils.OpenImageStream(pdbFileName)); } /// @@ -63,20 +61,5 @@ public static SymbolReader Create(IImageStream pdbStream) { } return null; } - - static IImageStream OpenImageStream(string fileName) { - try { - if (!File.Exists(fileName)) - return null; - return ImageStreamCreator.CreateImageStream(fileName); - } - catch (IOException) { - } - catch (UnauthorizedAccessException) { - } - catch (SecurityException) { - } - return null; - } } } diff --git a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs index e06ffaf52..8b65f23e8 100644 --- a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs +++ b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs @@ -1,8 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; using System.IO; -using System.Security; using dnlib.DotNet.MD; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; @@ -14,7 +12,7 @@ public static SymbolReader CreateFromAssemblyFile(IMetaData metaData, string ass } public static SymbolReader Create(IMetaData metaData, string pdbFileName) { - return Create(metaData, OpenImageStream(pdbFileName)); + return Create(metaData, ImageStreamUtils.OpenImageStream(pdbFileName)); } public static SymbolReader Create(IMetaData metaData, byte[] pdbData) { @@ -30,9 +28,10 @@ public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { return CreateCore(metaData, pdbStream); } - finally { + catch { if (pdbStream != null) pdbStream.Dispose(); + throw; } } @@ -48,30 +47,13 @@ static SymbolReader CreateCore(IMetaData metaData, IImageStream pdbStream) { } catch (IOException) { } - finally { - if (pdbStream != null) - pdbStream.Dispose(); - } + if (pdbStream != null) + pdbStream.Dispose(); return null; } internal static SymbolReader Create(IMetaData metaData) { return Portable.SymbolReaderCreator.TryCreate(metaData); } - - static IImageStream OpenImageStream(string fileName) { - try { - if (!File.Exists(fileName)) - return null; - return ImageStreamCreator.CreateImageStream(fileName); - } - catch (IOException) { - } - catch (UnauthorizedAccessException) { - } - catch (SecurityException) { - } - return null; - } } } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 1e0cb46ac..98a69c619 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -210,7 +210,7 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - method = reader.GetMethod(token, 1); + method = reader.GetMethod(module, token, 1); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, ownerMethod == null ? new GenericParamContext() : GenericParamContext.Create(ownerMethod), body, method.RootScope); @@ -375,6 +375,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody foreach (var ns in state.SymScope.Namespaces) state.PdbScope.Namespaces.Add(ns.Name); + state.PdbScope.ImportScope = state.SymScope.ImportScope; if (module != null) { var constants = state.SymScope.GetConstants(module, gpContext); @@ -500,6 +501,10 @@ static Instruction GetInstruction(IList instrs, int offset, ref int } return null; } + + internal void Dispose() { + reader.Dispose(); + } } enum Compiler { diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderCreator.cs index 1a837d24c..bb1b15d75 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderCreator.cs @@ -14,25 +14,14 @@ public static class SymbolReaderCreator { /// Creates a new instance /// /// PDB implementation to use - /// Path to assembly - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static SymbolReader Create(PdbImplType pdbImpl, string assemblyFileName) { - return CreateFromAssemblyFile(pdbImpl, null, assemblyFileName); - } - - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata or null + /// .NET metadata /// Path to assembly /// A new instance or null if there's no PDB /// file on disk or if it's not possible to create a . public static SymbolReader CreateFromAssemblyFile(PdbImplType pdbImpl, IMetaData metaData, string assemblyFileName) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(assemblyFileName); + return Dss.SymbolReaderCreator.CreateFromAssemblyFile(assemblyFileName); case PdbImplType.Managed: return ManagedSymbolReaderCreator.CreateFromAssemblyFile(metaData, assemblyFileName); @@ -45,7 +34,7 @@ public static SymbolReader CreateFromAssemblyFile(PdbImplType pdbImpl, IMetaData /// Creates a new instance /// /// PDB implementation to use - /// .NET metadata or null + /// .NET metadata /// Path to PDB file /// A new instance or null if there's no PDB /// file on disk or if it's not possible to create a . @@ -65,7 +54,7 @@ public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, strin /// Creates a new instance /// /// PDB implementation to use - /// .NET metadata or null + /// .NET metadata /// PDB file data /// A new instance or null if it's not possible /// to create a . @@ -85,7 +74,7 @@ public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, byte[ /// Creates a new instance /// /// PDB implementation to use - /// .NET metadata or null + /// .NET metadata /// PDB file stream which is now owned by us /// A new instance or null if it's not possible /// to create a . @@ -104,86 +93,6 @@ public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, IImag } } - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata stream which is now owned by us. Only need to be - /// non-null if MS COM API should be used - /// Path to PDB file - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static SymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, string pdbFileName) { - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(mdStream, pdbFileName); - - case PdbImplType.Managed: - if (mdStream != null) - mdStream.Dispose(); - return ManagedSymbolReaderCreator.Create(null, pdbFileName); - - default: - if (mdStream != null) - mdStream.Dispose(); - throw new InvalidOperationException(); - } - } - - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata stream which is now owned by us. Only need to be - /// non-null if MS COM API should be used - /// PDB file data - /// A new instance or null if it's not possible - /// to create a . - public static SymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, byte[] pdbData) { - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(mdStream, pdbData); - - case PdbImplType.Managed: - if (mdStream != null) - mdStream.Dispose(); - return ManagedSymbolReaderCreator.Create(null, pdbData); - - default: - if (mdStream != null) - mdStream.Dispose(); - throw new InvalidOperationException(); - } - } - - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata stream which is now owned by us. Only need to be - /// non-null if MS COM API should be used - /// PDB file stream which is now owned by us - /// A new instance or null if it's not possible - /// to create a . - public static SymbolReader Create(PdbImplType pdbImpl, IImageStream mdStream, IImageStream pdbStream) { - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(mdStream, pdbStream); - - case PdbImplType.Managed: - if (mdStream != null) - mdStream.Dispose(); - return ManagedSymbolReaderCreator.Create(null, pdbStream); - - default: - if (mdStream != null) - mdStream.Dispose(); - if (pdbStream != null) - pdbStream.Dispose(); - throw new InvalidOperationException(); - } - } - internal static SymbolReader Create(PdbImplType pdbImpl, MetaData metaData) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index 28b1b273a..86023b441 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using dnlib.DotNet.Emit; @@ -8,7 +9,7 @@ namespace dnlib.DotNet.Pdb.Symbols { /// /// Reads symbols from a PDB file /// - public abstract class SymbolReader { + public abstract class SymbolReader : IDisposable { /// /// Gets the user entry point token or 0 if none /// @@ -20,12 +21,13 @@ public abstract class SymbolReader { public abstract ReadOnlyCollection Documents { get; } /// - /// Gets a method + /// Gets a method or returns null if the method doesn't exist in the PDB file /// + /// Module /// Method token /// Edit and continue version /// - public abstract SymbolMethod GetMethod(int method, int version); + public abstract SymbolMethod GetMethod(ModuleDef module, int method, int version); /// /// Reads custom debug info @@ -34,5 +36,11 @@ public abstract class SymbolReader { /// Method body /// Updated with custom debug info public abstract void GetCustomDebugInfo(MethodDef method, CilBody body, IList result); + + /// + /// Cleans up resources + /// + public virtual void Dispose() { + } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs index 7b5c91fc5..49ff6380b 100644 --- a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs +++ b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs @@ -1,9 +1,13 @@ // dnlib: See LICENSE.txt for more info +using System.Diagnostics; +using System.Text; + namespace dnlib.DotNet.Pdb.Symbols { /// /// Sequence point /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] public struct SymbolSequencePoint { /// /// IL offset @@ -34,5 +38,25 @@ public struct SymbolSequencePoint { /// End column /// public int EndColumn; + + string GetDebuggerString() { + var sb = new StringBuilder(); + if (Line == 0xFEEFEE && EndLine == 0xFEEFEE) + sb.Append(""); + else { + sb.Append("("); + sb.Append(Line); + sb.Append(","); + sb.Append(Column); + sb.Append(")-("); + sb.Append(EndLine); + sb.Append(","); + sb.Append(EndColumn); + sb.Append(")"); + } + sb.Append(": "); + sb.Append(Document.URL); + return sb.ToString(); + } } } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 301b5681f..848f1eb8e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -175,6 +175,7 @@ + From 40f2be675021225917c553cc5f8773d9f6ccabd0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 4 Nov 2017 21:05:32 +0100 Subject: [PATCH 048/511] Add language version = 4.0 to project file --- src/DotNet/AssemblyDef.cs | 9 ++++++++- src/dnlib.csproj | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 23bc4ddb7..1b277eef9 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -989,7 +989,14 @@ void InitializeTargetFrameworkAttribute() { static readonly UTF8String nameTargetFrameworkAttribute = new UTF8String("TargetFrameworkAttribute"); static bool TryGetName(ICustomAttributeType caType, out UTF8String ns, out UTF8String name) { - var type = (caType as MemberRef)?.DeclaringType ?? (caType as MethodDef)?.DeclaringType; + ITypeDefOrRef type; + var mr = caType as MemberRef; + if (mr != null) + type = mr.DeclaringType; + else { + var md = caType as MethodDef; + type = md == null ? null : md.DeclaringType; + } var tr = type as TypeRef; if (tr != null) { ns = tr.Namespace; diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 848f1eb8e..69fc7e42a 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -15,6 +15,7 @@ 512 true ..\dnlib.snk + 4 true From feabff14e8c70acf9041a2ddb628d000971256c4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 4 Nov 2017 21:12:52 +0100 Subject: [PATCH 049/511] Add .editorconfig and .gitattributes files --- .editorconfig | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ .gitattributes | 4 ++ 2 files changed, 114 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..fdbdd033f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,110 @@ +root = true + +[*] +indent_size = 4 +indent_style = tab +insert_final_newline = true +tab_width = 4 +#end_of_line = + +[*.json] + +[App.config] + +[*.yml] +indent_size = 2 +indent_style = space + +[*.{proj,csproj,vbproj,props,targets,resx,vsixmanifest}] +indent_size = 2 +indent_style = space + +[app.manifest] +indent_size = 2 +indent_style = space + +[*.xml] + +[*.xaml] +indent_style = space + +[*.{cs,vb}] +dotnet_sort_system_directives_first = true +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:none +dotnet_style_predefined_type_for_member_access = true:none +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_separate_import_directive_groups = false +dotnet_style_prefer_is_null_check_over_reference_equality_method = false:suggestion +dotnet_style_require_accessibility_modifiers = never:info + +[*.cs] +csharp_style_throw_expression = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_var_for_built_in_types = false:none +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_expression_bodied_constructors = true:suggestion +csharp_style_expression_bodied_methods = true:suggestion +csharp_style_expression_bodied_operators = true:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_accessors = true:suggestion +csharp_prefer_braces = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_parentheses = +csharp_space_after_cast = false +csharp_space_around_declaration_statements = false +csharp_space_before_open_square_brackets = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_square_brackets = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_semicolon_in_for_statement = true +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_around_binary_operators = before_and_after +csharp_indent_braces = false +csharp_indent_block_contents = true +csharp_indent_switch_labels = false +csharp_indent_case_contents = true +csharp_indent_labels = flush_left +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true +csharp_new_line_before_open_brace = none +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true +csharp_indent_case_contents_when_block = false +csharp_prefer_inferred_anonymous_type_member_names = true:suggestion +csharp_prefer_inferred_tuple_names = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +#csharp_preferred_modifier_order = +csharp_style_pattern_local_over_anonymous_function = true:suggestion + +[*.vb] +visual_basic_prefer_inferred_anonymous_type_member_names = true:suggestion +visual_basic_prefer_inferred_tuple_names = true:suggestion +#visual_basic_preferred_modifier_order = diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..03177af52 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto +*.cs text diff=csharp +*.sln text eol=crlf +*.csproj text eol=crlf From 21952ffe3588e599abaf2139fcc85f25063236db Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 5 Nov 2017 21:42:53 +0100 Subject: [PATCH 050/511] WIP: Add portable PDB reader --- src/DotNet/MD/IMetaData.cs | 7 + src/DotNet/MD/MetaData.cs | 4 + src/DotNet/MD/TablesStream.cs | 32 +- src/DotNet/MD/TablesStream_Read.cs | 91 ++++ src/DotNet/ModuleDef.cs | 13 +- src/DotNet/ModuleDefMD.cs | 6 +- src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 6 +- src/DotNet/Pdb/Managed/DbiScope.cs | 6 +- src/DotNet/Pdb/PdbImport.cs | 464 ++++++++++++++++++ src/DotNet/Pdb/PdbScope.cs | 7 +- src/DotNet/Pdb/Portable/Constants.cs | 17 + src/DotNet/Pdb/Portable/DocumentNameReader.cs | 97 ++++ .../Pdb/Portable/ImportScopeBlobReader.cs | 154 ++++++ src/DotNet/Pdb/Portable/ListCache.cs | 22 + .../Portable/LocalConstantSigBlobReader.cs | 283 +++++++++++ src/DotNet/Pdb/Portable/PortablePdbReader.cs | 334 +++++++++++++ src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs | 73 +++ src/DotNet/Pdb/Portable/SymbolMethodImpl.cs | 54 ++ .../Pdb/Portable/SymbolReaderCreator.cs | 22 +- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 116 +++++ src/DotNet/Pdb/Portable/SymbolVariableImpl.cs | 29 ++ src/DotNet/Pdb/Symbols/SymbolScope.cs | 7 +- src/dnlib.csproj | 11 + 23 files changed, 1816 insertions(+), 39 deletions(-) create mode 100644 src/DotNet/Pdb/PdbImport.cs create mode 100644 src/DotNet/Pdb/Portable/Constants.cs create mode 100644 src/DotNet/Pdb/Portable/DocumentNameReader.cs create mode 100644 src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs create mode 100644 src/DotNet/Pdb/Portable/ListCache.cs create mode 100644 src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs create mode 100644 src/DotNet/Pdb/Portable/PortablePdbReader.cs create mode 100644 src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs create mode 100644 src/DotNet/Pdb/Portable/SymbolMethodImpl.cs create mode 100644 src/DotNet/Pdb/Portable/SymbolScopeImpl.cs create mode 100644 src/DotNet/Pdb/Portable/SymbolVariableImpl.cs diff --git a/src/DotNet/MD/IMetaData.cs b/src/DotNet/MD/IMetaData.cs index 41d0ec65d..0412d3479 100644 --- a/src/DotNet/MD/IMetaData.cs +++ b/src/DotNet/MD/IMetaData.cs @@ -325,5 +325,12 @@ public interface IMetaData : IDisposable { /// /// A new instance RidList GetNonNestedClassRidList(); + + /// + /// Finds all LocalScope rids owned by + /// + /// Owner Method rid + /// A instance containing the valid LocalScope rids + RidList GetLocalScopeRidList(uint methodRid); } } diff --git a/src/DotNet/MD/MetaData.cs b/src/DotNet/MD/MetaData.cs index 58ceedd8c..be239bcba 100644 --- a/src/DotNet/MD/MetaData.cs +++ b/src/DotNet/MD/MetaData.cs @@ -825,6 +825,10 @@ public RidList GetNonNestedClassRidList() { return nonNestedTypes; } + public RidList GetLocalScopeRidList(uint methodRid) { + return FindAllRows(tablesStream.LocalScopeTable, 0, methodRid); + } + /// public void Dispose() { Dispose(true); diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 252e2a12f..532293c6a 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -71,14 +71,14 @@ public sealed partial class TablesStream : DotNetStream { public MDTable GenericParamTable { get; private set; } public MDTable MethodSpecTable { get; private set; } public MDTable GenericParamConstraintTable { get; private set; } - public MDTable Document { get; private set; } - public MDTable MethodDebugInformation { get; private set; } - public MDTable LocalScope { get; private set; } - public MDTable LocalVariable { get; private set; } - public MDTable LocalConstant { get; private set; } - public MDTable ImportScope { get; private set; } - public MDTable StateMachineMethod { get; private set; } - public MDTable CustomDebugInformation { get; private set; } + public MDTable DocumentTable { get; private set; } + public MDTable MethodDebugInformationTable { get; private set; } + public MDTable LocalScopeTable { get; private set; } + public MDTable LocalVariableTable { get; private set; } + public MDTable LocalConstantTable { get; private set; } + public MDTable ImportScopeTable { get; private set; } + public MDTable StateMachineMethodTable { get; private set; } + public MDTable CustomDebugInformationTable { get; private set; } #pragma warning restore #if THREAD_SAFE @@ -312,14 +312,14 @@ void InitializeTables() { GenericParamTable = mdTables[(int)Table.GenericParam]; MethodSpecTable = mdTables[(int)Table.MethodSpec]; GenericParamConstraintTable = mdTables[(int)Table.GenericParamConstraint]; - Document = mdTables[(int)Table.Document]; - MethodDebugInformation = mdTables[(int)Table.MethodDebugInformation]; - LocalScope = mdTables[(int)Table.LocalScope]; - LocalVariable = mdTables[(int)Table.LocalVariable]; - LocalConstant = mdTables[(int)Table.LocalConstant]; - ImportScope = mdTables[(int)Table.ImportScope]; - StateMachineMethod = mdTables[(int)Table.StateMachineMethod]; - CustomDebugInformation = mdTables[(int)Table.CustomDebugInformation]; + DocumentTable = mdTables[(int)Table.Document]; + MethodDebugInformationTable = mdTables[(int)Table.MethodDebugInformation]; + LocalScopeTable = mdTables[(int)Table.LocalScope]; + LocalVariableTable = mdTables[(int)Table.LocalVariable]; + LocalConstantTable = mdTables[(int)Table.LocalConstant]; + ImportScopeTable = mdTables[(int)Table.ImportScope]; + StateMachineMethodTable = mdTables[(int)Table.StateMachineMethod]; + CustomDebugInformationTable = mdTables[(int)Table.CustomDebugInformation]; } /// diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index 91315fc2b..7f1db069c 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -1690,6 +1690,97 @@ internal uint ReadGenericParamConstraintRow2(uint rid) { #endif } + internal uint ReadMethodDebugInformationRow2(uint rid, out uint document) { + var table = MethodDebugInformationTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + document = columns[0].Read(reader); + return columns[1].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadDocumentRow2(uint rid, out uint name, out uint hashAlgorithm, out uint hash) { + var table = DocumentTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + name = columns[0].Read(reader); + hashAlgorithm = columns[1].Read(reader); + hash = columns[2].Read(reader); + return columns[3].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadLocalScopeRow2(uint rid, out uint importScope, out uint variableList, out uint constantList, out uint startOffset) { + var table = LocalScopeTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + reader.Position += columns[0].Size; + importScope = columns[1].Read(reader); + variableList = columns[2].Read(reader); + constantList = columns[3].Read(reader); + startOffset = reader.ReadUInt32(); + return reader.ReadUInt32(); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadImportScopeRow2(uint rid, out uint parent) { + var table = ImportScopeTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + parent = columns[0].Read(reader); + return columns[1].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadLocalVariableRow2(uint rid, out ushort attributes, out ushort index) { + var table = LocalVariableTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + attributes = reader.ReadUInt16(); + index = reader.ReadUInt16(); + return columns[2].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadLocalConstantRow2(uint rid, out uint name) { + var table = LocalConstantTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + name = columns[0].Read(reader); + return columns[1].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + /// /// Reads a column /// diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 77429dc0e..f686a750a 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -23,7 +23,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the Module table /// - public abstract class ModuleDef : IHasCustomAttribute, IResolutionScope, IDisposable, IListListener, IModule, ITypeDefFinder, IDnlibDef, ITokenResolver { + public abstract class ModuleDef : IHasCustomAttribute, IResolutionScope, IDisposable, IListListener, IModule, ITypeDefFinder, IDnlibDef, ITokenResolver, ISignatureReaderHelper { /// Default characteristics protected const Characteristics DefaultCharacteristics = Characteristics.ExecutableImage | Characteristics._32BitMachine; @@ -1532,6 +1532,17 @@ protected static bool IsGreaterAssemblyRefVersion(AssemblyRef found, AssemblyRef var newVer = newOne.Version; return foundVer == null || (newVer != null && newVer >= foundVer); } + + ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { + uint token; + if (!CodedToken.TypeDefOrRef.Decode(codedToken, out token)) + return null; + return ResolveToken(token) as ITypeDefOrRef; + } + + TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) { + return null; + } } /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index eb3145069..b03da243f 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -22,7 +22,7 @@ namespace dnlib.DotNet { /// /// Created from a row in the Module table /// - public sealed class ModuleDefMD : ModuleDefMD2, IInstructionOperandResolver, ISignatureReaderHelper { + public sealed class ModuleDefMD : ModuleDefMD2, IInstructionOperandResolver { /// The file that contains all .NET metadata MetaData metaData; IMethodDecrypter methodDecrypter; @@ -2045,9 +2045,5 @@ public byte[] ReadBlob(uint token) { return null; } - - TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) { - return null; - } } } diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs index 23b635311..5c222d84a 100644 --- a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -92,7 +92,11 @@ public override ReadOnlyCollection Namespaces { } volatile ReadOnlyCollection namespaces; - public override PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { + public override PdbImportScope ImportScope { + get { return null; } + } + + public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext) { var scope2 = scope as ISymUnmanagedScope2; if (scope2 == null) return emptySymbolConstants; diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index c66402dbe..d9a36eada 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -48,6 +48,10 @@ public override ReadOnlyCollection Namespaces { get { return namespaces; } } + public override PdbImportScope ImportScope { + get { return null; } + } + public DbiScope(SymbolMethod method, SymbolScope parent, string name, uint offset, uint length) { this.method = method; this.parent = parent; @@ -195,7 +199,7 @@ static bool ReadAndCompareBytes(IImageStream stream, long end, byte[] bytes) { return true; } - public override PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext) { + public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext) { if (constants == null) return emptySymbolConstants; var res = new PdbConstant[constants.Count]; diff --git a/src/DotNet/Pdb/PdbImport.cs b/src/DotNet/Pdb/PdbImport.cs new file mode 100644 index 000000000..f5c2714c4 --- /dev/null +++ b/src/DotNet/Pdb/PdbImport.cs @@ -0,0 +1,464 @@ +// dnlib: See LICENSE.txt for more info + +using System.Diagnostics; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + +namespace dnlib.DotNet.Pdb { + /// + /// Import scope + /// + public sealed class PdbImportScope { + readonly ThreadSafe.IList imports = ThreadSafeListCreator.Create(); + + /// + /// Constructor + /// + public PdbImportScope() { + } + + /// + /// Gets/sets the parent import scope + /// + public PdbImportScope Parent { get; set; } + + /// + /// Gets all imports + /// + public ThreadSafe.IList Imports { + get { return imports; } + } + + /// + /// true if is not empty + /// + public bool HasImports { + get { return imports.Count > 0; } + } + } + + /// + /// Import kind + /// + public enum PdbImportDefinitionKind { +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + ImportNamespace, + ImportAssemblyNamespace, + ImportType, + ImportXmlNamespace, + ImportAssemblyReferenceAlias, + AliasAssemblyReference, + AliasNamespace, + AliasAssemblyNamespace, + AliasType, +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member + } + + /// + /// PDB import base class + /// + public abstract class PdbImport { + /// + /// Gets the import kind + /// + public abstract PdbImportDefinitionKind Kind { get; } + + internal abstract void PreventNewClasses(); + } + + /// + /// Import namespace + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbImportNamespace : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.ImportNamespace; } + } + + /// + /// Gets the target namespace + /// + public string TargetNamespace { get; set; } + + /// + /// Constructor + /// + public PdbImportNamespace() { + } + + /// + /// Constructor + /// + /// + public PdbImportNamespace(string targetNamespace) { + TargetNamespace = targetNamespace; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1}", Kind, TargetNamespace); + } + } + + /// + /// Import assembly, namespace + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbImportAssemblyNamespace : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.ImportAssemblyNamespace; } + } + + /// + /// Gets the target assembly + /// + public AssemblyRef TargetAssembly { get; set; } + + /// + /// Gets the target namespace + /// + public string TargetNamespace { get; set; } + + /// + /// Constructor + /// + public PdbImportAssemblyNamespace() { + } + + /// + /// Constructor + /// + /// + /// + public PdbImportAssemblyNamespace(AssemblyRef targetAssembly, string targetNamespace) { + TargetAssembly = targetAssembly; + TargetNamespace = targetNamespace; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1} {2}", Kind, TargetAssembly, TargetNamespace); + } + } + + /// + /// Import type + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbImportType : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.ImportType; } + } + + /// + /// Gets the target type + /// + public ITypeDefOrRef TargetType { get; set; } + + /// + /// Constructor + /// + public PdbImportType() { + } + + /// + /// Constructor + /// + /// + public PdbImportType(ITypeDefOrRef targetType) { + TargetType = targetType; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1}", Kind, TargetType); + } + } + + /// + /// Import xml namespace + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbImportXmlNamespace : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.ImportXmlNamespace; } + } + + /// + /// Gets the alias + /// + public string Alias { get; set; } + + /// + /// Gets the target namespace + /// + public string TargetNamespace { get; set; } + + /// + /// Constructor + /// + public PdbImportXmlNamespace() { + } + + /// + /// Constructor + /// + /// + /// + public PdbImportXmlNamespace(string alias, string targetNamespace) { + Alias = alias; + TargetNamespace = targetNamespace; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1} = {2}", Kind, Alias, TargetNamespace); + } + } + + /// + /// Import assembly reference alias + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbImportAssemblyReferenceAlias : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.ImportAssemblyReferenceAlias; } + } + + /// + /// Gets the alias + /// + public string Alias { get; set; } + + /// + /// Constructor + /// + public PdbImportAssemblyReferenceAlias() { + } + + /// + /// Constructor + /// + /// + public PdbImportAssemblyReferenceAlias(string alias) { + Alias = alias; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1}", Kind, Alias); + } + } + + /// + /// Alias assembly reference + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbAliasAssemblyReference : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.AliasAssemblyReference; } + } + + /// + /// Gets the alias + /// + public string Alias { get; set; } + + /// + /// Gets the target assembly + /// + public AssemblyRef TargetAssembly { get; set; } + + /// + /// Constructor + /// + public PdbAliasAssemblyReference() { + } + + /// + /// Constructor + /// + /// + /// + public PdbAliasAssemblyReference(string alias, AssemblyRef targetAssembly) { + Alias = alias; + TargetAssembly = targetAssembly; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1} = {2}", Kind, Alias, TargetAssembly); + } + } + + /// + /// Alias namespace + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbAliasNamespace : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.AliasNamespace; } + } + + /// + /// Gets the alias + /// + public string Alias { get; set; } + + /// + /// Gets the target namespace + /// + public string TargetNamespace { get; set; } + + /// + /// Constructor + /// + public PdbAliasNamespace() { + } + + /// + /// Constructor + /// + /// + /// + public PdbAliasNamespace(string alias, string targetNamespace) { + Alias = alias; + TargetNamespace = targetNamespace; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1} = {2}", Kind, Alias, TargetNamespace); + } + } + + /// + /// Alias assembly namespace + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbAliasAssemblyNamespace : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.AliasAssemblyNamespace; } + } + + /// + /// Gets the alias + /// + public string Alias { get; set; } + + /// + /// Gets the target assembly + /// + public AssemblyRef TargetAssembly { get; set; } + + /// + /// Gets the target namespace + /// + public string TargetNamespace { get; set; } + + /// + /// Constructor + /// + public PdbAliasAssemblyNamespace() { + } + + /// + /// Constructor + /// + /// + /// + /// + public PdbAliasAssemblyNamespace(string alias, AssemblyRef targetAssembly, string targetNamespace) { + Alias = alias; + TargetAssembly = targetAssembly; + TargetNamespace = targetNamespace; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1} = {2} {3}", Kind, Alias, TargetAssembly, TargetNamespace); + } + } + + /// + /// Alias type + /// + [DebuggerDisplay("{GetDebuggerString(),nq}")] + public sealed class PdbAliasType : PdbImport { + /// + /// Returns + /// + public sealed override PdbImportDefinitionKind Kind { + get { return PdbImportDefinitionKind.AliasType; } + } + + /// + /// Gets the alias + /// + public string Alias { get; set; } + + /// + /// Gets the target type + /// + public ITypeDefOrRef TargetType { get; set; } + + /// + /// Constructor + /// + public PdbAliasType() { + } + + /// + /// Constructor + /// + /// + /// + public PdbAliasType(string alias, ITypeDefOrRef targetType) { + Alias = alias; + TargetType = targetType; + } + + internal sealed override void PreventNewClasses() { } + + string GetDebuggerString() { + return string.Format("{0}: {1} = {2}", Kind, Alias, TargetType); + } + } +} diff --git a/src/DotNet/Pdb/PdbScope.cs b/src/DotNet/Pdb/PdbScope.cs index 89cd73f67..ba0e3aa4b 100644 --- a/src/DotNet/Pdb/PdbScope.cs +++ b/src/DotNet/Pdb/PdbScope.cs @@ -60,7 +60,7 @@ public bool HasVariables { } /// - /// Gets all namespaces + /// Gets all namespaces (Windows PDBs). Portable PDBs use /// public ThreadSafe.IList Namespaces { get { return namespaces; } @@ -73,6 +73,11 @@ public bool HasNamespaces { get { return namespaces.Count > 0; } } + /// + /// Gets/sets the import scope (Portable PDBs). Windows PDBs use + /// + public PdbImportScope ImportScope { get; set; } + /// /// Gets all constants /// diff --git a/src/DotNet/Pdb/Portable/Constants.cs b/src/DotNet/Pdb/Portable/Constants.cs new file mode 100644 index 000000000..7295cf977 --- /dev/null +++ b/src/DotNet/Pdb/Portable/Constants.cs @@ -0,0 +1,17 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb.Portable { + static class Constants { + public static readonly Guid LanguageCSharp = new Guid("3F5162F8-07C6-11D3-9053-00C04FA302A1"); + public static readonly Guid LanguageVisualBasic = new Guid("3A12D0B8-C26C-11D0-B442-00A0244A1DD2"); + public static readonly Guid LanguageFSharp = new Guid("AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3"); + + public static readonly Guid HashSHA1 = new Guid("FF1816EC-AA5E-4D10-87F7-6F4963833460"); + public static readonly Guid HashSHA256 = new Guid("8829D00F-11B8-4213-878B-770E8597AC16"); + + public static readonly Guid LanguageVendorMicrosoft = new Guid("994B45C4-E6E9-11D2-903F-00C04FA302A1"); + public static readonly Guid DocumentTypeText = new Guid("5A869D0B-6611-11D3-BD2A-0000F80849BD"); + } +} diff --git a/src/DotNet/Pdb/Portable/DocumentNameReader.cs b/src/DotNet/Pdb/Portable/DocumentNameReader.cs new file mode 100644 index 000000000..ec55edc74 --- /dev/null +++ b/src/DotNet/Pdb/Portable/DocumentNameReader.cs @@ -0,0 +1,97 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Text; +using dnlib.DotNet.MD; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Portable { + struct DocumentNameReader { + const int MAX_NAME_LENGTH = 64 * 1024; + readonly Dictionary docNamePartDict; + readonly BlobStream blobStream; + readonly StringBuilder sb; + + char prevSepChar; + byte[] prevSepCharBytes; + int prevSepCharBytesCount; + + public DocumentNameReader(BlobStream blobStream) { + docNamePartDict = new Dictionary(); + this.blobStream = blobStream; + sb = new StringBuilder(); + + prevSepChar = '\0'; + prevSepCharBytes = new byte[3]; + prevSepCharBytesCount = 0; + } + + public string ReadDocumentName(uint offset) { + sb.Length = 0; + using (var stream = blobStream.CreateStream(offset)) { + var sepChar = ReadSeparatorChar(stream); + bool needSep = false; + while (stream.Position < stream.Length) { + if (needSep) + sb.Append(sepChar); + needSep = sepChar != '\0'; + var part = ReadDocumentNamePart(stream.ReadCompressedUInt32()); + sb.Append(part); + if (sb.Length > MAX_NAME_LENGTH) { + sb.Length = MAX_NAME_LENGTH; + break; + } + } + } + return sb.ToString(); + } + + string ReadDocumentNamePart(uint offset) { + string name; + if (docNamePartDict.TryGetValue(offset, out name)) + return name; + var data = blobStream.ReadNoNull(offset); + name = Encoding.UTF8.GetString(data); + docNamePartDict.Add(offset, name); + return name; + } + + char ReadSeparatorChar(IImageStream stream) { + if (prevSepCharBytesCount != 0 && prevSepCharBytesCount <= stream.Length) { + var pos = stream.Position; + bool ok = true; + for (int i = 0; i < prevSepCharBytesCount; i++) { + if (i >= prevSepCharBytes.Length || stream.ReadByte() != prevSepCharBytes[i]) { + ok = false; + break; + } + } + if (ok) + return prevSepChar; + stream.Position = pos; + } + + var decoder = Encoding.UTF8.GetDecoder(); + var bytes = new byte[1]; + var chars = new char[2]; + prevSepCharBytesCount = 0; + for (int i = 0; ; i++) { + byte b = stream.ReadByte(); + prevSepCharBytesCount++; + if (i == 0 && b == 0) + break; + if (i < prevSepCharBytes.Length) + prevSepCharBytes[i] = b; + bytes[0] = b; + bool isLastByte = stream.Position + 1 == stream.Length; + int bytesUsed, charsUsed; + bool completed; + decoder.Convert(bytes, 0, 1, chars, 0, 2, isLastByte, out bytesUsed, out charsUsed, out completed); + if (charsUsed > 0) + break; + } + prevSepChar = chars[0]; + return prevSepChar; + } + } +} diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs new file mode 100644 index 000000000..1c53e3d27 --- /dev/null +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -0,0 +1,154 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using dnlib.DotNet.MD; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Portable { + // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#imports-blob + struct ImportScopeBlobReader { + const PdbImportDefinitionKind UNKNOWN_IMPORT_KIND = (PdbImportDefinitionKind)(-1); + readonly ModuleDef module; + readonly BlobStream blobStream; + + /// + /// Constructor + /// + /// Module that resolves assembly and type references + /// Portable PDB blob stream + public ImportScopeBlobReader(ModuleDef module, BlobStream blobStream) { + this.module = module; + this.blobStream = blobStream; + } + + public void Read(uint imports, IList result) { + if (imports == 0) + return; + using (var stream = blobStream.CreateStream(imports)) { + while (stream.Position < stream.Length) { + var kind = ToPdbImportDefinitionKind(stream.ReadCompressedUInt32()); + string targetNamespace, alias; + AssemblyRef targetAssembly; + PdbImport import; + ITypeDefOrRef targetType; + switch (kind) { + case PdbImportDefinitionKind.ImportNamespace: + // ::= ImportNamespace + targetNamespace = ReadUTF8(stream.ReadCompressedUInt32()); + import = new PdbImportNamespace(targetNamespace); + break; + + case PdbImportDefinitionKind.ImportAssemblyNamespace: + // ::= ImportAssemblyNamespace + targetAssembly = TryReadAssemblyRef(stream.ReadCompressedUInt32()); + targetNamespace = ReadUTF8(stream.ReadCompressedUInt32()); + import = new PdbImportAssemblyNamespace(targetAssembly, targetNamespace); + break; + + case PdbImportDefinitionKind.ImportType: + // ::= ImportType + targetType = TryReadType(stream.ReadCompressedUInt32()); + import = new PdbImportType(targetType); + break; + + case PdbImportDefinitionKind.ImportXmlNamespace: + // ::= ImportXmlNamespace + alias = ReadUTF8(stream.ReadCompressedUInt32()); + targetNamespace = ReadUTF8(stream.ReadCompressedUInt32()); + import = new PdbImportXmlNamespace(alias, targetNamespace); + break; + + case PdbImportDefinitionKind.ImportAssemblyReferenceAlias: + // ::= ImportReferenceAlias + alias = ReadUTF8(stream.ReadCompressedUInt32()); + import = new PdbImportAssemblyReferenceAlias(alias); + break; + + case PdbImportDefinitionKind.AliasAssemblyReference: + // ::= AliasAssemblyReference + alias = ReadUTF8(stream.ReadCompressedUInt32()); + targetAssembly = TryReadAssemblyRef(stream.ReadCompressedUInt32()); + import = new PdbAliasAssemblyReference(alias, targetAssembly); + break; + + case PdbImportDefinitionKind.AliasNamespace: + // ::= AliasNamespace + alias = ReadUTF8(stream.ReadCompressedUInt32()); + targetNamespace = ReadUTF8(stream.ReadCompressedUInt32()); + import = new PdbAliasNamespace(alias, targetNamespace); + break; + + case PdbImportDefinitionKind.AliasAssemblyNamespace: + // ::= AliasAssemblyNamespace + alias = ReadUTF8(stream.ReadCompressedUInt32()); + targetAssembly = TryReadAssemblyRef(stream.ReadCompressedUInt32()); + targetNamespace = ReadUTF8(stream.ReadCompressedUInt32()); + import = new PdbAliasAssemblyNamespace(alias, targetAssembly, targetNamespace); + break; + + case PdbImportDefinitionKind.AliasType: + // ::= AliasType + alias = ReadUTF8(stream.ReadCompressedUInt32()); + targetType = TryReadType(stream.ReadCompressedUInt32()); + import = new PdbAliasType(alias, targetType); + break; + + case UNKNOWN_IMPORT_KIND: + import = null; + break; + + default: + Debug.Fail("Unknown import definition kind: " + kind.ToString()); + import = null; + break; + } + if (import != null) + result.Add(import); + } + Debug.Assert(stream.Position == stream.Length); + } + } + + ITypeDefOrRef TryReadType(uint codedToken) { + uint token; + bool b = CodedToken.TypeDefOrRef.Decode(codedToken, out token); + Debug.Assert(b); + if (!b) + return null; + var type = module.ResolveToken(token) as ITypeDefOrRef; + Debug.Assert(type != null); + return type; + } + + AssemblyRef TryReadAssemblyRef(uint rid) { + var asmRef = module.ResolveToken(0x23000000 + rid) as AssemblyRef; + Debug.Assert(asmRef != null); + return asmRef; + } + + string ReadUTF8(uint offset) { + var bytes = blobStream.ReadNoNull(offset); + return Encoding.UTF8.GetString(bytes); + } + + static PdbImportDefinitionKind ToPdbImportDefinitionKind(uint value) { + // See System.Reflection.Metadata.ImportDefinitionKind + switch (value) { + case 1: return PdbImportDefinitionKind.ImportNamespace; + case 2: return PdbImportDefinitionKind.ImportAssemblyNamespace; + case 3: return PdbImportDefinitionKind.ImportType; + case 4: return PdbImportDefinitionKind.ImportXmlNamespace; + case 5: return PdbImportDefinitionKind.ImportAssemblyReferenceAlias; + case 6: return PdbImportDefinitionKind.AliasAssemblyReference; + case 7: return PdbImportDefinitionKind.AliasNamespace; + case 8: return PdbImportDefinitionKind.AliasAssemblyNamespace; + case 9: return PdbImportDefinitionKind.AliasType; + default: + Debug.Fail("Unknown import definition kind: 0x" + value.ToString("X")); + return UNKNOWN_IMPORT_KIND; + } + } + } +} diff --git a/src/DotNet/Pdb/Portable/ListCache.cs b/src/DotNet/Pdb/Portable/ListCache.cs new file mode 100644 index 000000000..2ba38974b --- /dev/null +++ b/src/DotNet/Pdb/Portable/ListCache.cs @@ -0,0 +1,22 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Threading; + +namespace dnlib.DotNet.Pdb.Portable { + static class ListCache { + static volatile List cachedList; + public static List AllocList() { + return Interlocked.Exchange(ref cachedList, null) ?? new List(); + } + public static void Free(ref List list) { + list.Clear(); + cachedList = list; + } + public static T[] FreeAndToArray(ref List list) { + var res = list.ToArray(); + Free(ref list); + return res; + } + } +} diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs new file mode 100644 index 000000000..dd5234d25 --- /dev/null +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -0,0 +1,283 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Diagnostics; +using System.Text; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Portable { + struct LocalConstantSigBlobReader { + readonly ModuleDef module; + readonly IImageStream reader; + /*readonly*/ GenericParamContext gpContext; + RecursionCounter recursionCounter; + + public LocalConstantSigBlobReader(ModuleDef module, IImageStream reader, GenericParamContext gpContext) { + this.module = module; + this.reader = reader; + this.gpContext = gpContext; + recursionCounter = default(RecursionCounter); + } + + public bool Read(out TypeSig type, out object value) { + try { + return ReadCore(out type, out value); + } + catch { + } + type = null; + value = null; + return false; + } + + bool ReadCore(out TypeSig type, out object value) { + if (!recursionCounter.Increment()) { + type = null; + value = null; + return false; + } + + bool res; + ITypeDefOrRef tdr; + UTF8String ns, name; + var et = (ElementType)reader.ReadByte(); + switch (et) { + case ElementType.Boolean: + type = module.CorLibTypes.Boolean; + value = reader.ReadBoolean(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.Char: + type = module.CorLibTypes.Char; + value = (char)reader.ReadUInt16(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.I1: + type = module.CorLibTypes.SByte; + value = reader.ReadSByte(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.U1: + type = module.CorLibTypes.Byte; + value = reader.ReadByte(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.I2: + type = module.CorLibTypes.Int16; + value = reader.ReadInt16(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.U2: + type = module.CorLibTypes.UInt16; + value = reader.ReadUInt16(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.I4: + type = module.CorLibTypes.Int32; + value = reader.ReadInt32(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.U4: + type = module.CorLibTypes.UInt32; + value = reader.ReadUInt32(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.I8: + type = module.CorLibTypes.Int64; + value = reader.ReadInt64(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.U8: + type = module.CorLibTypes.UInt64; + value = reader.ReadUInt64(); + if (reader.Position < reader.Length) + type = new ValueTypeSig(ReadTypeDefOrRef()); + res = true; + break; + + case ElementType.R4: + type = module.CorLibTypes.Single; + value = reader.ReadSingle(); + res = true; + break; + + case ElementType.R8: + type = module.CorLibTypes.Double; + value = reader.ReadDouble(); + res = true; + break; + + case ElementType.String: + type = module.CorLibTypes.String; + value = ReadString(); + res = true; + break; + + + case ElementType.Ptr: + res = Read(out type, out value); + if (res) + type = new PtrSig(type); + break; + + case ElementType.ByRef: + res = Read(out type, out value); + if (res) + type = new ByRefSig(type); + break; + + case ElementType.Object: + type = module.CorLibTypes.Object; + value = null; + res = true; + break; + + case ElementType.ValueType: + type = new ValueTypeSig(tdr = ReadTypeDefOrRef()); + value = null; + if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib()) { + if (name == stringDecimal) { + if (reader.Length - reader.Position != 13) + goto default; + try { + byte b = reader.ReadByte(); + value = new Decimal(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), (b & 0x80) != 0, (byte)(b & 0x7F)); + } + catch { + goto default; + } + } + else if (name == stringDateTime) { + if (reader.Length - reader.Position != 8) + goto default; + try { + value = new DateTime(reader.ReadInt64()); + } + catch { + goto default; + } + } + } + if (value == null && reader.Position != reader.Length) + value = reader.ReadRemainingBytes(); + res = true; + break; + + case ElementType.Class: + type = new ClassSig(ReadTypeDefOrRef()); + value = reader.Position == reader.Length ? null : reader.ReadRemainingBytes(); + res = true; + break; + + case ElementType.CModReqd: + tdr = ReadTypeDefOrRef(); + res = Read(out type, out value); + if (res) + type = new CModReqdSig(tdr, type); + break; + + case ElementType.CModOpt: + tdr = ReadTypeDefOrRef(); + res = Read(out type, out value); + if (res) + type = new CModOptSig(tdr, type); + break; + + case ElementType.Var: + case ElementType.Array: + case ElementType.GenericInst: + case ElementType.TypedByRef: + case ElementType.I: + case ElementType.U: + case ElementType.FnPtr: + case ElementType.SZArray: + case ElementType.MVar: + case ElementType.End: + case ElementType.Void: + case ElementType.ValueArray: + case ElementType.R: + case ElementType.Internal: + case ElementType.Module: + case ElementType.Sentinel: + case ElementType.Pinned: + default: + Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString()); + res = false; + type = null; + value = null; + break; + } + + recursionCounter.Decrement(); + return res; + } + static readonly UTF8String stringSystem = new UTF8String("System"); + static readonly UTF8String stringDecimal = new UTF8String("Decimal"); + static readonly UTF8String stringDateTime = new UTF8String("DateTime"); + + static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String name) { + var tr = tdr as TypeRef; + if (tr != null) { + @namespace = tr.Namespace; + name = tr.Name; + return true; + } + + var td = tdr as TypeDef; + if (td != null) { + @namespace = td.Namespace; + name = td.Name; + return true; + } + + @namespace = null; + name = null; + return false; + } + + ITypeDefOrRef ReadTypeDefOrRef() { + uint codedToken; + if (!reader.ReadCompressedUInt32(out codedToken)) + return null; + ISignatureReaderHelper helper = module; + return helper.ResolveTypeDefOrRef(codedToken, gpContext); + } + + string ReadString() { + if (reader.Position == reader.Length) + return string.Empty; + byte b = reader.ReadByte(); + if (b == 0xFF) + return null; + reader.Position--; + return Encoding.Unicode.GetString(reader.ReadRemainingBytes()); + } + } +} diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs new file mode 100644 index 000000000..89357a295 --- /dev/null +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -0,0 +1,334 @@ +// dnlib: See LICENSE.txt for more info + +// https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using dnlib.DotNet.Emit; +using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb.Symbols; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Portable { + sealed class PortablePdbReader : SymbolReader { + readonly IMetaData moduleMetaData; + readonly IMetaData pdbMetaData; + readonly ReadOnlyCollection documents; + + readonly Guid pdbId; + readonly uint timestamp; + readonly uint entryPointToken; + + public override int UserEntryPoint { + get { return (int)entryPointToken; } + } + + public override ReadOnlyCollection Documents { + get { return documents; } + } + + public PortablePdbReader(IMetaData moduleMetaData, IImageStream pdbStream) { + this.moduleMetaData = moduleMetaData; + pdbMetaData = MetaDataCreator.Create(pdbStream, true); + var pdbHeap = GetPdbStream(pdbMetaData.AllStreams); + Debug.Assert(pdbHeap != null); + if (pdbHeap != null) { + using (var stream = pdbHeap.GetClonedImageStream()) { + pdbId = new Guid(stream.ReadBytes(16)); + timestamp = stream.ReadUInt32(); + entryPointToken = stream.ReadUInt32(); + } + } + + documents = ReadDocuments(); + } + + static DotNetStream GetPdbStream(IList streams) { + foreach (var stream in streams) { + if (stream.Name == "#Pdb") + return stream; + } + return null; + } + + static Guid GetLanguageVendor(Guid language) { + if (language == Constants.LanguageCSharp || language == Constants.LanguageVisualBasic || language == Constants.LanguageFSharp) + return Constants.LanguageVendorMicrosoft; + return Guid.Empty; + } + + ReadOnlyCollection ReadDocuments() { + var docTbl = pdbMetaData.TablesStream.DocumentTable; + var docs = new SymbolDocument[docTbl.Rows]; + var nameReader = new DocumentNameReader(pdbMetaData.BlobStream); + for (int i = 0; i < docs.Length; i++) { + uint nameOffset, hashAlgorithmIndex, hashOffset; + uint languageIndex = pdbMetaData.TablesStream.ReadDocumentRow2((uint)i + 1, out nameOffset, out hashAlgorithmIndex, out hashOffset); + var url = nameReader.ReadDocumentName(nameOffset); + var language = pdbMetaData.GuidStream.Read(languageIndex) ?? Guid.Empty; + var languageVendor = GetLanguageVendor(language); + var documentType = Constants.DocumentTypeText; + var checkSumAlgorithmId = pdbMetaData.GuidStream.Read(hashAlgorithmIndex) ?? Guid.Empty; + var checkSum = pdbMetaData.BlobStream.ReadNoNull(hashOffset); + docs[i] = new SymbolDocumentImpl(url, language, languageVendor, documentType, checkSumAlgorithmId, checkSum); + } + return new ReadOnlyCollection(docs); + } + + bool TryGetSymbolDocument(uint rid, out SymbolDocument document) { + int index = (int)rid - 1; + if ((uint)index >= (uint)documents.Count) { + Debug.Fail("Couldn't find document with rid 0x" + rid.ToString("X6")); + document = null; + return false; + } + document = documents[index]; + return true; + } + + public override SymbolMethod GetMethod(ModuleDef module, int method, int version) { + if (((uint)method >> MDToken.TABLE_SHIFT) != (uint)Table.Method) + return null; + var mdTable = pdbMetaData.TablesStream.MethodDebugInformationTable; + uint methodRid = (uint)method & MDToken.RID_MASK; + if (!mdTable.IsValidRID(methodRid)) + return null; + + var sequencePoints = ReadSequencePoints(methodRid) ?? emptySymbolSequencePoints; + var rootScope = ReadScope(module, methodRid); + + bool isAsyncMethod = false;//TODO: + int kickoffMethod = 0;//TODO: + uint? catchHandlerILOffset = null;//TODO: + var asyncStepInfos = new ReadOnlyCollection(new SymbolAsyncStepInfo[0]);//TODO: + var symbolMethod = new SymbolMethodImpl(method, rootScope, sequencePoints, isAsyncMethod, kickoffMethod, catchHandlerILOffset, asyncStepInfos); + rootScope.method = symbolMethod; + return symbolMethod; + } + + ReadOnlyCollection ReadSequencePoints(uint methodRid) { + uint documentRid; + uint sequencePointsOffset = pdbMetaData.TablesStream.ReadMethodDebugInformationRow2(methodRid, out documentRid); + if (sequencePointsOffset == 0) + return null; + + var seqPointsBuilder = ListCache.AllocList(); + using (var seqPointsStream = pdbMetaData.BlobStream.CreateStream(sequencePointsOffset)) { + uint localSig = seqPointsStream.ReadCompressedUInt32(); + if (documentRid == 0) + documentRid = seqPointsStream.ReadCompressedUInt32(); + + SymbolDocument document; + TryGetSymbolDocument(documentRid, out document); + + uint ilOffset = uint.MaxValue; + int line = -1, column = 0; + bool canReadDocumentRecord = false; + while (seqPointsStream.Position < seqPointsStream.Length) { + uint data = seqPointsStream.ReadCompressedUInt32(); + if (data == 0 && canReadDocumentRecord) { + // document-record + + documentRid = seqPointsStream.ReadCompressedUInt32(); + TryGetSymbolDocument(documentRid, out document); + } + else { + // SequencePointRecord + + Debug.Assert(document != null); + if (document == null) + return null; + + var symSeqPoint = new SymbolSequencePoint { + Document = document, + }; + + if (ilOffset == uint.MaxValue) + ilOffset = data; + else { + Debug.Assert(data != 0); + if (data == 0) + return null; + ilOffset += data; + } + symSeqPoint.Offset = (int)ilOffset; + + uint dlines = seqPointsStream.ReadCompressedUInt32(); + int dcolumns = dlines == 0 ? (int)seqPointsStream.ReadCompressedUInt32() : seqPointsStream.ReadCompressedInt32(); + + if (dlines == 0 && dcolumns == 0) { + // hidden-sequence-point-record + + const int HIDDEN_LINE = 0xFEEFEE; + const int HIDDEN_COLUMN = 0; + symSeqPoint.Line = HIDDEN_LINE; + symSeqPoint.EndLine = HIDDEN_LINE; + symSeqPoint.Column = HIDDEN_COLUMN; + symSeqPoint.EndColumn = HIDDEN_COLUMN; + } + else { + // sequence-point-record + + if (line < 0) { + line = (int)seqPointsStream.ReadCompressedUInt32(); + column = (int)seqPointsStream.ReadCompressedUInt32(); + } + else { + line += seqPointsStream.ReadCompressedInt32(); + column += seqPointsStream.ReadCompressedInt32(); + } + + symSeqPoint.Line = line; + symSeqPoint.EndLine = line + (int)dlines; + symSeqPoint.Column = column; + symSeqPoint.EndColumn = column + dcolumns; + } + + seqPointsBuilder.Add(symSeqPoint); + } + + canReadDocumentRecord = true; + } + Debug.Assert(seqPointsStream.Position == seqPointsStream.Length); + } + + return new ReadOnlyCollection(ListCache.FreeAndToArray(ref seqPointsBuilder)); + } + static readonly ReadOnlyCollection emptySymbolSequencePoints = new ReadOnlyCollection(new SymbolSequencePoint[0]); + + SymbolScopeImpl ReadScope(ModuleDef module, uint methodRid) { + var scopesRidList = pdbMetaData.GetLocalScopeRidList(methodRid); + SymbolScopeImpl rootScopeOrNull = null; + if (scopesRidList.Count != 0) { + var stack = ListCache.AllocList(); + var importScopeBlobReader = new ImportScopeBlobReader(module, pdbMetaData.BlobStream); + for (int i = 0; i < scopesRidList.Count; i++) { + var rid = scopesRidList[i]; + uint importScope, variableList, constantList, startOffset; + uint length = pdbMetaData.TablesStream.ReadLocalScopeRow2(rid, out importScope, out variableList, out constantList, out startOffset); + uint endOffset = startOffset + length; + + SymbolScopeImpl parent = null; + while (stack.Count > 0) { + var nextParent = stack[stack.Count - 1]; + if (startOffset >= nextParent.StartOffset && endOffset <= nextParent.EndOffset) { + parent = nextParent; + break; + } + stack.RemoveAt(stack.Count - 1); + } + + Debug.Assert(parent != null || rootScopeOrNull == null); + var scope = new SymbolScopeImpl(parent, (int)startOffset, (int)endOffset); + if (rootScopeOrNull == null) + rootScopeOrNull = scope; + stack.Add(scope); + if (parent != null) + parent.childrenList.Add(scope); + + scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, importScope); + uint variableListEnd, constantListEnd; + GetEndOfLists(rid, out variableListEnd, out constantListEnd); + ReadVariables(scope, variableList, variableListEnd); + ReadConstants(scope, constantList, constantListEnd); + } + + ListCache.Free(ref stack); + } + return rootScopeOrNull ?? new SymbolScopeImpl(null, 0, int.MaxValue); + } + + void GetEndOfLists(uint scopeRid, out uint variableListEnd, out uint constantListEnd) { + var localScopeTable = pdbMetaData.TablesStream.LocalScopeTable; + var nextRid = scopeRid + 1; + if (!localScopeTable.IsValidRID(nextRid)) { + variableListEnd = pdbMetaData.TablesStream.LocalVariableTable.Rows + 1; + constantListEnd = pdbMetaData.TablesStream.LocalConstantTable.Rows + 1; + } + else { + uint nextImportScope, nextVariableList, nextConstantList, nextStartOffset; + pdbMetaData.TablesStream.ReadLocalScopeRow2(nextRid, out nextImportScope, out nextVariableList, out nextConstantList, out nextStartOffset); + variableListEnd = nextVariableList; + constantListEnd = nextConstantList; + } + } + + PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope) { + if (importScope == 0) + return null; + const int MAX = 1000; + PdbImportScope result = null; + PdbImportScope prevScope = null; + for (int i = 0; importScope != 0; i++) { + Debug.Assert(i < MAX); + if (i >= MAX) + return null; + uint imports = pdbMetaData.TablesStream.ReadImportScopeRow2(importScope, out importScope); + var scope = new PdbImportScope(); + if (result == null) + result = scope; + if (prevScope != null) + prevScope.Parent = scope; + importScopeBlobReader.Read(imports, scope.Imports); + prevScope = scope; + } + + return result; + } + + void ReadVariables(SymbolScopeImpl scope, uint variableList, uint variableListEnd) { + if (variableList == 0) + return; + Debug.Assert(variableList <= variableListEnd); + if (variableList >= variableListEnd) + return; + var table = pdbMetaData.TablesStream.LocalVariableTable; + Debug.Assert(table.IsValidRID(variableListEnd - 1)); + if (!table.IsValidRID(variableListEnd - 1)) + return; + Debug.Assert(table.IsValidRID(variableList)); + if (!table.IsValidRID(variableList)) + return; + for (uint rid = variableList; rid < variableListEnd; rid++) { + ushort attributes, index; + var nameOffset = pdbMetaData.TablesStream.ReadLocalVariableRow2(rid, out attributes, out index); + var name = pdbMetaData.StringsStream.Read(nameOffset); + scope.localsList.Add(new SymbolVariableImpl(name, ToSymbolVariableAttributes(attributes), index)); + } + } + + static SymbolVariableAttributes ToSymbolVariableAttributes(ushort attributes) { + var res = SymbolVariableAttributes.None; + const ushort DebuggerHidden = 0x0001; + if ((attributes & DebuggerHidden) != 0) + res |= SymbolVariableAttributes.CompilerGenerated; + return res; + } + + void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEnd) { + if (constantList == 0) + return; + Debug.Assert(constantList <= constantListEnd); + if (constantList >= constantListEnd) + return; + var table = pdbMetaData.TablesStream.LocalConstantTable; + Debug.Assert(table.IsValidRID(constantListEnd - 1)); + if (!table.IsValidRID(constantListEnd - 1)) + return; + Debug.Assert(table.IsValidRID(constantList)); + if (!table.IsValidRID(constantList)) + return; + scope.SetConstants(pdbMetaData, constantList, constantListEnd); + } + + public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + //TODO: CustomDebugInformation table + } + + public override void Dispose() { + pdbMetaData.Dispose(); + } + } +} diff --git a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs new file mode 100644 index 000000000..3957dcb31 --- /dev/null +++ b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs @@ -0,0 +1,73 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Diagnostics; +using System.Text; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Portable { + [DebuggerDisplay("{GetDebuggerString(),nq}")] + sealed class SymbolDocumentImpl : SymbolDocument { + readonly string url; + /*readonly*/ Guid language; + /*readonly*/ Guid languageVendor; + /*readonly*/ Guid documentType; + /*readonly*/ Guid checkSumAlgorithmId; + readonly byte[] checkSum; + + string GetDebuggerString() { + var sb = new StringBuilder(); + if (language == Constants.LanguageCSharp) + sb.Append("C#"); + else if (language == Constants.LanguageVisualBasic) + sb.Append("VB"); + else if (language == Constants.LanguageFSharp) + sb.Append("F#"); + else + sb.Append(language.ToString()); + sb.Append(", "); + if (checkSumAlgorithmId == Constants.HashSHA1) + sb.Append("SHA-1"); + else if (checkSumAlgorithmId == Constants.HashSHA256) + sb.Append("SHA-256"); + else + sb.Append(checkSumAlgorithmId.ToString()); + sb.Append(": "); + sb.Append(url); + return sb.ToString(); + } + + public override string URL { + get { return url; } + } + + public override Guid Language { + get { return language; } + } + + public override Guid LanguageVendor { + get { return languageVendor; } + } + + public override Guid DocumentType { + get { return documentType; } + } + + public override Guid CheckSumAlgorithmId { + get { return checkSumAlgorithmId; } + } + + public override byte[] CheckSum { + get { return checkSum; } + } + + public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum) { + this.url = url; + this.language = language; + this.languageVendor = languageVendor; + this.documentType = documentType; + this.checkSumAlgorithmId = checkSumAlgorithmId; + this.checkSum = checkSum; + } + } +} diff --git a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs new file mode 100644 index 000000000..04a2f0b24 --- /dev/null +++ b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs @@ -0,0 +1,54 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.ObjectModel; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Portable { + sealed class SymbolMethodImpl : SymbolMethod { + readonly int token; + readonly SymbolScope rootScope; + readonly ReadOnlyCollection sequencePoints; + readonly bool isAsyncMethod; + readonly int kickoffMethod; + readonly uint? catchHandlerILOffset; + readonly ReadOnlyCollection asyncStepInfos; + + public override int Token { + get { return token; } + } + + public override SymbolScope RootScope { + get { return rootScope; } + } + + public override ReadOnlyCollection SequencePoints { + get { return sequencePoints; } + } + + public override bool IsAsyncMethod { + get { return isAsyncMethod; } + } + + public override int KickoffMethod { + get { return kickoffMethod; } + } + + public override uint? CatchHandlerILOffset { + get { return catchHandlerILOffset; } + } + + public override ReadOnlyCollection AsyncStepInfos { + get { return asyncStepInfos; } + } + + public SymbolMethodImpl(int token, SymbolScope rootScope, ReadOnlyCollection sequencePoints, bool isAsyncMethod, int kickoffMethod, uint? catchHandlerILOffset, ReadOnlyCollection asyncStepInfos) { + this.token = token; + this.rootScope = rootScope; + this.sequencePoints = sequencePoints; + this.isAsyncMethod = isAsyncMethod; + this.kickoffMethod = kickoffMethod; + this.catchHandlerILOffset = catchHandlerILOffset; + this.asyncStepInfos = asyncStepInfos; + } + } +} diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index a3e17eb10..11483ecfd 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -8,23 +8,19 @@ namespace dnlib.DotNet.Pdb.Portable { static class SymbolReaderCreator { public static SymbolReader TryCreate(IMetaData metaData, IImageStream pdbStream) { - if (metaData == null) - return null; - if (pdbStream == null) - return null; try { - pdbStream.Position = 0; - if (pdbStream.ReadUInt32() != 0x424A5342) - return null; - pdbStream.Position = 0; - return null;//TODO: + if (metaData != null && pdbStream != null) { + pdbStream.Position = 0; + if (pdbStream.ReadUInt32() == 0x424A5342) { + pdbStream.Position = 0; + return new PortablePdbReader(metaData, pdbStream); + } + } } catch (IOException) { } - finally { - if (pdbStream != null) - pdbStream.Dispose(); - } + if (pdbStream != null) + pdbStream.Dispose(); return null; } diff --git a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs new file mode 100644 index 000000000..8196e62df --- /dev/null +++ b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs @@ -0,0 +1,116 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Portable { + sealed class SymbolScopeImpl : SymbolScope { + internal SymbolMethod method; + readonly SymbolScopeImpl parent; + readonly int startOffset; + readonly int endOffset; + readonly ReadOnlyCollection children; + readonly ReadOnlyCollection locals; + internal readonly List childrenList; + internal readonly List localsList; + internal PdbImportScope importScope; + + public override SymbolMethod Method { + get { + if (method != null) + return method; + var p = parent; + if (p == null) + return method; + for (;;) { + if (p.parent == null) + return method = p.method; + p = p.parent; + } + } + } + + public override SymbolScope Parent { + get { return parent; } + } + + public override int StartOffset { + get { return startOffset; } + } + + public override int EndOffset { + get { return endOffset; } + } + + public override ReadOnlyCollection Children { + get { return children; } + } + + public override ReadOnlyCollection Locals { + get { return locals; } + } + + public override ReadOnlyCollection Namespaces { + get { return emptySymbolNamespaces; } + } + static readonly ReadOnlyCollection emptySymbolNamespaces = new ReadOnlyCollection(new SymbolNamespace[0]); + + public override PdbImportScope ImportScope { + get { return importScope; } + } + + public SymbolScopeImpl(SymbolScopeImpl parent, int startOffset, int endOffset) { + method = null; + this.parent = parent; + this.startOffset = startOffset; + this.endOffset = endOffset; + childrenList = new List(); + localsList = new List(); + children = new ReadOnlyCollection(childrenList); + locals = new ReadOnlyCollection(localsList); + } + + IMetaData constantsMetaData; + uint constantList; + uint constantListEnd; + + internal void SetConstants(IMetaData metaData, uint constantList, uint constantListEnd) { + constantsMetaData = metaData; + this.constantList = constantList; + this.constantListEnd = constantListEnd; + } + + public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext) { + if (constantList >= constantListEnd) + return emptyPdbConstants; + Debug.Assert(constantsMetaData != null); + + var res = new PdbConstant[constantListEnd - constantList]; + int w = 0; + for (int i = 0; i < res.Length; i++) { + uint rid = constantList + (uint)i; + uint nameOffset; + uint signature = constantsMetaData.TablesStream.ReadLocalConstantRow2(rid, out nameOffset); + var name = constantsMetaData.StringsStream.Read(nameOffset); + using (var stream = constantsMetaData.BlobStream.CreateStream(signature)) { + var localConstantSigBlobReader = new LocalConstantSigBlobReader(module, stream, gpContext); + TypeSig type; + object value; + bool b = localConstantSigBlobReader.Read(out type, out value); + Debug.Assert(b); + if (b) + res[w++] = new PdbConstant(name, type, value); + Debug.Assert(stream.Position == stream.Length); + } + } + if (res.Length != w) + Array.Resize(ref res, w); + return res; + } + static readonly PdbConstant[] emptyPdbConstants = new PdbConstant[0]; + } +} diff --git a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs new file mode 100644 index 000000000..4b67cdf47 --- /dev/null +++ b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs @@ -0,0 +1,29 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.Portable { + sealed class SymbolVariableImpl : SymbolVariable { + readonly string name; + readonly SymbolVariableAttributes attributes; + readonly int index; + + public override string Name { + get { return name; } + } + + public override SymbolVariableAttributes Attributes { + get { return attributes; } + } + + public override int Index { + get { return index; } + } + + public SymbolVariableImpl(string name, SymbolVariableAttributes attributes, int index) { + this.name = name; + this.attributes = attributes; + this.index = index; + } + } +} diff --git a/src/DotNet/Pdb/Symbols/SymbolScope.cs b/src/DotNet/Pdb/Symbols/SymbolScope.cs index 91a572511..cc70ea1a7 100644 --- a/src/DotNet/Pdb/Symbols/SymbolScope.cs +++ b/src/DotNet/Pdb/Symbols/SymbolScope.cs @@ -42,12 +42,17 @@ public abstract class SymbolScope { /// public abstract ReadOnlyCollection Namespaces { get; } + /// + /// Gets the import scope or null if none + /// + public abstract PdbImportScope ImportScope { get; } + /// /// Gets all the constants /// /// Owner module if a signature must be read from the #Blob /// Generic parameter context /// - public abstract PdbConstant[] GetConstants(ModuleDefMD module, GenericParamContext gpContext); + public abstract PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext); } } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 69fc7e42a..592e8427c 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -186,8 +186,19 @@ + + + + + + + + + + + From 3f6a2dc0843904ebd652b22ae31654e0ee8764f4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 5 Nov 2017 21:43:08 +0100 Subject: [PATCH 051/511] Add iterator method info --- src/DotNet/MD/IMetaData.cs | 7 ++++ src/DotNet/MD/MetaData.cs | 5 +++ src/DotNet/MD/TablesStream_Read.cs | 14 ++++++++ src/DotNet/ModuleDefMD.cs | 9 +++-- src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 23 ++++++------ src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 4 +-- src/DotNet/Pdb/Managed/DbiFunction.cs | 22 +++++------- src/DotNet/Pdb/Managed/PdbReader.cs | 4 +-- src/DotNet/Pdb/PdbIteratorMethod.cs | 19 ++++++++++ src/DotNet/Pdb/PdbMethod.cs | 5 +++ src/DotNet/Pdb/PdbState.cs | 36 +++++++++---------- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 38 +++++++++++++++----- src/DotNet/Pdb/Portable/SymbolMethodImpl.cs | 26 +++++++------- src/DotNet/Pdb/Symbols/SymbolMethod.cs | 22 +++++++++--- src/DotNet/Pdb/Symbols/SymbolReader.cs | 4 +-- src/dnlib.csproj | 1 + 16 files changed, 157 insertions(+), 82 deletions(-) create mode 100644 src/DotNet/Pdb/PdbIteratorMethod.cs diff --git a/src/DotNet/MD/IMetaData.cs b/src/DotNet/MD/IMetaData.cs index 0412d3479..b0b1b7dc4 100644 --- a/src/DotNet/MD/IMetaData.cs +++ b/src/DotNet/MD/IMetaData.cs @@ -332,5 +332,12 @@ public interface IMetaData : IDisposable { /// Owner Method rid /// A instance containing the valid LocalScope rids RidList GetLocalScopeRidList(uint methodRid); + + /// + /// Gets the StateMachineMethod rid or 0 if it's not a state machine method + /// + /// Owner Method rid + /// + uint GetStateMachineMethodRid(uint methodRid); } } diff --git a/src/DotNet/MD/MetaData.cs b/src/DotNet/MD/MetaData.cs index be239bcba..b68e7ca54 100644 --- a/src/DotNet/MD/MetaData.cs +++ b/src/DotNet/MD/MetaData.cs @@ -829,6 +829,11 @@ public RidList GetLocalScopeRidList(uint methodRid) { return FindAllRows(tablesStream.LocalScopeTable, 0, methodRid); } + public uint GetStateMachineMethodRid(uint methodRid) { + var list = FindAllRows(tablesStream.StateMachineMethodTable, 0, methodRid); + return list.Length == 0 ? 0 : list[0]; + } + /// public void Dispose() { Dispose(true); diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index 7f1db069c..b2ec924f6 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -1781,6 +1781,20 @@ internal uint ReadLocalConstantRow2(uint rid, out uint name) { #endif } + internal uint ReadStateMachineMethodRow2(uint rid) { + var table = StateMachineMethodTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + reader.Position += columns[0].Size; + return columns[1].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + /// /// Reads a column /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index b03da243f..4e29f55dc 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1856,7 +1856,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out mb)) { var cilBody = mb as CilBody; if (cilBody != null) - return InitializeBodyFromPdb(method, cilBody, method.OrigRid); + return InitializeBodyFromPdb(method, cilBody); return mb; } @@ -1864,7 +1864,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib return null; var codeType = implAttrs & MethodImplAttributes.CodeTypeMask; if (codeType == MethodImplAttributes.IL) - return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext), method.OrigRid); + return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext)); if (codeType == MethodImplAttributes.Native) return new NativeMethodBody(rva); return null; @@ -1875,12 +1875,11 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// /// Owner method /// Method body - /// Method rid /// Returns originak value - CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body, uint rid) { + CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body) { var ps = pdbState; if (ps != null) - ps.InitializeMethodBody(this, method, body, rid); + ps.InitializeMethodBody(this, method, body); return body; } diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index 4beec1f4b..7faa5a460 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -72,24 +72,22 @@ public override ReadOnlyCollection SequencePoints { } volatile ReadOnlyCollection sequencePoints; - public override bool IsAsyncMethod { - get { return asyncMethod != null && asyncMethod.IsAsyncMethod(); } + public override int IteratorKickoffMethod { + get { return 0; } } - public override int KickoffMethod { + public override int AsyncKickoffMethod { get { - Debug.Assert(IsAsyncMethod); - if (asyncMethod == null) - throw new InvalidOperationException(); + if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) + return 0; return (int)asyncMethod.GetKickoffMethod(); } } - public override uint? CatchHandlerILOffset { + public override uint? AsyncCatchHandlerILOffset { get { - Debug.Assert(IsAsyncMethod); - if (asyncMethod == null) - throw new InvalidOperationException(); + if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) + return null; if (!asyncMethod.HasCatchHandlerILOffset()) return null; return asyncMethod.GetCatchHandlerILOffset(); @@ -98,10 +96,9 @@ public override uint? CatchHandlerILOffset { public override ReadOnlyCollection AsyncStepInfos { get { + if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) + return null; if (asyncStepInfos == null) { - Debug.Assert(IsAsyncMethod); - if (asyncMethod == null) - throw new InvalidOperationException(); var stepInfoCount = asyncMethod.GetAsyncStepInfoCount(); var yieldOffsets = new uint[stepInfoCount]; var breakpointOffsets = new uint[stepInfoCount]; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index a7e898c07..823b4f4af 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -53,9 +53,9 @@ public override ReadOnlyCollection Documents { } volatile ReadOnlyCollection documents; - public override SymbolMethod GetMethod(ModuleDef module, int method, int version) { + public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version) { ISymUnmanagedMethod unMethod; - int hr = reader.GetMethodByVersion((uint)method, version, out unMethod); + int hr = reader.GetMethodByVersion(method.MDToken.Raw, version, out unMethod); if (hr == E_FAIL) return null; Marshal.ThrowExceptionForHR(hr); diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index 9cb30acda..f590e80a3 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -71,30 +71,25 @@ public override ReadOnlyCollection SequencePoints { } ReadOnlyCollection sequencePoints; - const string asyncMethodInfoAttributeName = "asyncMethodInfo"; - public override bool IsAsyncMethod { - get { - var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - return data != null && data.Length >= 0x0C; - } + public override int IteratorKickoffMethod { + get { return 0; } } - public override int KickoffMethod { + const string asyncMethodInfoAttributeName = "asyncMethodInfo"; + public override int AsyncKickoffMethod { get { - Debug.Assert(IsAsyncMethod); var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) - throw new InvalidOperationException(); + return 0; return BitConverter.ToInt32(data, 0); } } - public override uint? CatchHandlerILOffset { + public override uint? AsyncCatchHandlerILOffset { get { - Debug.Assert(IsAsyncMethod); var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) - throw new InvalidOperationException(); + return null; uint token = BitConverter.ToUInt32(data, 4); return token == uint.MaxValue ? (uint?)null : token; } @@ -110,10 +105,9 @@ public override ReadOnlyCollection AsyncStepInfos { volatile ReadOnlyCollection asyncStepInfos; SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { - Debug.Assert(IsAsyncMethod); var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) - throw new InvalidOperationException(); + return emptySymbolAsyncStepInfos; int pos = 8; int count = BitConverter.ToInt32(data, pos); pos += 4; diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 4f0b807a5..31eaee0ff 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -318,9 +318,9 @@ internal static string ReadCString(IImageStream stream) { return value; } - public override SymbolMethod GetMethod(ModuleDef module, int method, int version) { + public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version) { DbiFunction symMethod; - if (functions.TryGetValue(method, out symMethod)) + if (functions.TryGetValue(method.MDToken.ToInt32(), out symMethod)) return symMethod; return null; } diff --git a/src/DotNet/Pdb/PdbIteratorMethod.cs b/src/DotNet/Pdb/PdbIteratorMethod.cs new file mode 100644 index 000000000..1c2c41840 --- /dev/null +++ b/src/DotNet/Pdb/PdbIteratorMethod.cs @@ -0,0 +1,19 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb { + /// + /// Iterator method info + /// + public sealed class PdbIteratorMethod { + /// + /// Gets/sets the kickoff method + /// + public MethodDef KickoffMethod { get; set; } + + /// + /// Constructor + /// + public PdbIteratorMethod() { + } + } +} diff --git a/src/DotNet/Pdb/PdbMethod.cs b/src/DotNet/Pdb/PdbMethod.cs index 5391d713c..f4c8c3e39 100644 --- a/src/DotNet/Pdb/PdbMethod.cs +++ b/src/DotNet/Pdb/PdbMethod.cs @@ -25,6 +25,11 @@ public sealed class PdbMethod { /// public PdbAsyncMethod AsyncMethod { get; set; } + /// + /// Gets/sets the iterator method info or null if there's none + /// + public PdbIteratorMethod IteratorMethod { get; set; } + /// /// Gets all custom debug infos /// diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 98a69c619..e73fe9e69 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -181,36 +181,22 @@ public List RemoveAllDocuments(bool returnDocs) { #endif } - /// - /// Initializes a with information found in the PDB file. The - /// instructions in must have valid offsets. This method is - /// automatically called by and you don't need to explicitly call - /// it. - /// - /// Method body - /// Method row ID - [Obsolete("Don't use this method, the body gets initialied by dnlib", true)] - public void InitializeDontCall(CilBody body, uint methodRid) { - InitializeMethodBody(null, null, body, methodRid); - } - internal Compiler GetCompiler(ModuleDef module) { if (compiler == Compiler.Unknown) compiler = CalculateCompiler(module); return compiler; } - internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, uint methodRid) { + internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { Debug.Assert((module == null) == (ownerMethod == null)); if (reader == null || body == null) return; - var token = (int)(0x06000000 + methodRid); SymbolMethod method; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - method = reader.GetMethod(module, token, 1); + method = reader.GetMethod(module, ownerMethod, 1); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, ownerMethod == null ? new GenericParamContext() : GenericParamContext.Create(ownerMethod), body, method.RootScope); @@ -218,6 +204,8 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci if (module != null && method.IsAsyncMethod) pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method); + if (module != null && method.IsIteratorMethod) + pdbMethod.IteratorMethod = CreateIteratorMethod(module, ownerMethod, body, method); if (ownerMethod != null) { // Read the custom debug info last so eg. local names have been initialized @@ -251,7 +239,7 @@ Compiler CalculateCompiler(ModuleDef module) { static readonly UTF8String nameAssemblyVisualBasic = new UTF8String("Microsoft.VisualBasic"); PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { - var kickoffToken = new MDToken(symMethod.KickoffMethod); + var kickoffToken = new MDToken(symMethod.AsyncKickoffMethod); if (kickoffToken.Table != MD.Table.Method) return null; var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); @@ -261,7 +249,7 @@ PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody b var asyncMethod = new PdbAsyncMethod(asyncStepInfos.Count); asyncMethod.KickoffMethod = kickoffMethod; - var catchHandlerILOffset = symMethod.CatchHandlerILOffset; + var catchHandlerILOffset = symMethod.AsyncCatchHandlerILOffset; if (catchHandlerILOffset != null) { asyncMethod.CatchHandlerInstruction = GetInstruction(body, catchHandlerILOffset.Value); Debug.Assert(asyncMethod.CatchHandlerInstruction != null); @@ -299,6 +287,18 @@ PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody b return asyncMethod; } + PdbIteratorMethod CreateIteratorMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { + var kickoffToken = new MDToken(symMethod.IteratorKickoffMethod); + if (kickoffToken.Table != MD.Table.Method) + return null; + + var iteratorMethod = new PdbIteratorMethod(); + + iteratorMethod.KickoffMethod = module.ResolveMethod(kickoffToken.Rid); + + return iteratorMethod; + } + Instruction GetInstruction(CilBody body, uint offset) { if (body == null) return null; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 89357a295..d3f3b0d07 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -88,25 +88,45 @@ bool TryGetSymbolDocument(uint rid, out SymbolDocument document) { return true; } - public override SymbolMethod GetMethod(ModuleDef module, int method, int version) { - if (((uint)method >> MDToken.TABLE_SHIFT) != (uint)Table.Method) - return null; + public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version) { var mdTable = pdbMetaData.TablesStream.MethodDebugInformationTable; - uint methodRid = (uint)method & MDToken.RID_MASK; + uint methodRid = method.Rid; if (!mdTable.IsValidRID(methodRid)) return null; var sequencePoints = ReadSequencePoints(methodRid) ?? emptySymbolSequencePoints; var rootScope = ReadScope(module, methodRid); - bool isAsyncMethod = false;//TODO: - int kickoffMethod = 0;//TODO: - uint? catchHandlerILOffset = null;//TODO: - var asyncStepInfos = new ReadOnlyCollection(new SymbolAsyncStepInfo[0]);//TODO: - var symbolMethod = new SymbolMethodImpl(method, rootScope, sequencePoints, isAsyncMethod, kickoffMethod, catchHandlerILOffset, asyncStepInfos); + var kickoffMethod = GetKickoffMethod(methodRid); + bool isAsyncMethod = kickoffMethod != 0 && IsAsyncMethod(method); + bool isIteratorMethod = kickoffMethod != 0 && !isAsyncMethod; + int iteratorKickoffMethod = isIteratorMethod ? kickoffMethod : 0; + int asyncKickoffMethod = isAsyncMethod ? kickoffMethod : 0; + uint? asyncCatchHandlerILOffset = null; + var asyncStepInfos = emptySymbolAsyncStepInfos; + var symbolMethod = new SymbolMethodImpl(method.MDToken.ToInt32(), rootScope, sequencePoints, iteratorKickoffMethod, asyncKickoffMethod, asyncCatchHandlerILOffset, asyncStepInfos); rootScope.method = symbolMethod; return symbolMethod; } + static readonly ReadOnlyCollection emptySymbolAsyncStepInfos = new ReadOnlyCollection(new SymbolAsyncStepInfo[0]); + + static bool IsAsyncMethod(MethodDef method) { + foreach (var iface in method.DeclaringType.Interfaces) { + if (iface.Interface.Name != stringIAsyncStateMachine) + continue; + if (iface.Interface.FullName == "System.Runtime.CompilerServices.IAsyncStateMachine") + return true; + } + return false; + } + static readonly UTF8String stringIAsyncStateMachine = new UTF8String("IAsyncStateMachine"); + + int GetKickoffMethod(uint methodRid) { + uint rid = pdbMetaData.GetStateMachineMethodRid(methodRid); + if (rid == 0) + return 0; + return 0x06000000 + (int)pdbMetaData.TablesStream.ReadStateMachineMethodRow2(rid); + } ReadOnlyCollection ReadSequencePoints(uint methodRid) { uint documentRid; diff --git a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs index 04a2f0b24..9d32b2c68 100644 --- a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs @@ -8,9 +8,9 @@ sealed class SymbolMethodImpl : SymbolMethod { readonly int token; readonly SymbolScope rootScope; readonly ReadOnlyCollection sequencePoints; - readonly bool isAsyncMethod; - readonly int kickoffMethod; - readonly uint? catchHandlerILOffset; + readonly int iteratorKickoffMethod; + readonly int asyncKickoffMethod; + readonly uint? asyncCatchHandlerILOffset; readonly ReadOnlyCollection asyncStepInfos; public override int Token { @@ -25,29 +25,29 @@ public override ReadOnlyCollection SequencePoints { get { return sequencePoints; } } - public override bool IsAsyncMethod { - get { return isAsyncMethod; } + public override int IteratorKickoffMethod { + get { return iteratorKickoffMethod; } } - public override int KickoffMethod { - get { return kickoffMethod; } + public override int AsyncKickoffMethod { + get { return asyncKickoffMethod; } } - public override uint? CatchHandlerILOffset { - get { return catchHandlerILOffset; } + public override uint? AsyncCatchHandlerILOffset { + get { return asyncCatchHandlerILOffset; } } public override ReadOnlyCollection AsyncStepInfos { get { return asyncStepInfos; } } - public SymbolMethodImpl(int token, SymbolScope rootScope, ReadOnlyCollection sequencePoints, bool isAsyncMethod, int kickoffMethod, uint? catchHandlerILOffset, ReadOnlyCollection asyncStepInfos) { + public SymbolMethodImpl(int token, SymbolScope rootScope, ReadOnlyCollection sequencePoints, int iteratorKickoffMethod, int asyncKickoffMethod, uint? asyncCatchHandlerILOffset, ReadOnlyCollection asyncStepInfos) { this.token = token; this.rootScope = rootScope; this.sequencePoints = sequencePoints; - this.isAsyncMethod = isAsyncMethod; - this.kickoffMethod = kickoffMethod; - this.catchHandlerILOffset = catchHandlerILOffset; + this.iteratorKickoffMethod = iteratorKickoffMethod; + this.asyncKickoffMethod = asyncKickoffMethod; + this.asyncCatchHandlerILOffset = asyncCatchHandlerILOffset; this.asyncStepInfos = asyncStepInfos; } } diff --git a/src/DotNet/Pdb/Symbols/SymbolMethod.cs b/src/DotNet/Pdb/Symbols/SymbolMethod.cs index a9146879a..a9a767029 100644 --- a/src/DotNet/Pdb/Symbols/SymbolMethod.cs +++ b/src/DotNet/Pdb/Symbols/SymbolMethod.cs @@ -22,20 +22,34 @@ public abstract class SymbolMethod { /// public abstract ReadOnlyCollection SequencePoints { get; } + /// + /// true if this is an iterator method + /// + public bool IsIteratorMethod { + get { return IteratorKickoffMethod != 0; } + } + + /// + /// Gets the kick off method if it's an iterator method, otherwise 0 + /// + public abstract int IteratorKickoffMethod { get; } + /// /// true if this is an async method /// - public abstract bool IsAsyncMethod { get; } + public bool IsAsyncMethod { + get { return AsyncKickoffMethod != 0; } + } /// - /// Gets the kick off method if it's an async method () + /// Gets the kick off method if it's an async method, otherwise 0 /// - public abstract int KickoffMethod { get; } + public abstract int AsyncKickoffMethod { get; } /// /// Gets the catch handler IL offset if it's an async method () /// - public abstract uint? CatchHandlerILOffset { get; } + public abstract uint? AsyncCatchHandlerILOffset { get; } /// /// Gets the async step infos if it's an async method () diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index 86023b441..12fb28642 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -24,10 +24,10 @@ public abstract class SymbolReader : IDisposable { /// Gets a method or returns null if the method doesn't exist in the PDB file /// /// Module - /// Method token + /// Method /// Edit and continue version /// - public abstract SymbolMethod GetMethod(ModuleDef module, int method, int version); + public abstract SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version); /// /// Reads custom debug info diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 592e8427c..0753c1ff5 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -187,6 +187,7 @@ + From 27ff48bc385b2cf6d4e03fcd62fb71c27a15b67c Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 6 Nov 2017 23:27:53 +0100 Subject: [PATCH 052/511] Add IHasCustomDebugInformation and CDI props --- src/DotNet/AssemblyDef.cs | 37 +++- src/DotNet/AssemblyNameInfo.cs | 18 -- src/DotNet/AssemblyRef.cs | 44 +++- src/DotNet/DeclSecurity.cs | 38 +++- src/DotNet/Emit/LocalList.cs | 24 +- src/DotNet/Emit/MethodBody.cs | 27 --- src/DotNet/EventDef.cs | 37 +++- src/DotNet/ExportedType.cs | 43 +++- src/DotNet/FieldDef.cs | 43 +++- src/DotNet/FileDef.cs | 44 +++- src/DotNet/GenericParam.cs | 37 +++- src/DotNet/GenericParamConstraint.cs | 46 +++- src/DotNet/ICodedToken.cs | 21 ++ src/DotNet/InterfaceImpl.cs | 46 +++- src/DotNet/ManifestResource.cs | 44 +++- src/DotNet/MemberRef.cs | 46 +++- src/DotNet/MethodDef.cs | 46 +++- src/DotNet/MethodSpec.cs | 46 +++- src/DotNet/ModuleDef.cs | 36 ++- src/DotNet/ModuleDefMD.cs | 19 +- src/DotNet/ModuleRef.cs | 44 +++- src/DotNet/ParamDef.cs | 43 +++- src/DotNet/Pdb/CorSymVarFlag.cs | 10 + src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 5 + src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 15 +- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 19 +- src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 27 ++- src/DotNet/Pdb/Dss/SymbolVariableImpl.cs | 14 +- src/DotNet/Pdb/Managed/DbiDocument.cs | 4 + src/DotNet/Pdb/Managed/DbiFunction.cs | 30 +-- src/DotNet/Pdb/Managed/DbiScope.cs | 26 +-- src/DotNet/Pdb/Managed/DbiVariable.cs | 15 +- src/DotNet/Pdb/Managed/PdbReader.cs | 19 +- src/DotNet/Pdb/PdbConstant.cs | 34 ++- src/DotNet/Pdb/PdbDocument.cs | 30 ++- src/DotNet/Pdb/PdbImport.cs | 20 +- src/DotNet/Pdb/PdbLocal.cs | 88 ++++++++ src/DotNet/Pdb/PdbLocalAttributes.cs | 21 ++ src/DotNet/Pdb/PdbMethod.cs | 10 - src/DotNet/Pdb/PdbScope.cs | 30 ++- src/DotNet/Pdb/PdbState.cs | 209 +++++++++--------- src/DotNet/Pdb/PdbWriter.cs | 21 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 84 ++++--- src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs | 8 +- src/DotNet/Pdb/Portable/SymbolMethodImpl.cs | 12 +- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 37 ++-- src/DotNet/Pdb/Portable/SymbolVariableImpl.cs | 12 +- src/DotNet/Pdb/Symbols/SymbolDocument.cs | 5 + src/DotNet/Pdb/Symbols/SymbolMethod.cs | 6 +- src/DotNet/Pdb/Symbols/SymbolReader.cs | 22 +- src/DotNet/Pdb/Symbols/SymbolScope.cs | 15 +- src/DotNet/Pdb/Symbols/SymbolVariable.cs | 17 +- src/DotNet/PropertyDef.cs | 37 +++- src/DotNet/StandAloneSig.cs | 46 +++- src/DotNet/TypeDef.cs | 37 +++- src/DotNet/TypeRef.cs | 43 +++- src/DotNet/TypeSpec.cs | 45 +++- src/dnlib.csproj | 3 + 58 files changed, 1542 insertions(+), 363 deletions(-) create mode 100644 src/DotNet/Pdb/CorSymVarFlag.cs create mode 100644 src/DotNet/Pdb/PdbLocal.cs create mode 100644 src/DotNet/Pdb/PdbLocalAttributes.cs diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 1b277eef9..e4778badf 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -9,6 +9,7 @@ using dnlib.DotNet.Writer; using dnlib.Threading; using System.Text.RegularExpressions; +using dnlib.DotNet.Pdb; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -20,7 +21,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the Assembly table /// - public abstract class AssemblyDef : IHasCustomAttribute, IHasDeclSecurity, IAssembly, IListListener, ITypeDefFinder, IDnlibDef { + public abstract class AssemblyDef : IHasCustomAttribute, IHasDeclSecurity, IHasCustomDebugInformation, IAssembly, IListListener, ITypeDefFinder, IDnlibDef { /// /// The row id in its table /// @@ -190,6 +191,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + + /// + public int HasCustomDebugInformationTag { + get { return 14; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } /// public bool HasDeclSecurities { get { return DeclSecurities.Count > 0; } @@ -934,6 +962,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// public override bool TryGetOriginalTargetFrameworkAttribute(out string framework, out Version version, out string profile) { if (!hasInitdTFA) diff --git a/src/DotNet/AssemblyNameInfo.cs b/src/DotNet/AssemblyNameInfo.cs index 1d1512ec5..45fbe9426 100644 --- a/src/DotNet/AssemblyNameInfo.cs +++ b/src/DotNet/AssemblyNameInfo.cs @@ -31,15 +31,6 @@ public Version Version { set { version = value; } } - /// - /// Gets/sets the - /// - [Obsolete("Use Attributes property instead", false)] - public AssemblyAttributes Flags { - get { return flags; } - set { flags = value; } - } - /// /// Gets/sets the /// @@ -64,15 +55,6 @@ public UTF8String Name { set { name = value; } } - /// - /// Gets/sets the culture or null if none specified - /// - [Obsolete("Use Culture property instead", false)] - public UTF8String Locale { - get { return Culture; } - set { Culture = value; } - } - /// /// Gets/sets the culture or null if none specified /// diff --git a/src/DotNet/AssemblyRef.cs b/src/DotNet/AssemblyRef.cs index d92379f1f..58b7aad1c 100644 --- a/src/DotNet/AssemblyRef.cs +++ b/src/DotNet/AssemblyRef.cs @@ -4,12 +4,20 @@ using System.Reflection; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the AssemblyRef table /// - public abstract class AssemblyRef : IHasCustomAttribute, IImplementation, IResolutionScope, IAssembly, IScope { + public abstract class AssemblyRef : IHasCustomAttribute, IImplementation, IResolutionScope, IHasCustomDebugInformation, IAssembly, IScope { /// /// An assembly ref that can be used to indicate that it references the current assembly /// when the current assembly is not known (eg. a type string without any assembly info @@ -151,6 +159,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 15; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// public string FullName { get { return FullNameToken; } @@ -483,6 +518,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/DeclSecurity.cs b/src/DotNet/DeclSecurity.cs index 905387062..4e75092d7 100644 --- a/src/DotNet/DeclSecurity.cs +++ b/src/DotNet/DeclSecurity.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; #if THREAD_SAFE @@ -18,7 +19,7 @@ namespace dnlib.DotNet { /// A high-level representation of a row in the DeclSecurity table /// [DebuggerDisplay("{Action} Count={SecurityAttributes.Count}")] - public abstract class DeclSecurity : IHasCustomAttribute { + public abstract class DeclSecurity : IHasCustomAttribute, IHasCustomDebugInformation { /// /// The row id in its table /// @@ -89,6 +90,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 8; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// true if is not empty /// @@ -191,6 +219,14 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + var gpContext = new GenericParamContext(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/Emit/LocalList.cs b/src/DotNet/Emit/LocalList.cs index 9290833d9..e6641ba46 100644 --- a/src/DotNet/Emit/LocalList.cs +++ b/src/DotNet/Emit/LocalList.cs @@ -1,9 +1,10 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics; using dnlib.Utils; using dnlib.Threading; +using dnlib.DotNet.Pdb; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -228,7 +229,7 @@ public sealed class Local : IVariable { TypeSig typeSig; int index; string name; - int pdbAttributes; + PdbLocalAttributes attributes; /// /// Gets/sets the type of the local @@ -247,7 +248,7 @@ public int Index { } /// - /// Gets/sets the name + /// Gets the name. This property is obsolete, use to get/set the name stored in the PDB file. /// public string Name { get { return name; } @@ -255,12 +256,19 @@ public string Name { } /// - /// Gets/sets the PDB attributes. This seems to be a CorSymVarFlag enumeration. - /// It's VAR_IS_COMP_GEN (1) if it's a compiler-generated local. + /// Gets the attributes. This property is obsolete, use to get/set the attributes stored in the PDB file. /// - public int PdbAttributes { - get { return pdbAttributes; } - set { pdbAttributes = value; } + public PdbLocalAttributes Attributes { + get { return attributes; } + set { attributes = value; } + } + + internal void SetName(string name) { + this.name = name; + } + + internal void SetAttributes(PdbLocalAttributes attributes) { + this.attributes = attributes; } /// diff --git a/src/DotNet/Emit/MethodBody.cs b/src/DotNet/Emit/MethodBody.cs index 811f5bb63..d24f5a8bc 100644 --- a/src/DotNet/Emit/MethodBody.cs +++ b/src/DotNet/Emit/MethodBody.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System; using System.Collections.Generic; using dnlib.DotNet.Pdb; using dnlib.PE; @@ -180,32 +179,6 @@ public bool HasPdbMethod { get { return PdbMethod != null; } } - /// - /// Gets/sets the PDB scope - /// - [Obsolete("Use PdbMethod.Scope property instead")] - public PdbScope Scope { - get { - var pdbMethod = this.pdbMethod; - return pdbMethod == null ? null : pdbMethod.Scope; - } - set { - var pdbMethod = this.pdbMethod; - if (pdbMethod == null && value != null) - this.pdbMethod = pdbMethod = new PdbMethod(); - if (pdbMethod != null) - pdbMethod.Scope = value; - } - } - - /// - /// true if is not null - /// - [Obsolete("Use HasPdbMethod to check if it has PDB info")] - public bool HasScope { - get { return Scope != null; } - } - /// /// Default constructor /// diff --git a/src/DotNet/EventDef.cs b/src/DotNet/EventDef.cs index 65712adba..7bc631641 100644 --- a/src/DotNet/EventDef.cs +++ b/src/DotNet/EventDef.cs @@ -3,6 +3,7 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; #if THREAD_SAFE @@ -15,7 +16,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the Event table /// - public abstract class EventDef : IHasCustomAttribute, IHasSemantic, IFullName, IMemberDef { + public abstract class EventDef : IHasCustomAttribute, IHasSemantic, IHasCustomDebugInformation, IFullName, IMemberDef { /// /// The row id in its table /// @@ -93,6 +94,33 @@ protected virtual void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); } + /// + public int HasCustomDebugInformationTag { + get { return 10; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Gets/sets the adder method /// @@ -420,6 +448,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(declaringType2), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 1c4b4a11c..54e8b7b16 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -3,13 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + namespace dnlib.DotNet { /// /// A high-level representation of a row in the ExportedType table /// - public abstract class ExportedType : IHasCustomAttribute, IImplementation, IType { + public abstract class ExportedType : IHasCustomAttribute, IImplementation, IHasCustomDebugInformation, IType { /// /// The row id in its table /// @@ -67,6 +74,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 17; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// public bool IsValueType { get { @@ -726,6 +760,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// protected override IImplementation GetImplementation_NoLock() { return readerModule.ResolveImplementation(implementationRid); diff --git a/src/DotNet/FieldDef.cs b/src/DotNet/FieldDef.cs index 4596d34f3..de899bb4b 100644 --- a/src/DotNet/FieldDef.cs +++ b/src/DotNet/FieldDef.cs @@ -3,14 +3,21 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.PE; using dnlib.Threading; +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + namespace dnlib.DotNet { /// /// A high-level representation of a row in the Field table /// - public abstract class FieldDef : IHasConstant, IHasCustomAttribute, IHasFieldMarshal, IMemberForwarded, IField, ITokenOperand, IMemberDef { + public abstract class FieldDef : IHasConstant, IHasCustomAttribute, IHasFieldMarshal, IMemberForwarded, IHasCustomDebugInformation, IField, ITokenOperand, IMemberDef { /// /// The row id in its table /// @@ -68,6 +75,33 @@ protected virtual void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); } + /// + public int HasCustomDebugInformationTag { + get { return 1; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// From column Field.Flags /// @@ -870,6 +904,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(declaringType2), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// protected override uint? GetFieldOffset_NoLock() { return readerModule.TablesStream.ReadFieldLayoutRow2(readerModule.MetaData.GetFieldLayoutRid(origRid)); diff --git a/src/DotNet/FileDef.cs b/src/DotNet/FileDef.cs index 6681dff6a..aa1cf1d08 100644 --- a/src/DotNet/FileDef.cs +++ b/src/DotNet/FileDef.cs @@ -3,12 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the File table /// - public abstract class FileDef : IHasCustomAttribute, IImplementation, IManagedEntryPoint { + public abstract class FileDef : IHasCustomAttribute, IImplementation, IHasCustomDebugInformation, IManagedEntryPoint { /// /// The row id in its table /// @@ -87,6 +95,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 16; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Set or clear flags in /// @@ -182,6 +217,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/GenericParam.cs b/src/DotNet/GenericParam.cs index 5df8bfe36..69b1a0b54 100644 --- a/src/DotNet/GenericParam.cs +++ b/src/DotNet/GenericParam.cs @@ -6,6 +6,7 @@ using dnlib.Utils; using dnlib.DotNet.MD; using dnlib.Threading; +using dnlib.DotNet.Pdb; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -18,7 +19,7 @@ namespace dnlib.DotNet { /// A high-level representation of a row in the GenericParam table /// [DebuggerDisplay("{Name.String}")] - public abstract class GenericParam : IHasCustomAttribute, IMemberDef, IListListener { + public abstract class GenericParam : IHasCustomAttribute, IHasCustomDebugInformation, IMemberDef, IListListener { /// /// The row id in its table /// @@ -150,6 +151,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 19; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// true if is not empty /// @@ -439,6 +467,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), GetGenericParamContext(owner), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// protected override void InitializeGenericParamConstraints() { var list = readerModule.MetaData.GetGenericParamConstraintRidList(origRid); diff --git a/src/DotNet/GenericParamConstraint.cs b/src/DotNet/GenericParamConstraint.cs index 4d20a9a05..9e5d50ec3 100644 --- a/src/DotNet/GenericParamConstraint.cs +++ b/src/DotNet/GenericParamConstraint.cs @@ -3,12 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the GenericParamConstraint table /// - public abstract class GenericParamConstraint : IHasCustomAttribute, IContainsGenericParameter { + public abstract class GenericParamConstraint : IHasCustomAttribute, IHasCustomDebugInformation, IContainsGenericParameter { /// /// The row id in its table /// @@ -72,6 +80,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 20; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + bool IContainsGenericParameter.ContainsGenericParameter { get { return TypeHelper.ContainsGenericParameter(this); } } @@ -104,6 +139,7 @@ sealed class GenericParamConstraintMD : GenericParamConstraint, IMDTokenProvider readonly ModuleDefMD readerModule; readonly uint origRid; + readonly GenericParamContext gpContext; /// public uint OrigRid { @@ -117,6 +153,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// @@ -135,6 +178,7 @@ public GenericParamConstraintMD(ModuleDefMD readerModule, uint rid, GenericParam this.origRid = rid; this.rid = rid; this.readerModule = readerModule; + this.gpContext = gpContext; uint constraint = readerModule.TablesStream.ReadGenericParamConstraintRow2(origRid); this.constraint = readerModule.ResolveTypeDefOrRef(constraint, gpContext); this.owner = readerModule.GetOwner(this); diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index c167808bb..b45da7f0f 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using dnlib.DotNet.Pdb; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -1023,6 +1024,26 @@ public interface ITypeOrMethodDef : ICodedToken, IHasCustomAttribute, IHasDeclSe bool HasGenericParameters { get; } } + /// + /// HasCustomDebugInformation interface + /// + public interface IHasCustomDebugInformation { + /// + /// The custom debug information tag + /// + int HasCustomDebugInformationTag { get; } + + /// + /// Gets the custom debug infos + /// + ThreadSafe.IList CustomDebugInfos { get; } + + /// + /// true if is not empty + /// + bool HasCustomDebugInfos { get; } + } + public static partial class Extensions { /// /// Converts a to a diff --git a/src/DotNet/InterfaceImpl.cs b/src/DotNet/InterfaceImpl.cs index ec3aaded0..416ef1f2c 100644 --- a/src/DotNet/InterfaceImpl.cs +++ b/src/DotNet/InterfaceImpl.cs @@ -4,13 +4,21 @@ using System.Diagnostics; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the InterfaceImpl table /// [DebuggerDisplay("{Interface}")] - public abstract class InterfaceImpl : IHasCustomAttribute, IContainsGenericParameter { + public abstract class InterfaceImpl : IHasCustomAttribute, IContainsGenericParameter, IHasCustomDebugInformation { /// /// The row id in its table /// @@ -64,6 +72,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 5; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + bool IContainsGenericParameter.ContainsGenericParameter { get { return TypeHelper.ContainsGenericParameter(this); } } @@ -96,6 +131,7 @@ sealed class InterfaceImplMD : InterfaceImpl, IMDTokenProviderMD { readonly ModuleDefMD readerModule; readonly uint origRid; + readonly GenericParamContext gpContext; /// public uint OrigRid { @@ -109,6 +145,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// @@ -127,6 +170,7 @@ public InterfaceImplMD(ModuleDefMD readerModule, uint rid, GenericParamContext g this.origRid = rid; this.rid = rid; this.readerModule = readerModule; + this.gpContext = gpContext; uint @interface = readerModule.TablesStream.ReadInterfaceImplRow2(origRid); this.@interface = readerModule.ResolveTypeDefOrRef(@interface, gpContext); } diff --git a/src/DotNet/ManifestResource.cs b/src/DotNet/ManifestResource.cs index 896d9048e..4a6223e5c 100644 --- a/src/DotNet/ManifestResource.cs +++ b/src/DotNet/ManifestResource.cs @@ -4,13 +4,21 @@ using System.Diagnostics; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the ManifestResource table /// [DebuggerDisplay("{Offset} {Name.String} {Implementation}")] - public abstract class ManifestResource : IHasCustomAttribute { + public abstract class ManifestResource : IHasCustomAttribute, IHasCustomDebugInformation { /// /// The row id in its table /// @@ -94,6 +102,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 18; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Modify property: = /// ( & ) | . @@ -200,6 +235,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index 97e820a1f..2486b5504 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -4,12 +4,20 @@ using System.Collections.Generic; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the MemberRef table /// - public abstract class MemberRef : IHasCustomAttribute, IMethodDefOrRef, ICustomAttributeType, IField, IContainsGenericParameter { + public abstract class MemberRef : IHasCustomAttribute, IMethodDefOrRef, ICustomAttributeType, IField, IContainsGenericParameter, IHasCustomDebugInformation { /// /// The row id in its table /// @@ -98,6 +106,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 6; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// public ITypeDefOrRef DeclaringType { get { @@ -504,6 +539,7 @@ sealed class MemberRefMD : MemberRef, IMDTokenProviderMD { readonly ModuleDefMD readerModule; readonly uint origRid; + readonly GenericParamContext gpContext; /// public uint OrigRid { @@ -517,6 +553,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// @@ -535,6 +578,7 @@ public MemberRefMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpCon this.origRid = rid; this.rid = rid; this.readerModule = readerModule; + this.gpContext = gpContext; this.module = readerModule; uint @class, name; uint signature = readerModule.TablesStream.ReadMemberRefRow(origRid, out @class, out name); diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 707cbe06a..f1e033bd4 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -7,6 +7,8 @@ using dnlib.DotNet.MD; using dnlib.DotNet.Emit; using dnlib.Threading; +using dnlib.DotNet.Pdb; +using System.Diagnostics; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -18,7 +20,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the Method table /// - public abstract class MethodDef : IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, IMethodDefOrRef, IMemberForwarded, ICustomAttributeType, ITypeOrMethodDef, IManagedEntryPoint, IListListener, IListListener, IMemberDef { + public abstract class MethodDef : IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, IMethodDefOrRef, IMemberForwarded, ICustomAttributeType, ITypeOrMethodDef, IManagedEntryPoint, IHasCustomDebugInformation, IListListener, IListListener, IMemberDef { internal static readonly UTF8String StaticConstructorName = ".cctor"; internal static readonly UTF8String InstanceConstructorName = ".ctor"; @@ -311,6 +313,33 @@ protected virtual void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); } + /// + public int HasCustomDebugInformationTag { + get { return 0; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Gets the methods this method implements /// @@ -1248,7 +1277,11 @@ protected override ImplMap GetImplMap_NoLock() { /// protected override MethodBody GetMethodBody_NoLock() { - return readerModule.ReadMethodBody(this, origRva, origImplAttributes, new GenericParamContext(declaringType2, this)); + var list = ThreadSafeListCreator.Create(); + var body = readerModule.ReadMethodBody(this, origRva, origImplAttributes, list, new GenericParamContext(declaringType2, this)); + Debug.Assert(customDebugInfos == null); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + return body; } /// @@ -1258,6 +1291,15 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + // The property will initialize CDIs + var body = Body; + Debug.Assert(customDebugInfos != null); + if (customDebugInfos == null) + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// protected override void InitializeOverrides() { var dt = declaringType2 as TypeDefMD; diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index 2dcac36b9..713fd8c58 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -3,12 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the MethodSpec table /// - public abstract class MethodSpec : IHasCustomAttribute, IMethod, IContainsGenericParameter { + public abstract class MethodSpec : IHasCustomAttribute, IHasCustomDebugInformation, IMethod, IContainsGenericParameter { /// /// The row id in its table /// @@ -72,6 +80,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 21; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// MethodSig IMethod.MethodSig { get { @@ -258,6 +293,7 @@ sealed class MethodSpecMD : MethodSpec, IMDTokenProviderMD { readonly ModuleDefMD readerModule; readonly uint origRid; + readonly GenericParamContext gpContext; /// public uint OrigRid { @@ -271,6 +307,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// @@ -289,6 +332,7 @@ public MethodSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpCo this.origRid = rid; this.rid = rid; this.readerModule = readerModule; + this.gpContext = gpContext; uint method; uint instantiation = readerModule.TablesStream.ReadMethodSpecRow(origRid, out method); this.method = readerModule.ResolveMethodDefOrRef(method, gpContext); diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index f686a750a..407d35146 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -23,7 +23,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the Module table /// - public abstract class ModuleDef : IHasCustomAttribute, IResolutionScope, IDisposable, IListListener, IModule, ITypeDefFinder, IDnlibDef, ITokenResolver, ISignatureReaderHelper { + public abstract class ModuleDef : IHasCustomAttribute, IHasCustomDebugInformation, IResolutionScope, IDisposable, IListListener, IModule, ITypeDefFinder, IDnlibDef, ITokenResolver, ISignatureReaderHelper { /// Default characteristics protected const Characteristics DefaultCharacteristics = Characteristics.ExecutableImage | Characteristics._32BitMachine; @@ -166,6 +166,33 @@ protected virtual void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); } + /// + public int HasCustomDebugInformationTag { + get { return 7; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Gets the module's assembly. To set this value, add this /// to . @@ -1628,6 +1655,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// protected override RVA GetNativeEntryPoint_NoLock() { return readerModule.GetNativeEntryPoint(); diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 4e29f55dc..406f706c5 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -541,6 +541,13 @@ public void LoadPdb(PdbImplType pdbImpl) { LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, loc)); } + internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { + var ps = pdbState; + if (ps == null) + return; + ps.InitializeCustomDebugInfos(token, gpContext, result); + } + ModuleKind GetKind() { if (TablesStream.AssemblyTable.Rows < 1) return ModuleKind.NetModule; @@ -1848,15 +1855,16 @@ internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid, GenericPa /// Method /// Method RVA /// Method impl attrs + /// Updated with custom debug infos /// Generic parameter context /// A or null if none - internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, GenericParamContext gpContext) { + internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, IList customDebugInfos, GenericParamContext gpContext) { MethodBody mb; var mDec = methodDecrypter; if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out mb)) { var cilBody = mb as CilBody; if (cilBody != null) - return InitializeBodyFromPdb(method, cilBody); + return InitializeBodyFromPdb(method, cilBody, customDebugInfos); return mb; } @@ -1864,7 +1872,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib return null; var codeType = implAttrs & MethodImplAttributes.CodeTypeMask; if (codeType == MethodImplAttributes.IL) - return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext)); + return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext), customDebugInfos); if (codeType == MethodImplAttributes.Native) return new NativeMethodBody(rva); return null; @@ -1875,11 +1883,12 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// /// Owner method /// Method body + /// Updated with custom debug infos /// Returns originak value - CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body) { + CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body, IList customDebugInfos) { var ps = pdbState; if (ps != null) - ps.InitializeMethodBody(this, method, body); + ps.InitializeMethodBody(this, method, body, customDebugInfos); return body; } diff --git a/src/DotNet/ModuleRef.cs b/src/DotNet/ModuleRef.cs index 00fca704b..f59786728 100644 --- a/src/DotNet/ModuleRef.cs +++ b/src/DotNet/ModuleRef.cs @@ -3,12 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the ModuleRef table /// - public abstract class ModuleRef : IHasCustomAttribute, IMemberRefParent, IResolutionScope, IModule, IOwnerModule { + public abstract class ModuleRef : IHasCustomAttribute, IMemberRefParent, IHasCustomDebugInformation, IResolutionScope, IModule, IOwnerModule { /// /// The row id in its table /// @@ -87,6 +95,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 12; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// public ModuleDef Module { get { return module; } @@ -171,6 +206,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/ParamDef.cs b/src/DotNet/ParamDef.cs index 524ad477a..a5b098322 100644 --- a/src/DotNet/ParamDef.cs +++ b/src/DotNet/ParamDef.cs @@ -4,14 +4,21 @@ using System.Diagnostics; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + namespace dnlib.DotNet { /// /// A high-level representation of a row in the Param table /// [DebuggerDisplay("{Sequence} {Name}")] - public abstract class ParamDef : IHasConstant, IHasCustomAttribute, IHasFieldMarshal { + public abstract class ParamDef : IHasConstant, IHasCustomAttribute, IHasFieldMarshal, IHasCustomDebugInformation { /// /// The row id in its table /// @@ -201,6 +208,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 4; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// true if is not null /// @@ -387,6 +421,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), GenericParamContext.Create(declaringMethod), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/Pdb/CorSymVarFlag.cs b/src/DotNet/Pdb/CorSymVarFlag.cs new file mode 100644 index 000000000..6888ba858 --- /dev/null +++ b/src/DotNet/Pdb/CorSymVarFlag.cs @@ -0,0 +1,10 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb { + [Flags] + enum CorSymVarFlag : uint { + VAR_IS_COMP_GEN = 0x00000001, + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index 7d0040ffc..5de138e4c 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -68,5 +68,10 @@ public override byte[] CheckSum { return buffer; } } + + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { return emptyPdbCustomDebugInfos; } + } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; } } diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index 7faa5a460..c33fb65d9 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -1,8 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; -using System.Collections.ObjectModel; -using System.Diagnostics; +using System.Collections.Generic; using System.Diagnostics.SymbolStore; using System.Threading; using dnlib.DotNet.Pdb.Symbols; @@ -37,7 +36,7 @@ public override SymbolScope RootScope { } volatile SymbolScope rootScope; - public override ReadOnlyCollection SequencePoints { + public override IList SequencePoints { get { if (sequencePoints == null) { uint seqPointCount; @@ -65,12 +64,12 @@ public override ReadOnlyCollection SequencePoints { EndColumn = endColumns[i], }; } - Interlocked.CompareExchange(ref sequencePoints, new ReadOnlyCollection(seqPoints), null); + sequencePoints = seqPoints; } return sequencePoints; } } - volatile ReadOnlyCollection sequencePoints; + volatile SymbolSequencePoint[] sequencePoints; public override int IteratorKickoffMethod { get { return 0; } @@ -94,7 +93,7 @@ public override uint? AsyncCatchHandlerILOffset { } } - public override ReadOnlyCollection AsyncStepInfos { + public override IList AsyncStepInfos { get { if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) return null; @@ -107,11 +106,11 @@ public override ReadOnlyCollection AsyncStepInfos { var res = new SymbolAsyncStepInfo[stepInfoCount]; for (int i = 0; i < res.Length; i++) res[i] = new SymbolAsyncStepInfo(yieldOffsets[i], breakpointOffsets[i], breakpointMethods[i]); - Interlocked.CompareExchange(ref asyncStepInfos, new ReadOnlyCollection(res), null); + asyncStepInfos = res; } return asyncStepInfos; } } - volatile ReadOnlyCollection asyncStepInfos; + volatile SymbolAsyncStepInfo[] asyncStepInfos; } } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 823b4f4af..e6615f348 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Runtime.InteropServices; using System.Threading; using dnlib.DotNet.Emit; @@ -10,6 +9,7 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolReaderImpl : SymbolReader { + ModuleDef module; readonly ISymUnmanagedReader reader; const int E_FAIL = unchecked((int)0x80004005); @@ -36,7 +36,7 @@ public override int UserEntryPoint { } } - public override ReadOnlyCollection Documents { + public override IList Documents { get { if (documents == null) { uint numDocs; @@ -46,14 +46,18 @@ public override ReadOnlyCollection Documents { var docs = new SymbolDocument[numDocs]; for (uint i = 0; i < numDocs; i++) docs[i] = new SymbolDocumentImpl(unDocs[i]); - Interlocked.CompareExchange(ref documents, new ReadOnlyCollection(docs), null); + documents = docs; } return documents; } } - volatile ReadOnlyCollection documents; + volatile SymbolDocument[] documents; - public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version) { + public override void Initialize(ModuleDef module) { + this.module = module; + } + + public override SymbolMethod GetMethod(MethodDef method, int version) { ISymUnmanagedMethod unMethod; int hr = reader.GetMethodByVersion(method.MDToken.Raw, version, out unMethod); if (hr == E_FAIL) @@ -62,7 +66,7 @@ public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int v return unMethod == null ? null : new SymbolMethodImpl(unMethod); } - public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { const string CDI_NAME = "MD2"; uint bufSize; reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, 0, out bufSize, null); @@ -72,5 +76,8 @@ public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + } } } diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs index 5c222d84a..f87ab0e93 100644 --- a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.ObjectModel; +using System.Collections.Generic; using System.Diagnostics; using System.Threading; using dnlib.DotNet.Pdb.Symbols; @@ -41,7 +41,7 @@ public override int EndOffset { } } - public override ReadOnlyCollection Children { + public override IList Children { get { if (children == null) { uint numScopes; @@ -51,14 +51,14 @@ public override ReadOnlyCollection Children { var scopes = new SymbolScope[numScopes]; for (uint i = 0; i < numScopes; i++) scopes[i] = new SymbolScopeImpl(unScopes[i], method, this); - Interlocked.CompareExchange(ref children, new ReadOnlyCollection(scopes), null); + children = scopes; } return children; } } - volatile ReadOnlyCollection children; + volatile SymbolScope[] children; - public override ReadOnlyCollection Locals { + public override IList Locals { get { if (locals == null) { uint numVars; @@ -68,14 +68,14 @@ public override ReadOnlyCollection Locals { var vars = new SymbolVariable[numVars]; for (uint i = 0; i < numVars; i++) vars[i] = new SymbolVariableImpl(unVars[i]); - Interlocked.CompareExchange(ref locals, new ReadOnlyCollection(vars), null); + locals = vars; } return locals; } } - volatile ReadOnlyCollection locals; + volatile SymbolVariable[] locals; - public override ReadOnlyCollection Namespaces { + public override IList Namespaces { get { if (namespaces == null) { uint numNss; @@ -85,18 +85,23 @@ public override ReadOnlyCollection Namespaces { var nss = new SymbolNamespace[numNss]; for (uint i = 0; i < numNss; i++) nss[i] = new SymbolNamespaceImpl(unNss[i]); - Interlocked.CompareExchange(ref namespaces, new ReadOnlyCollection(nss), null); + namespaces = nss; } return namespaces; } } - volatile ReadOnlyCollection namespaces; + volatile SymbolNamespace[] namespaces; + + public override IList CustomDebugInfos { + get { return emptyPdbCustomDebugInfos; } + } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; public override PdbImportScope ImportScope { get { return null; } } - public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext) { + public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { var scope2 = scope as ISymUnmanagedScope2; if (scope2 == null) return emptySymbolConstants; diff --git a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs index 4efd7afa4..58071af6a 100644 --- a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs @@ -18,14 +18,13 @@ public override int Index { } } - public override SymbolVariableAttributes Attributes { + public override PdbLocalAttributes Attributes { get { uint result; variable.GetAttributes(out result); - const int VAR_IS_COMP_GEN = 1; - if ((result & VAR_IS_COMP_GEN) != 0) - return SymbolVariableAttributes.CompilerGenerated; - return SymbolVariableAttributes.None; + if ((result & (uint)CorSymVarFlag.VAR_IS_COMP_GEN) != 0) + return PdbLocalAttributes.DebuggerHidden; + return PdbLocalAttributes.None; } } @@ -40,5 +39,10 @@ public override string Name { return new string(chars, 0, chars.Length - 1); } } + + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { return emptyPdbCustomDebugInfos; } + } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; } } diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index f0f9040d9..e3757883b 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -32,6 +32,10 @@ public override Guid CheckSumAlgorithmId { public override byte[] CheckSum { get { return checkSum; } } + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { return emptyPdbCustomDebugInfos; } + } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; public DbiDocument(string url) { this.url = url; diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index f590e80a3..fe236facf 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; using System.Threading; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; @@ -20,19 +18,10 @@ public override int Token { public DbiScope Root { get; private set; } public List Lines { get { return lines; } - set { - lines = value; - sequencePoints = new ReadOnlyCollection(lines); - } + set { lines = value; } } List lines; - static readonly ReadOnlyCollection emptySymbolSequencePoints = new ReadOnlyCollection(new SymbolSequencePoint[0]); - - public DbiFunction() { - sequencePoints = emptySymbolSequencePoints; - } - public void Read(IImageStream stream, long recEnd) { stream.Position += 4; var end = stream.ReadUInt32(); @@ -66,10 +55,15 @@ public override SymbolScope RootScope { get { return Root; } } - public override ReadOnlyCollection SequencePoints { - get { return sequencePoints; } + public override IList SequencePoints { + get { + var l = lines; + if (l == null) + return emptySymbolSequencePoints; + return l; + } } - ReadOnlyCollection sequencePoints; + static readonly SymbolSequencePoint[] emptySymbolSequencePoints = new SymbolSequencePoint[0]; public override int IteratorKickoffMethod { get { return 0; } @@ -95,14 +89,14 @@ public override uint? AsyncCatchHandlerILOffset { } } - public override ReadOnlyCollection AsyncStepInfos { + public override IList AsyncStepInfos { get { if (asyncStepInfos == null) - Interlocked.CompareExchange(ref asyncStepInfos, new ReadOnlyCollection(CreateSymbolAsyncStepInfos()), null); + asyncStepInfos = CreateSymbolAsyncStepInfos(); return asyncStepInfos; } } - volatile ReadOnlyCollection asyncStepInfos; + volatile SymbolAsyncStepInfo[] asyncStepInfos; SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index d9a36eada..652c8c524 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Diagnostics; using System.Text; using dnlib.DotNet.Pdb.Symbols; @@ -16,9 +15,6 @@ sealed class DbiScope : SymbolScope { readonly List childrenList; readonly List localsList; readonly List namespacesList; - readonly ReadOnlyCollection children; - readonly ReadOnlyCollection locals; - readonly ReadOnlyCollection namespaces; public override SymbolMethod Method { get { return method; } @@ -36,18 +32,23 @@ public override int EndOffset { get { return endOffset; } } - public override ReadOnlyCollection Children { - get { return children; } + public override IList Children { + get { return childrenList; } } - public override ReadOnlyCollection Locals { - get { return locals; } + public override IList Locals { + get { return localsList; } } - public override ReadOnlyCollection Namespaces { - get { return namespaces; } + public override IList Namespaces { + get { return namespacesList; } } + public override IList CustomDebugInfos { + get { return emptyPdbCustomDebugInfos; } + } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; + public override PdbImportScope ImportScope { get { return null; } } @@ -60,11 +61,8 @@ public DbiScope(SymbolMethod method, SymbolScope parent, string name, uint offse endOffset = (int)(offset + length); childrenList = new List(); - children = new ReadOnlyCollection(childrenList); localsList = new List(); - locals = new ReadOnlyCollection(localsList); namespacesList = new List(); - namespaces = new ReadOnlyCollection(namespacesList); } public string Name { get; private set; } @@ -199,7 +197,7 @@ static bool ReadAndCompareBytes(IImageStream stream, long end, byte[] bytes) { return true; } - public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext) { + public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { if (constants == null) return emptySymbolConstants; var res = new PdbConstant[constants.Count]; diff --git a/src/DotNet/Pdb/Managed/DbiVariable.cs b/src/DotNet/Pdb/Managed/DbiVariable.cs index 082167cad..7d490f356 100644 --- a/src/DotNet/Pdb/Managed/DbiVariable.cs +++ b/src/DotNet/Pdb/Managed/DbiVariable.cs @@ -10,16 +10,21 @@ public override string Name { } string name; - public override SymbolVariableAttributes Attributes { + public override PdbLocalAttributes Attributes { get { return attributes; } } - SymbolVariableAttributes attributes; + PdbLocalAttributes attributes; public override int Index { get { return index; } } int index; + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { return emptyPdbCustomDebugInfos; } + } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; + public void Read(IImageStream stream) { index = stream.ReadInt32(); stream.Position += 10; @@ -27,11 +32,11 @@ public void Read(IImageStream stream) { name = PdbReader.ReadCString(stream); } - static SymbolVariableAttributes GetAttributes(uint flags) { - SymbolVariableAttributes res = 0; + static PdbLocalAttributes GetAttributes(uint flags) { + PdbLocalAttributes res = 0; const int fCompGenx = 4; if ((flags & fCompGenx) != 0) - res |= SymbolVariableAttributes.CompilerGenerated; + res |= PdbLocalAttributes.DebuggerHidden; return res; } } diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 31eaee0ff..9d92f93b7 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -3,7 +3,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Diagnostics; using System.Text; using System.Threading; @@ -20,6 +19,7 @@ sealed class PdbReader : SymbolReader { Dictionary names; Dictionary strings; List modules; + ModuleDef module; const int STREAM_ROOT = 0; const int STREAM_NAMES = 1; @@ -40,6 +40,10 @@ sealed class PdbReader : SymbolReader { /// public Guid Guid { get; private set; } + public override void Initialize(ModuleDef module) { + this.module = module; + } + /// /// Read the PDB in the specified stream. /// @@ -318,32 +322,32 @@ internal static string ReadCString(IImageStream stream) { return value; } - public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version) { + public override SymbolMethod GetMethod(MethodDef method, int version) { DbiFunction symMethod; if (functions.TryGetValue(method.MDToken.ToInt32(), out symMethod)) return symMethod; return null; } - public override ReadOnlyCollection Documents { + public override IList Documents { get { if (documentsResult == null) { var docs = new SymbolDocument[documents.Count]; int i = 0; foreach (var doc in documents.Values) docs[i++] = doc; - Interlocked.CompareExchange(ref documentsResult, new ReadOnlyCollection(docs), null); + documentsResult = docs; } return documentsResult; } } - volatile ReadOnlyCollection documentsResult; + volatile SymbolDocument[] documentsResult; public override int UserEntryPoint { get { return (int)entryPt; } } - public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { const string CDI_NAME = "MD2"; DbiFunction func; bool b = functions.TryGetValue(method.MDToken.ToInt32(), out func); @@ -355,5 +359,8 @@ public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + } } } diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs index 14ef2f0ca..2f5cb4ca1 100644 --- a/src/DotNet/Pdb/PdbConstant.cs +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -1,10 +1,18 @@ // dnlib: See LICENSE.txt for more info +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + namespace dnlib.DotNet.Pdb { /// /// A constant in a method scope, eg. "const int SomeConstant = 123;" /// - public struct PdbConstant { + public sealed class PdbConstant : IHasCustomDebugInformation { string name; TypeSig type; object value; @@ -33,6 +41,12 @@ public object Value { set { this.value = value; } } + /// + /// Constructor + /// + public PdbConstant() { + } + /// /// Constructor /// @@ -45,6 +59,24 @@ public PdbConstant(string name, TypeSig type, object value) { this.value = value; } + /// + public int HasCustomDebugInformationTag { + get { return 25; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { return customDebugInfos; } + } + readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); + /// /// ToString() /// diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index e539d6ffc..0684e6ea3 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -3,14 +3,22 @@ using System; using System.Diagnostics; using System.Diagnostics.SymbolStore; +using System.Threading; using dnlib.DotNet.Pdb.Symbols; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet.Pdb { /// /// A PDB document /// [DebuggerDisplay("{Url}")] - public sealed class PdbDocument { + public sealed class PdbDocument : IHasCustomDebugInformation { /// /// Gets/sets the document URL /// @@ -41,6 +49,24 @@ public sealed class PdbDocument { /// public byte[] CheckSum { get; set; } + /// + public int HasCustomDebugInformationTag { + get { return 22; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { return customDebugInfos; } + } + readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); + /// /// Default constructor /// @@ -60,6 +86,8 @@ public PdbDocument(SymbolDocument symDoc) { this.DocumentType = symDoc.DocumentType; this.CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId; this.CheckSum = symDoc.CheckSum; + foreach (var cdi in symDoc.CustomDebugInfos) + customDebugInfos.Add(cdi); } /// diff --git a/src/DotNet/Pdb/PdbImport.cs b/src/DotNet/Pdb/PdbImport.cs index f5c2714c4..aac151615 100644 --- a/src/DotNet/Pdb/PdbImport.cs +++ b/src/DotNet/Pdb/PdbImport.cs @@ -13,7 +13,7 @@ namespace dnlib.DotNet.Pdb { /// /// Import scope /// - public sealed class PdbImportScope { + public sealed class PdbImportScope : IHasCustomDebugInformation { readonly ThreadSafe.IList imports = ThreadSafeListCreator.Create(); /// @@ -40,6 +40,24 @@ public ThreadSafe.IList Imports { public bool HasImports { get { return imports.Count > 0; } } + + /// + public int HasCustomDebugInformationTag { + get { return 26; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { return customDebugInfos; } + } + readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); } /// diff --git a/src/DotNet/Pdb/PdbLocal.cs b/src/DotNet/Pdb/PdbLocal.cs new file mode 100644 index 000000000..92edca881 --- /dev/null +++ b/src/DotNet/Pdb/PdbLocal.cs @@ -0,0 +1,88 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.DotNet.Emit; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + +namespace dnlib.DotNet.Pdb { + /// + /// A local variable + /// + public sealed class PdbLocal : IHasCustomDebugInformation { + /// + /// Constructor + /// + public PdbLocal() { + } + + /// + /// Constructor + /// + /// + /// + /// + public PdbLocal(Local local, string name, PdbLocalAttributes attributes) { + Local = local; + Name = name; + Attributes = attributes; + } + + /// + /// Gets/sets the local + /// + public Local Local { get; set; } + + /// + /// Gets/sets the name + /// + public string Name { get; set; } + + /// + /// Gets/sets the attributes + /// + public PdbLocalAttributes Attributes { get; set; } + + /// + /// Gets the index of the local + /// + public int Index { + get { return Local.Index; } + } + + /// + /// true if it should be hidden in debugger variables windows. Not all compiler generated locals have this flag set. + /// + public bool IsDebuggerHidden { + get { return (Attributes & PdbLocalAttributes.DebuggerHidden) != 0; } + set { + if (value) + Attributes |= PdbLocalAttributes.DebuggerHidden; + else + Attributes &= ~PdbLocalAttributes.DebuggerHidden; + } + } + + /// + public int HasCustomDebugInformationTag { + get { return 24; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { return customDebugInfos; } + } + readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); + } +} diff --git a/src/DotNet/Pdb/PdbLocalAttributes.cs b/src/DotNet/Pdb/PdbLocalAttributes.cs new file mode 100644 index 000000000..8953d2fb8 --- /dev/null +++ b/src/DotNet/Pdb/PdbLocalAttributes.cs @@ -0,0 +1,21 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb { + /// + /// Local attributes + /// + [Flags] + public enum PdbLocalAttributes { + /// + /// No bit is set + /// + None = 0, + + /// + /// Local should be hidden in debugger variables windows. Not all compiler generated locals have this flag set. + /// + DebuggerHidden = 0x00000001, + } +} diff --git a/src/DotNet/Pdb/PdbMethod.cs b/src/DotNet/Pdb/PdbMethod.cs index f4c8c3e39..1e9422790 100644 --- a/src/DotNet/Pdb/PdbMethod.cs +++ b/src/DotNet/Pdb/PdbMethod.cs @@ -13,8 +13,6 @@ namespace dnlib.DotNet.Pdb { /// A PDB method /// public sealed class PdbMethod { - readonly ThreadSafe.IList customDebugInfos; - /// /// Gets/sets the root scope. It contains all scopes of the method, using namespaces, variables and constants /// @@ -30,18 +28,10 @@ public sealed class PdbMethod { /// public PdbIteratorMethod IteratorMethod { get; set; } - /// - /// Gets all custom debug infos - /// - public ThreadSafe.IList CustomDebugInfos { - get { return customDebugInfos; } - } - /// /// Constructor /// public PdbMethod() { - customDebugInfos = ThreadSafeListCreator.Create(); } } } diff --git a/src/DotNet/Pdb/PdbScope.cs b/src/DotNet/Pdb/PdbScope.cs index ba0e3aa4b..53536ad4e 100644 --- a/src/DotNet/Pdb/PdbScope.cs +++ b/src/DotNet/Pdb/PdbScope.cs @@ -15,12 +15,18 @@ namespace dnlib.DotNet.Pdb { /// A PDB scope /// [DebuggerDisplay("{Start} - {End}")] - public sealed class PdbScope { + public sealed class PdbScope : IHasCustomDebugInformation { readonly ThreadSafe.IList scopes = ThreadSafeListCreator.Create(); - readonly ThreadSafe.IList locals = ThreadSafeListCreator.Create(); + readonly ThreadSafe.IList locals = ThreadSafeListCreator.Create(); readonly ThreadSafe.IList namespaces = ThreadSafeListCreator.Create(); readonly ThreadSafe.IList constants = ThreadSafeListCreator.Create(); + /// + /// Constructor + /// + public PdbScope() { + } + /// /// Gets/sets the first instruction /// @@ -48,7 +54,7 @@ public bool HasScopes { /// /// Gets all locals in this scope /// - public ThreadSafe.IList Variables { + public ThreadSafe.IList Variables { get { return locals; } } @@ -91,5 +97,23 @@ public ThreadSafe.IList Constants { public bool HasConstants { get { return constants.Count > 0; } } + + /// + public int HasCustomDebugInformationTag { + get { return 23; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { return customDebugInfos; } + } + readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); } } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index e73fe9e69..ff5114d1c 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Diagnostics; using dnlib.DotNet.Emit; +using dnlib.DotNet.MD; using dnlib.DotNet.Pdb.Symbols; using dnlib.Threading; @@ -16,7 +16,7 @@ public sealed class PdbState { readonly SymbolReader reader; readonly Dictionary docDict = new Dictionary(); MethodDef userEntryPoint; - Compiler compiler; + readonly Compiler compiler; #if THREAD_SAFE readonly Lock theLock = Lock.Create(); @@ -61,13 +61,6 @@ public bool HasDocuments { } } - /// - /// Default constructor - /// - [Obsolete("Use PdbState(ModuleDef) constructor")] - public PdbState() { - } - /// /// Constructor /// @@ -89,6 +82,7 @@ public PdbState(SymbolReader reader, ModuleDefMD module) { if (module == null) throw new ArgumentNullException("module"); this.reader = reader; + reader.Initialize(module); this.compiler = CalculateCompiler(module); this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; @@ -181,14 +175,11 @@ public List RemoveAllDocuments(bool returnDocs) { #endif } - internal Compiler GetCompiler(ModuleDef module) { - if (compiler == Compiler.Unknown) - compiler = CalculateCompiler(module); - return compiler; + internal Compiler Compiler { + get { return compiler; } } - internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { - Debug.Assert((module == null) == (ownerMethod == null)); + internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, IList customDebugInfos) { if (reader == null || body == null) return; @@ -196,21 +187,19 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - method = reader.GetMethod(module, ownerMethod, 1); + method = reader.GetMethod(ownerMethod, 1); if (method != null) { var pdbMethod = new PdbMethod(); - pdbMethod.Scope = CreateScope(module, ownerMethod == null ? new GenericParamContext() : GenericParamContext.Create(ownerMethod), body, method.RootScope); + pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); - if (module != null && method.IsAsyncMethod) + if (method.IsAsyncMethod) pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method); - if (module != null && method.IsIteratorMethod) + if (method.IsIteratorMethod) pdbMethod.IteratorMethod = CreateIteratorMethod(module, ownerMethod, body, method); - if (ownerMethod != null) { - // Read the custom debug info last so eg. local names have been initialized - reader.GetCustomDebugInfo(ownerMethod, body, pdbMethod.CustomDebugInfos); - } + // Read the custom debug info last so eg. local names have been initialized + reader.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); body.PdbMethod = pdbMethod; } @@ -219,7 +208,7 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci #endif } - Compiler CalculateCompiler(ModuleDef module) { + static Compiler CalculateCompiler(ModuleDef module) { if (module == null) return Compiler.Other; @@ -240,7 +229,7 @@ Compiler CalculateCompiler(ModuleDef module) { PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { var kickoffToken = new MDToken(symMethod.AsyncKickoffMethod); - if (kickoffToken.Table != MD.Table.Method) + if (kickoffToken.Table != Table.Method) return null; var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); @@ -268,8 +257,8 @@ PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody b } else { var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); - Debug.Assert(breakpointMethodToken.Table == MD.Table.Method); - if (breakpointMethodToken.Table != MD.Table.Method) + Debug.Assert(breakpointMethodToken.Table == Table.Method); + if (breakpointMethodToken.Table != Table.Method) continue; breakpointMethod = module.ResolveMethod(breakpointMethodToken.Rid); Debug.Assert(breakpointMethod != null); @@ -289,7 +278,7 @@ PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody b PdbIteratorMethod CreateIteratorMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { var kickoffToken = new MDToken(symMethod.IteratorKickoffMethod); - if (kickoffToken.Table != MD.Table.Method) + if (kickoffToken.Table != Table.Method) return null; var iteratorMethod = new PdbIteratorMethod(); @@ -337,7 +326,7 @@ void AddSequencePoints(CilBody body, SymbolMethod method) { struct CreateScopeState { public SymbolScope SymScope; public PdbScope PdbScope; - public ReadOnlyCollection Children; + public IList Children; public int ChildrenIndex; } @@ -350,11 +339,13 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody var state = new CreateScopeState() { SymScope = symScope }; recursive_call: int instrIndex = 0; - int endIsInclusiveValue = GetCompiler(module) == Compiler.VisualBasic ? 1 : 0; + int endIsInclusiveValue = Compiler == Compiler.VisualBasic ? 1 : 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), }; + foreach (var cdi in state.SymScope.CustomDebugInfos) + state.PdbScope.CustomDebugInfos.Add(cdi); foreach (var symLocal in state.SymScope.Locals) { int localIndex = symLocal.Index; @@ -363,95 +354,93 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody continue; } var local = body.Variables[localIndex]; - local.Name = symLocal.Name; + var name = symLocal.Name; + local.SetName(name); var attributes = symLocal.Attributes; - int pdbAttributes = 0; - const int VAR_IS_COMP_GEN = 1; - if ((attributes & SymbolVariableAttributes.CompilerGenerated) != 0) - pdbAttributes |= VAR_IS_COMP_GEN; - local.PdbAttributes = pdbAttributes; - state.PdbScope.Variables.Add(local); + local.SetAttributes(attributes); + var pdbLocal = new PdbLocal(local, name, attributes); + foreach (var cdi in symLocal.CustomDebugInfos) + pdbLocal.CustomDebugInfos.Add(cdi); + state.PdbScope.Variables.Add(pdbLocal); } foreach (var ns in state.SymScope.Namespaces) state.PdbScope.Namespaces.Add(ns.Name); state.PdbScope.ImportScope = state.SymScope.ImportScope; - if (module != null) { - var constants = state.SymScope.GetConstants(module, gpContext); - for (int i = 0; i < constants.Length; i++) { - var constant = constants[i]; - var type = constant.Type.RemovePinnedAndModifiers(); - if (type != null) { - // Fix a few values since they're stored as some other type in the PDB - switch (type.ElementType) { - case ElementType.Boolean: - if (constant.Value is short) - constant.Value = (short)constant.Value != 0; - break; - case ElementType.Char: - if (constant.Value is ushort) - constant.Value = (char)(ushort)constant.Value; - break; - case ElementType.I1: - if (constant.Value is short) - constant.Value = (sbyte)(short)constant.Value; + var constants = state.SymScope.GetConstants(module, gpContext); + for (int i = 0; i < constants.Count; i++) { + var constant = constants[i]; + var type = constant.Type.RemovePinnedAndModifiers(); + if (type != null) { + // Fix a few values since they're stored as some other type in the PDB + switch (type.ElementType) { + case ElementType.Boolean: + if (constant.Value is short) + constant.Value = (short)constant.Value != 0; + break; + case ElementType.Char: + if (constant.Value is ushort) + constant.Value = (char)(ushort)constant.Value; + break; + case ElementType.I1: + if (constant.Value is short) + constant.Value = (sbyte)(short)constant.Value; + break; + case ElementType.U1: + if (constant.Value is short) + constant.Value = (byte)(short)constant.Value; + break; + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + case ElementType.Void: + case ElementType.Ptr: + case ElementType.ByRef: + case ElementType.TypedByRef: + case ElementType.I: + case ElementType.U: + case ElementType.FnPtr: + case ElementType.ValueType: + break; + case ElementType.String: + // "" is stored as null, and null is stored as (int)0 + if (constant.Value is int && (int)constant.Value == 0) + constant.Value = null; + else if (constant.Value == null) + constant.Value = string.Empty; + break; + case ElementType.Object: + case ElementType.Class: + case ElementType.SZArray: + case ElementType.Array: + default: + if (constant.Value is int && (int)constant.Value == 0) + constant.Value = null; + break; + case ElementType.GenericInst: + var gis = (GenericInstSig)type; + if (gis.GenericType is ValueTypeSig) break; - case ElementType.U1: - if (constant.Value is short) - constant.Value = (byte)(short)constant.Value; - break; - case ElementType.I2: - case ElementType.U2: - case ElementType.I4: - case ElementType.U4: - case ElementType.I8: - case ElementType.U8: - case ElementType.R4: - case ElementType.R8: - case ElementType.Void: - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.FnPtr: - case ElementType.ValueType: - break; - case ElementType.String: - // "" is stored as null, and null is stored as (int)0 - if (constant.Value is int && (int)constant.Value == 0) - constant.Value = null; - else if (constant.Value == null) - constant.Value = string.Empty; - break; - case ElementType.Object: - case ElementType.Class: - case ElementType.SZArray: - case ElementType.Array: - default: - if (constant.Value is int && (int)constant.Value == 0) - constant.Value = null; - break; - case ElementType.GenericInst: - var gis = (GenericInstSig)type; - if (gis.GenericType is ValueTypeSig) + goto case ElementType.Class; + case ElementType.Var: + case ElementType.MVar: + var gp = ((GenericSig)type).GenericParam; + if (gp != null) { + if (gp.HasNotNullableValueTypeConstraint) break; - goto case ElementType.Class; - case ElementType.Var: - case ElementType.MVar: - var gp = ((GenericSig)type).GenericParam; - if (gp != null) { - if (gp.HasNotNullableValueTypeConstraint) - break; - if (gp.HasReferenceTypeConstraint) - goto case ElementType.Class; - } - break; + if (gp.HasReferenceTypeConstraint) + goto case ElementType.Class; } + break; } - state.PdbScope.Constants.Add(constant); } + state.PdbScope.Constants.Add(constant); } // Here's the now somewhat obfuscated for loop @@ -502,13 +491,17 @@ static Instruction GetInstruction(IList instrs, int offset, ref int return null; } + internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { + Debug.Assert(token.Table != Table.Method, "Methods get initialized when reading the method bodies"); + reader.GetCustomDebugInfos(token.ToInt32(), gpContext, result); + } + internal void Dispose() { reader.Dispose(); } } enum Compiler { - Unknown, Other, VisualBasic, } diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/PdbWriter.cs index e5344eb12..1062dc962 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/PdbWriter.cs @@ -74,7 +74,7 @@ public PdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) this.module = metaData.Module; this.instrToOffset = new Dictionary(); this.customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); - this.localsEndScopeIncValue = pdbState.GetCompiler(metaData.module) == Compiler.VisualBasic ? 1 : 0; + this.localsEndScopeIncValue = pdbState.Compiler == Compiler.VisualBasic ? 1 : 0; } /// @@ -123,7 +123,7 @@ bool ShouldAddMethod(MethodDef method) { // Don't check whether it's the empty string. Only check for null. if (local.Name != null) return true; - if (local.PdbAttributes != 0) + if (local.Attributes != 0) return true; } @@ -260,9 +260,9 @@ void Write(MethodDef method) { WriteScope(ref info, scope, 0); } - if (pdbMethod.CustomDebugInfos.Count != 0) { + if (method.CustomDebugInfos.Count != 0) { customDebugInfoWriterContext.Logger = GetLogger(); - var cdiData = PdbCustomDebugInfoWriter.Write(metaData, method, customDebugInfoWriterContext, pdbMethod.CustomDebugInfos); + var cdiData = PdbCustomDebugInfoWriter.Write(metaData, method, customDebugInfoWriterContext, method.CustomDebugInfos); if (cdiData != null) writer.SetSymAttribute(symbolToken, "MD2", cdiData); } @@ -378,7 +378,7 @@ void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { writer.CloseScope(startOffset == 0 && endOffset == info.BodySize ? endOffset : endOffset - localsEndScopeIncValue); } - void AddLocals(MethodDef method, IList locals, uint startOffset, uint endOffset) { + void AddLocals(MethodDef method, IList locals, uint startOffset, uint endOffset) { if (locals.Count == 0) return; uint token = metaData.GetLocalVarSigToken(method); @@ -387,13 +387,20 @@ void AddLocals(MethodDef method, IList locals, uint startOffset, uint end return; } foreach (var local in locals) { - if (local.Name == null && local.PdbAttributes == 0) + uint attrs = GetPdbLocalFlags(local.Attributes); + if (attrs == 0 && local.Name == null) continue; - writer.DefineLocalVariable2(local.Name ?? string.Empty, (uint)local.PdbAttributes, + writer.DefineLocalVariable2(local.Name ?? string.Empty, attrs, token, 1, (uint)local.Index, 0, 0, startOffset, endOffset); } } + static uint GetPdbLocalFlags(PdbLocalAttributes attributes) { + if ((attributes & PdbLocalAttributes.DebuggerHidden) != 0) + return (uint)CorSymVarFlag.VAR_IS_COMP_GEN; + return 0; + } + int GetUserEntryPointToken() { var ep = pdbState.UserEntryPoint; if (ep == null) diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index d3f3b0d07..251f2dcaa 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Diagnostics; using dnlib.DotNet.Emit; using dnlib.DotNet.MD; @@ -13,9 +12,10 @@ namespace dnlib.DotNet.Pdb.Portable { sealed class PortablePdbReader : SymbolReader { + ModuleDef module; readonly IMetaData moduleMetaData; readonly IMetaData pdbMetaData; - readonly ReadOnlyCollection documents; + SymbolDocument[] documents; readonly Guid pdbId; readonly uint timestamp; @@ -25,7 +25,7 @@ public override int UserEntryPoint { get { return (int)entryPointToken; } } - public override ReadOnlyCollection Documents { + public override IList Documents { get { return documents; } } @@ -41,7 +41,10 @@ public PortablePdbReader(IMetaData moduleMetaData, IImageStream pdbStream) { entryPointToken = stream.ReadUInt32(); } } + } + public override void Initialize(ModuleDef module) { + this.module = module; documents = ReadDocuments(); } @@ -59,10 +62,13 @@ static Guid GetLanguageVendor(Guid language) { return Guid.Empty; } - ReadOnlyCollection ReadDocuments() { + SymbolDocument[] ReadDocuments() { + Debug.Assert(module != null); var docTbl = pdbMetaData.TablesStream.DocumentTable; var docs = new SymbolDocument[docTbl.Rows]; var nameReader = new DocumentNameReader(pdbMetaData.BlobStream); + var custInfos = ListCache.AllocList(); + var gpContext = new GenericParamContext(); for (int i = 0; i < docs.Length; i++) { uint nameOffset, hashAlgorithmIndex, hashOffset; uint languageIndex = pdbMetaData.TablesStream.ReadDocumentRow2((uint)i + 1, out nameOffset, out hashAlgorithmIndex, out hashOffset); @@ -72,14 +78,22 @@ ReadOnlyCollection ReadDocuments() { var documentType = Constants.DocumentTypeText; var checkSumAlgorithmId = pdbMetaData.GuidStream.Read(hashAlgorithmIndex) ?? Guid.Empty; var checkSum = pdbMetaData.BlobStream.ReadNoNull(hashOffset); - docs[i] = new SymbolDocumentImpl(url, language, languageVendor, documentType, checkSumAlgorithmId, checkSum); + + var token = new MDToken(Table.Document, i + 1).ToInt32(); + custInfos.Clear(); + GetCustomDebugInfos(token, gpContext, custInfos); + var custInfosArray = custInfos.Count == 0 ? emptyPdbCustomDebugInfos : custInfos.ToArray(); + + docs[i] = new SymbolDocumentImpl(url, language, languageVendor, documentType, checkSumAlgorithmId, checkSum, custInfosArray); } - return new ReadOnlyCollection(docs); + ListCache.Free(ref custInfos); + return docs; } + static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; bool TryGetSymbolDocument(uint rid, out SymbolDocument document) { int index = (int)rid - 1; - if ((uint)index >= (uint)documents.Count) { + if ((uint)index >= (uint)documents.Length) { Debug.Fail("Couldn't find document with rid 0x" + rid.ToString("X6")); document = null; return false; @@ -88,14 +102,15 @@ bool TryGetSymbolDocument(uint rid, out SymbolDocument document) { return true; } - public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version) { + public override SymbolMethod GetMethod(MethodDef method, int version) { var mdTable = pdbMetaData.TablesStream.MethodDebugInformationTable; uint methodRid = method.Rid; if (!mdTable.IsValidRID(methodRid)) return null; var sequencePoints = ReadSequencePoints(methodRid) ?? emptySymbolSequencePoints; - var rootScope = ReadScope(module, methodRid); + var gpContext = GenericParamContext.Create(method); + var rootScope = ReadScope(methodRid, gpContext); var kickoffMethod = GetKickoffMethod(methodRid); bool isAsyncMethod = kickoffMethod != 0 && IsAsyncMethod(method); @@ -108,7 +123,7 @@ public override SymbolMethod GetMethod(ModuleDef module, MethodDef method, int v rootScope.method = symbolMethod; return symbolMethod; } - static readonly ReadOnlyCollection emptySymbolAsyncStepInfos = new ReadOnlyCollection(new SymbolAsyncStepInfo[0]); + static readonly SymbolAsyncStepInfo[] emptySymbolAsyncStepInfos = new SymbolAsyncStepInfo[0]; static bool IsAsyncMethod(MethodDef method) { foreach (var iface in method.DeclaringType.Interfaces) { @@ -128,7 +143,7 @@ int GetKickoffMethod(uint methodRid) { return 0x06000000 + (int)pdbMetaData.TablesStream.ReadStateMachineMethodRow2(rid); } - ReadOnlyCollection ReadSequencePoints(uint methodRid) { + SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { uint documentRid; uint sequencePointsOffset = pdbMetaData.TablesStream.ReadMethodDebugInformationRow2(methodRid, out documentRid); if (sequencePointsOffset == 0) @@ -214,19 +229,21 @@ ReadOnlyCollection ReadSequencePoints(uint methodRid) { Debug.Assert(seqPointsStream.Position == seqPointsStream.Length); } - return new ReadOnlyCollection(ListCache.FreeAndToArray(ref seqPointsBuilder)); + return ListCache.FreeAndToArray(ref seqPointsBuilder); } - static readonly ReadOnlyCollection emptySymbolSequencePoints = new ReadOnlyCollection(new SymbolSequencePoint[0]); + static readonly SymbolSequencePoint[] emptySymbolSequencePoints = new SymbolSequencePoint[0]; - SymbolScopeImpl ReadScope(ModuleDef module, uint methodRid) { + SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { var scopesRidList = pdbMetaData.GetLocalScopeRidList(methodRid); SymbolScopeImpl rootScopeOrNull = null; if (scopesRidList.Count != 0) { + var custInfos = ListCache.AllocList(); var stack = ListCache.AllocList(); var importScopeBlobReader = new ImportScopeBlobReader(module, pdbMetaData.BlobStream); for (int i = 0; i < scopesRidList.Count; i++) { var rid = scopesRidList[i]; uint importScope, variableList, constantList, startOffset; + int token = new MDToken(Table.LocalScope, rid).ToInt32(); uint length = pdbMetaData.TablesStream.ReadLocalScopeRow2(rid, out importScope, out variableList, out constantList, out startOffset); uint endOffset = startOffset + length; @@ -241,23 +258,27 @@ SymbolScopeImpl ReadScope(ModuleDef module, uint methodRid) { } Debug.Assert(parent != null || rootScopeOrNull == null); - var scope = new SymbolScopeImpl(parent, (int)startOffset, (int)endOffset); + custInfos.Clear(); + GetCustomDebugInfos(token, gpContext, custInfos); + var customDebugInfos = custInfos.Count == 0 ? emptyPdbCustomDebugInfos : custInfos.ToArray(); + var scope = new SymbolScopeImpl(this, parent, (int)startOffset, (int)endOffset, customDebugInfos); if (rootScopeOrNull == null) rootScopeOrNull = scope; stack.Add(scope); if (parent != null) parent.childrenList.Add(scope); - scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, importScope); + scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, importScope, gpContext); uint variableListEnd, constantListEnd; GetEndOfLists(rid, out variableListEnd, out constantListEnd); - ReadVariables(scope, variableList, variableListEnd); + ReadVariables(scope, gpContext, variableList, variableListEnd); ReadConstants(scope, constantList, constantListEnd); } ListCache.Free(ref stack); + ListCache.Free(ref custInfos); } - return rootScopeOrNull ?? new SymbolScopeImpl(null, 0, int.MaxValue); + return rootScopeOrNull ?? new SymbolScopeImpl(this, null, 0, int.MaxValue, emptyPdbCustomDebugInfos); } void GetEndOfLists(uint scopeRid, out uint variableListEnd, out uint constantListEnd) { @@ -275,7 +296,7 @@ void GetEndOfLists(uint scopeRid, out uint variableListEnd, out uint constantLis } } - PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope) { + PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope, GenericParamContext gpContext) { if (importScope == 0) return null; const int MAX = 1000; @@ -285,8 +306,10 @@ PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReade Debug.Assert(i < MAX); if (i >= MAX) return null; + int token = new MDToken(Table.ImportScope, importScope).ToInt32(); uint imports = pdbMetaData.TablesStream.ReadImportScopeRow2(importScope, out importScope); var scope = new PdbImportScope(); + GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos); if (result == null) result = scope; if (prevScope != null) @@ -298,7 +321,7 @@ PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReade return result; } - void ReadVariables(SymbolScopeImpl scope, uint variableList, uint variableListEnd) { + void ReadVariables(SymbolScopeImpl scope, GenericParamContext gpContext, uint variableList, uint variableListEnd) { if (variableList == 0) return; Debug.Assert(variableList <= variableListEnd); @@ -311,19 +334,25 @@ void ReadVariables(SymbolScopeImpl scope, uint variableList, uint variableListEn Debug.Assert(table.IsValidRID(variableList)); if (!table.IsValidRID(variableList)) return; + var custInfos = ListCache.AllocList(); for (uint rid = variableList; rid < variableListEnd; rid++) { + int token = new MDToken(Table.LocalVariable, rid).ToInt32(); + custInfos.Clear(); + GetCustomDebugInfos(token, gpContext, custInfos); + var customDebugInfos = custInfos.Count == 0 ? emptyPdbCustomDebugInfos : custInfos.ToArray(); ushort attributes, index; var nameOffset = pdbMetaData.TablesStream.ReadLocalVariableRow2(rid, out attributes, out index); var name = pdbMetaData.StringsStream.Read(nameOffset); - scope.localsList.Add(new SymbolVariableImpl(name, ToSymbolVariableAttributes(attributes), index)); + scope.localsList.Add(new SymbolVariableImpl(name, ToSymbolVariableAttributes(attributes), index, customDebugInfos)); } + ListCache.Free(ref custInfos); } - static SymbolVariableAttributes ToSymbolVariableAttributes(ushort attributes) { - var res = SymbolVariableAttributes.None; + static PdbLocalAttributes ToSymbolVariableAttributes(ushort attributes) { + var res = PdbLocalAttributes.None; const ushort DebuggerHidden = 0x0001; if ((attributes & DebuggerHidden) != 0) - res |= SymbolVariableAttributes.CompilerGenerated; + res |= PdbLocalAttributes.DebuggerHidden; return res; } @@ -343,7 +372,12 @@ void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEn scope.SetConstants(pdbMetaData, constantList, constantListEnd); } - public override void GetCustomDebugInfo(MethodDef method, CilBody body, IList result) { + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + Debug.Assert(method.Module == module); + //TODO: CustomDebugInformation table + } + + public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { //TODO: CustomDebugInformation table } diff --git a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs index 3957dcb31..b894901f7 100644 --- a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs @@ -14,6 +14,7 @@ sealed class SymbolDocumentImpl : SymbolDocument { /*readonly*/ Guid documentType; /*readonly*/ Guid checkSumAlgorithmId; readonly byte[] checkSum; + readonly PdbCustomDebugInfo[] customDebugInfos; string GetDebuggerString() { var sb = new StringBuilder(); @@ -61,13 +62,18 @@ public override byte[] CheckSum { get { return checkSum; } } - public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum) { + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { return customDebugInfos; } + } + + public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum, PdbCustomDebugInfo[] customDebugInfos) { this.url = url; this.language = language; this.languageVendor = languageVendor; this.documentType = documentType; this.checkSumAlgorithmId = checkSumAlgorithmId; this.checkSum = checkSum; + this.customDebugInfos = customDebugInfos; } } } diff --git a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs index 9d32b2c68..502bbd0d1 100644 --- a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs @@ -1,17 +1,17 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.ObjectModel; +using System.Collections.Generic; using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Portable { sealed class SymbolMethodImpl : SymbolMethod { readonly int token; readonly SymbolScope rootScope; - readonly ReadOnlyCollection sequencePoints; + readonly SymbolSequencePoint[] sequencePoints; readonly int iteratorKickoffMethod; readonly int asyncKickoffMethod; readonly uint? asyncCatchHandlerILOffset; - readonly ReadOnlyCollection asyncStepInfos; + readonly SymbolAsyncStepInfo[] asyncStepInfos; public override int Token { get { return token; } @@ -21,7 +21,7 @@ public override SymbolScope RootScope { get { return rootScope; } } - public override ReadOnlyCollection SequencePoints { + public override IList SequencePoints { get { return sequencePoints; } } @@ -37,11 +37,11 @@ public override uint? AsyncCatchHandlerILOffset { get { return asyncCatchHandlerILOffset; } } - public override ReadOnlyCollection AsyncStepInfos { + public override IList AsyncStepInfos { get { return asyncStepInfos; } } - public SymbolMethodImpl(int token, SymbolScope rootScope, ReadOnlyCollection sequencePoints, int iteratorKickoffMethod, int asyncKickoffMethod, uint? asyncCatchHandlerILOffset, ReadOnlyCollection asyncStepInfos) { + public SymbolMethodImpl(int token, SymbolScope rootScope, SymbolSequencePoint[] sequencePoints, int iteratorKickoffMethod, int asyncKickoffMethod, uint? asyncCatchHandlerILOffset, SymbolAsyncStepInfo[] asyncStepInfos) { this.token = token; this.rootScope = rootScope; this.sequencePoints = sequencePoints; diff --git a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs index 8196e62df..4e09d4f1d 100644 --- a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs @@ -2,22 +2,21 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Diagnostics; using dnlib.DotNet.MD; using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Portable { sealed class SymbolScopeImpl : SymbolScope { + readonly PortablePdbReader owner; internal SymbolMethod method; readonly SymbolScopeImpl parent; readonly int startOffset; readonly int endOffset; - readonly ReadOnlyCollection children; - readonly ReadOnlyCollection locals; internal readonly List childrenList; internal readonly List localsList; internal PdbImportScope importScope; + readonly PdbCustomDebugInfo[] customDebugInfos; public override SymbolMethod Method { get { @@ -46,32 +45,36 @@ public override int EndOffset { get { return endOffset; } } - public override ReadOnlyCollection Children { - get { return children; } + public override IList Children { + get { return childrenList; } } - public override ReadOnlyCollection Locals { - get { return locals; } + public override IList Locals { + get { return localsList; } } - public override ReadOnlyCollection Namespaces { + public override IList Namespaces { get { return emptySymbolNamespaces; } } - static readonly ReadOnlyCollection emptySymbolNamespaces = new ReadOnlyCollection(new SymbolNamespace[0]); + static readonly SymbolNamespace[] emptySymbolNamespaces = new SymbolNamespace[0]; + + public override IList CustomDebugInfos { + get { return customDebugInfos; } + } public override PdbImportScope ImportScope { get { return importScope; } } - public SymbolScopeImpl(SymbolScopeImpl parent, int startOffset, int endOffset) { + public SymbolScopeImpl(PortablePdbReader owner, SymbolScopeImpl parent, int startOffset, int endOffset, PdbCustomDebugInfo[] customDebugInfos) { + this.owner = owner; method = null; this.parent = parent; this.startOffset = startOffset; this.endOffset = endOffset; childrenList = new List(); localsList = new List(); - children = new ReadOnlyCollection(childrenList); - locals = new ReadOnlyCollection(localsList); + this.customDebugInfos = customDebugInfos; } IMetaData constantsMetaData; @@ -84,7 +87,7 @@ internal void SetConstants(IMetaData metaData, uint constantList, uint constantL this.constantListEnd = constantListEnd; } - public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext) { + public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { if (constantList >= constantListEnd) return emptyPdbConstants; Debug.Assert(constantsMetaData != null); @@ -102,8 +105,12 @@ public override PdbConstant[] GetConstants(ModuleDef module, GenericParamContext object value; bool b = localConstantSigBlobReader.Read(out type, out value); Debug.Assert(b); - if (b) - res[w++] = new PdbConstant(name, type, value); + if (b) { + var pdbConstant = new PdbConstant(name, type, value); + int token = new MDToken(Table.LocalConstant, rid).ToInt32(); + owner.GetCustomDebugInfos(token, gpContext, pdbConstant.CustomDebugInfos); + res[w++] = pdbConstant; + } Debug.Assert(stream.Position == stream.Length); } } diff --git a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs index 4b67cdf47..3600054bc 100644 --- a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs @@ -5,14 +5,15 @@ namespace dnlib.DotNet.Pdb.Portable { sealed class SymbolVariableImpl : SymbolVariable { readonly string name; - readonly SymbolVariableAttributes attributes; + readonly PdbLocalAttributes attributes; readonly int index; + readonly PdbCustomDebugInfo[] customDebugInfos; public override string Name { get { return name; } } - public override SymbolVariableAttributes Attributes { + public override PdbLocalAttributes Attributes { get { return attributes; } } @@ -20,10 +21,15 @@ public override int Index { get { return index; } } - public SymbolVariableImpl(string name, SymbolVariableAttributes attributes, int index) { + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { return customDebugInfos; } + } + + public SymbolVariableImpl(string name, PdbLocalAttributes attributes, int index, PdbCustomDebugInfo[] customDebugInfos) { this.name = name; this.attributes = attributes; this.index = index; + this.customDebugInfos = customDebugInfos; } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolDocument.cs b/src/DotNet/Pdb/Symbols/SymbolDocument.cs index ad85350eb..d401fcb56 100644 --- a/src/DotNet/Pdb/Symbols/SymbolDocument.cs +++ b/src/DotNet/Pdb/Symbols/SymbolDocument.cs @@ -36,5 +36,10 @@ public abstract class SymbolDocument { /// Gets the checksum /// public abstract byte[] CheckSum { get; } + + /// + /// Gets the custom debug infos + /// + public abstract PdbCustomDebugInfo[] CustomDebugInfos { get; } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolMethod.cs b/src/DotNet/Pdb/Symbols/SymbolMethod.cs index a9a767029..cd64d4cba 100644 --- a/src/DotNet/Pdb/Symbols/SymbolMethod.cs +++ b/src/DotNet/Pdb/Symbols/SymbolMethod.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.ObjectModel; +using System.Collections.Generic; namespace dnlib.DotNet.Pdb.Symbols { /// @@ -20,7 +20,7 @@ public abstract class SymbolMethod { /// /// Gets all sequence points /// - public abstract ReadOnlyCollection SequencePoints { get; } + public abstract IList SequencePoints { get; } /// /// true if this is an iterator method @@ -54,6 +54,6 @@ public bool IsAsyncMethod { /// /// Gets the async step infos if it's an async method () /// - public abstract ReadOnlyCollection AsyncStepInfos { get; } + public abstract IList AsyncStepInfos { get; } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index 12fb28642..a805cd81f 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using dnlib.DotNet.Emit; namespace dnlib.DotNet.Pdb.Symbols { @@ -10,6 +9,12 @@ namespace dnlib.DotNet.Pdb.Symbols { /// Reads symbols from a PDB file /// public abstract class SymbolReader : IDisposable { + /// + /// Called by the owner module before any other methods and properties are called + /// + /// Owner module + public abstract void Initialize(ModuleDef module); + /// /// Gets the user entry point token or 0 if none /// @@ -18,16 +23,15 @@ public abstract class SymbolReader : IDisposable { /// /// Gets all documents /// - public abstract ReadOnlyCollection Documents { get; } + public abstract IList Documents { get; } /// /// Gets a method or returns null if the method doesn't exist in the PDB file /// - /// Module /// Method /// Edit and continue version /// - public abstract SymbolMethod GetMethod(ModuleDef module, MethodDef method, int version); + public abstract SymbolMethod GetMethod(MethodDef method, int version); /// /// Reads custom debug info @@ -35,7 +39,15 @@ public abstract class SymbolReader : IDisposable { /// Method /// Method body /// Updated with custom debug info - public abstract void GetCustomDebugInfo(MethodDef method, CilBody body, IList result); + public abstract void GetCustomDebugInfos(MethodDef method, CilBody body, IList result); + + /// + /// Reads custom debug info + /// + /// Token of a instance + /// Generic parameter context + /// Updated with custom debug info + public abstract void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result); /// /// Cleans up resources diff --git a/src/DotNet/Pdb/Symbols/SymbolScope.cs b/src/DotNet/Pdb/Symbols/SymbolScope.cs index cc70ea1a7..80f08c638 100644 --- a/src/DotNet/Pdb/Symbols/SymbolScope.cs +++ b/src/DotNet/Pdb/Symbols/SymbolScope.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.ObjectModel; +using System.Collections.Generic; namespace dnlib.DotNet.Pdb.Symbols { /// @@ -30,17 +30,22 @@ public abstract class SymbolScope { /// /// Gets all child scopes /// - public abstract ReadOnlyCollection Children { get; } + public abstract IList Children { get; } /// /// Gets all locals defined in this scope /// - public abstract ReadOnlyCollection Locals { get; } + public abstract IList Locals { get; } /// /// Gets all namespaces in this scope /// - public abstract ReadOnlyCollection Namespaces { get; } + public abstract IList Namespaces { get; } + + /// + /// Gets all custom debug infos + /// + public abstract IList CustomDebugInfos { get; } /// /// Gets the import scope or null if none @@ -53,6 +58,6 @@ public abstract class SymbolScope { /// Owner module if a signature must be read from the #Blob /// Generic parameter context /// - public abstract PdbConstant[] GetConstants(ModuleDef module, GenericParamContext gpContext); + public abstract IList GetConstants(ModuleDef module, GenericParamContext gpContext); } } diff --git a/src/DotNet/Pdb/Symbols/SymbolVariable.cs b/src/DotNet/Pdb/Symbols/SymbolVariable.cs index 71e70ae8b..840a23b5d 100644 --- a/src/DotNet/Pdb/Symbols/SymbolVariable.cs +++ b/src/DotNet/Pdb/Symbols/SymbolVariable.cs @@ -15,27 +15,16 @@ public abstract class SymbolVariable { /// /// Gets the attributes /// - public abstract SymbolVariableAttributes Attributes { get; } + public abstract PdbLocalAttributes Attributes { get; } /// /// Gets the index of the variable /// public abstract int Index { get; } - } - - /// - /// Variable flags - /// - [Flags] - public enum SymbolVariableAttributes { - /// - /// No bit is set - /// - None = 0, /// - /// It's a compiler generated variable + /// Gets all custom debug infos /// - CompilerGenerated = 0x00000001, + public abstract PdbCustomDebugInfo[] CustomDebugInfos { get; } } } diff --git a/src/DotNet/PropertyDef.cs b/src/DotNet/PropertyDef.cs index 6bc33c5f4..2da3200d7 100644 --- a/src/DotNet/PropertyDef.cs +++ b/src/DotNet/PropertyDef.cs @@ -3,6 +3,7 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; #if THREAD_SAFE @@ -15,7 +16,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the Property table /// - public abstract class PropertyDef : IHasConstant, IHasCustomAttribute, IHasSemantic, IFullName, IMemberDef { + public abstract class PropertyDef : IHasConstant, IHasCustomAttribute, IHasSemantic, IHasCustomDebugInformation, IFullName, IMemberDef { /// /// The row id in its table /// @@ -144,6 +145,33 @@ protected virtual void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); } + /// + public int HasCustomDebugInformationTag { + get { return 9; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Gets/sets the first getter method. Writing null will clear all get methods. /// @@ -524,6 +552,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(declaringType2), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/StandAloneSig.cs b/src/DotNet/StandAloneSig.cs index 336524d92..b25dd7c87 100644 --- a/src/DotNet/StandAloneSig.cs +++ b/src/DotNet/StandAloneSig.cs @@ -3,12 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; +using dnlib.Threading; + +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif namespace dnlib.DotNet { /// /// A high-level representation of a row in the StandAloneSig table /// - public abstract class StandAloneSig : IHasCustomAttribute, IContainsGenericParameter { + public abstract class StandAloneSig : IHasCustomAttribute, IHasCustomDebugInformation, IContainsGenericParameter { /// /// The row id in its table /// @@ -62,6 +70,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 11; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// Gets/sets the method sig /// @@ -119,6 +154,7 @@ sealed class StandAloneSigMD : StandAloneSig, IMDTokenProviderMD { readonly ModuleDefMD readerModule; readonly uint origRid; + readonly GenericParamContext gpContext; /// public uint OrigRid { @@ -132,6 +168,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// @@ -150,6 +193,7 @@ public StandAloneSigMD(ModuleDefMD readerModule, uint rid, GenericParamContext g this.origRid = rid; this.rid = rid; this.readerModule = readerModule; + this.gpContext = gpContext; uint signature = readerModule.TablesStream.ReadStandAloneSigRow2(origRid); this.signature = readerModule.ReadSignature(signature, gpContext); } diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index dad29e996..337b141a3 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -8,6 +8,7 @@ using dnlib.DotNet.Emit; using dnlib.Threading; using System.Text; +using dnlib.DotNet.Pdb; #if THREAD_SAFE using ThreadSafe = dnlib.Threading.Collections; @@ -19,7 +20,7 @@ namespace dnlib.DotNet { /// /// A high-level representation of a row in the TypeDef table /// - public abstract class TypeDef : ITypeDefOrRef, IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, ITypeOrMethodDef, IListListener, IListListener, IListListener, IListListener, IListListener, IListListener, IMemberRefResolver, IMemberDef { + public abstract class TypeDef : ITypeDefOrRef, IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, ITypeOrMethodDef, IHasCustomDebugInformation, IListListener, IListListener, IListListener, IListListener, IListListener, IListListener, IMemberRefResolver, IMemberDef { /// /// The row id in its table /// @@ -588,6 +589,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 3; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// true if there's at least one in /// @@ -2180,6 +2208,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(this), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// protected override ModuleDef GetModule2_NoLock() { return DeclaringType2_NoLock != null ? null : readerModule; diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index b0d7c8141..8881fad71 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -3,13 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + namespace dnlib.DotNet { /// /// A high-level representation of a row in the TypeRef table /// - public abstract class TypeRef : ITypeDefOrRef, IHasCustomAttribute, IMemberRefParent, IResolutionScope { + public abstract class TypeRef : ITypeDefOrRef, IHasCustomAttribute, IMemberRefParent, IHasCustomDebugInformation, IResolutionScope { /// /// The row id in its table /// @@ -208,6 +215,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + /// + public int HasCustomDebugInformationTag { + get { return 2; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } + /// /// true if it's nested within another /// @@ -423,6 +457,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index 39420f7d7..dd2f4160f 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -3,13 +3,20 @@ using System; using System.Threading; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; using dnlib.Threading; +#if THREAD_SAFE +using ThreadSafe = dnlib.Threading.Collections; +#else +using ThreadSafe = System.Collections.Generic; +#endif + namespace dnlib.DotNet { /// /// A high-level representation of a row in the TypeSpec table /// - public abstract class TypeSpec : ITypeDefOrRef, IHasCustomAttribute, IMemberRefParent { + public abstract class TypeSpec : ITypeDefOrRef, IHasCustomAttribute, IMemberRefParent, IHasCustomDebugInformation { /// /// The row id in its table /// @@ -299,6 +306,33 @@ public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } } + + /// + public int HasCustomDebugInformationTag { + get { return 13; } + } + + /// + public bool HasCustomDebugInfos { + get { return CustomDebugInfos.Count > 0; } + } + + /// + /// Gets all custom debug infos + /// + public ThreadSafe.IList CustomDebugInfos { + get { + if (customDebugInfos == null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected ThreadSafe.IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() { + Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + } /// public override string ToString() { return FullName; @@ -333,8 +367,8 @@ sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD { /// The module where this instance is located readonly ModuleDefMD readerModule; - readonly GenericParamContext gpContext; readonly uint origRid; + readonly GenericParamContext gpContext; readonly uint signatureOffset; /// @@ -357,6 +391,13 @@ protected override void InitializeCustomAttributes() { Interlocked.CompareExchange(ref customAttributes, tmp, null); } + /// + protected override void InitializeCustomDebugInfos() { + var list = ThreadSafeListCreator.Create(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + /// /// Constructor /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 0753c1ff5..c1915b85e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -174,6 +174,7 @@ + @@ -188,6 +189,8 @@ + + From b2ab1e0f92f8b1e1923d66e4da99b4e23806d1b0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 6 Nov 2017 23:28:02 +0100 Subject: [PATCH 053/511] Add PDB file kind property --- src/DotNet/ModuleDef.cs | 5 +++-- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 4 ++++ src/DotNet/Pdb/Managed/PdbReader.cs | 4 ++++ src/DotNet/Pdb/PdbFileKind.cs | 18 ++++++++++++++++++ src/DotNet/Pdb/PdbState.cs | 10 +++++++++- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 4 ++++ src/DotNet/Pdb/Symbols/SymbolReader.cs | 5 +++++ src/dnlib.csproj | 1 + 8 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/DotNet/Pdb/PdbFileKind.cs diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 407d35146..5bd91295a 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1205,8 +1205,9 @@ public ResourceData FindWin32ResourceData(ResourceName type, ResourceName name, /// /// Creates a new /// - public void CreatePdbState() { - SetPdbState(new PdbState(this)); + /// PDB file kind + public void CreatePdbState(PdbFileKind pdbFileKind) { + SetPdbState(new PdbState(this, pdbFileKind)); } /// diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index e6615f348..87281cdb5 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -24,6 +24,10 @@ public SymbolReaderImpl(ISymUnmanagedReader reader) { this.reader = reader; } + public override PdbFileKind PdbFileKind { + get { return PdbFileKind.WindowsPDB; } + } + public override int UserEntryPoint { get { uint token; diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 9d92f93b7..276ad4494 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -31,6 +31,10 @@ sealed class PdbReader : SymbolReader { Dictionary functions; uint entryPt; + public override PdbFileKind PdbFileKind { + get { return PdbFileKind.WindowsPDB; } + } + /// /// The age of PDB file. /// diff --git a/src/DotNet/Pdb/PdbFileKind.cs b/src/DotNet/Pdb/PdbFileKind.cs new file mode 100644 index 000000000..941746f2d --- /dev/null +++ b/src/DotNet/Pdb/PdbFileKind.cs @@ -0,0 +1,18 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb { + /// + /// PDB file kind + /// + public enum PdbFileKind { + /// + /// Windows PDB + /// + WindowsPDB, + + /// + /// Portable PDB + /// + PortablePDB, + } +} diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index ff5114d1c..6735702cf 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -22,6 +22,11 @@ public sealed class PdbState { readonly Lock theLock = Lock.Create(); #endif + /// + /// Gets the PDB file kind + /// + public PdbFileKind PdbFileKind { get; private set; } + /// /// Gets/sets the user entry point method. /// @@ -65,10 +70,12 @@ public bool HasDocuments { /// Constructor /// /// Module - public PdbState(ModuleDef module) { + /// PDB file kind + public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { if (module == null) throw new ArgumentNullException("module"); this.compiler = CalculateCompiler(module); + PdbFileKind = pdbFileKind; } /// @@ -83,6 +90,7 @@ public PdbState(SymbolReader reader, ModuleDefMD module) { throw new ArgumentNullException("module"); this.reader = reader; reader.Initialize(module); + PdbFileKind = reader.PdbFileKind; this.compiler = CalculateCompiler(module); this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 251f2dcaa..9ef9b45c7 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -21,6 +21,10 @@ sealed class PortablePdbReader : SymbolReader { readonly uint timestamp; readonly uint entryPointToken; + public override PdbFileKind PdbFileKind { + get { return PdbFileKind.PortablePDB; } + } + public override int UserEntryPoint { get { return (int)entryPointToken; } } diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index a805cd81f..e32c52d7a 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -15,6 +15,11 @@ public abstract class SymbolReader : IDisposable { /// Owner module public abstract void Initialize(ModuleDef module); + /// + /// Gets the PDB file kind + /// + public abstract PdbFileKind PdbFileKind { get; } + /// /// Gets the user entry point token or 0 if none /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index c1915b85e..6aac8f7b0 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -187,6 +187,7 @@ + From 431965bf451cd3d64beb2a79006b35a45e28284c Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 6 Nov 2017 23:28:26 +0100 Subject: [PATCH 054/511] Read #Pdb stream and add a new PdbStream class and prop --- src/DotNet/MD/CompressedMetaData.cs | 18 ++++++-- src/DotNet/MD/DotNetTableSizes.cs | 20 +++++---- src/DotNet/MD/ENCMetaData.cs | 6 +-- src/DotNet/MD/IMetaData.cs | 10 +++++ src/DotNet/MD/MetaData.cs | 23 +++++++++- src/DotNet/MD/MetaDataCreator.cs | 8 ++-- src/DotNet/MD/PdbStream.cs | 47 ++++++++++++++++++++ src/DotNet/MD/TablesStream.cs | 18 +++++++- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 25 +---------- src/DotNet/Writer/TablesHeap.cs | 3 +- src/dnlib.csproj | 1 + 11 files changed, 134 insertions(+), 45 deletions(-) create mode 100644 src/DotNet/MD/PdbStream.cs diff --git a/src/DotNet/MD/CompressedMetaData.cs b/src/DotNet/MD/CompressedMetaData.cs index 612cdc472..022cea8ed 100644 --- a/src/DotNet/MD/CompressedMetaData.cs +++ b/src/DotNet/MD/CompressedMetaData.cs @@ -24,8 +24,8 @@ public CompressedMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDa } /// - internal CompressedMetaData(MetaDataHeader mdHeader) - : base(mdHeader) { + internal CompressedMetaData(MetaDataHeader mdHeader, bool isStandalonePortablePdb) + : base(mdHeader, isStandalonePortablePdb) { } static CompressedMetaData() { @@ -133,6 +133,15 @@ protected override void InitializeInternal(IImageStream mdStream) { hotStream = null; imageStream = null; continue; + + case "#Pdb": + if (isStandalonePortablePdb && pdbStream == null) { + pdbStream = new PdbStream(imageStream, sh); + imageStream = null; + allStreams.Add(pdbStream); + continue; + } + break; } dns = new DotNetStream(imageStream, sh); imageStream = null; @@ -163,7 +172,10 @@ protected override void InitializeInternal(IImageStream mdStream) { InitializeHotStreams(hotStreams); } - tablesStream.Initialize(); + if (pdbStream != null) + tablesStream.Initialize(pdbStream.TypeSystemTableRows); + else + tablesStream.Initialize(null); } int GetPointerSize() { diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index 0ad9be57d..60a7fecdb 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -11,26 +11,30 @@ sealed class DotNetTableSizes { bool bigStrings; bool bigGuid; bool bigBlob; - IList rowCounts; TableInfo[] tableInfos; + internal static bool IsSystemTable(Table table) { + return table < Table.Document; + } + /// /// Initializes the table sizes /// /// true if #Strings size >= 0x10000 /// true if #GUID size >= 0x10000 /// true if #Blob size >= 0x10000 - /// Count of rows in each table - public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList rowCounts) { + /// Count of rows in each table + /// Count of rows in each table (debug tables) + public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList systemRowCounts, IList debugRowCounts) { this.bigStrings = bigStrings; this.bigGuid = bigGuid; this.bigBlob = bigBlob; - this.rowCounts = rowCounts; foreach (var tableInfo in tableInfos) { + var rowCounts = IsSystemTable(tableInfo.Table) ? systemRowCounts : debugRowCounts; int colOffset = 0; foreach (var colInfo in tableInfo.Columns) { colInfo.Offset = colOffset; - var colSize = GetSize(colInfo.ColumnSize); + var colSize = GetSize(colInfo.ColumnSize, rowCounts); colInfo.Size = colSize; colOffset += colSize + (colSize & 1); } @@ -38,7 +42,7 @@ public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList rowCounts) { if (ColumnSize.Module <= columnSize && columnSize <= ColumnSize.CustomDebugInformation) { int table = (int)(columnSize - ColumnSize.Module); uint count = table >= rowCounts.Count ? 0 : rowCounts[table]; @@ -100,6 +104,8 @@ public TableInfo[] CreateTables(byte majorVersion, byte minorVersion) { return CreateTables(majorVersion, minorVersion, out maxPresentTables); } + internal const int normalMaxTables = (int)Table.CustomDebugInformation + 1; + /// /// Creates the table infos /// @@ -108,8 +114,6 @@ public TableInfo[] CreateTables(byte majorVersion, byte minorVersion) { /// Initialized to max present tables (eg. 42 or 45) /// All table infos (not completely initialized) public TableInfo[] CreateTables(byte majorVersion, byte minorVersion, out int maxPresentTables) { - // The three extra generics tables aren't used by CLR 1.x - const int normalMaxTables = (int)Table.CustomDebugInformation + 1; maxPresentTables = (majorVersion == 1 && minorVersion == 0) ? (int)Table.NestedClass + 1 : normalMaxTables; var tableInfos = new TableInfo[normalMaxTables]; diff --git a/src/DotNet/MD/ENCMetaData.cs b/src/DotNet/MD/ENCMetaData.cs index e0322c9cb..996967073 100644 --- a/src/DotNet/MD/ENCMetaData.cs +++ b/src/DotNet/MD/ENCMetaData.cs @@ -31,8 +31,8 @@ public ENCMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeade } /// - internal ENCMetaData(MetaDataHeader mdHeader) - : base(mdHeader) { + internal ENCMetaData(MetaDataHeader mdHeader, bool isStandalonePortablePdb) + : base(mdHeader, isStandalonePortablePdb) { } /// @@ -116,7 +116,7 @@ protected override void InitializeInternal(IImageStream mdStream) { if (tablesStream == null) throw new BadImageFormatException("Missing MD stream"); - tablesStream.Initialize(); + tablesStream.Initialize(null); // The pointer tables are used iff row count != 0 hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty; diff --git a/src/DotNet/MD/IMetaData.cs b/src/DotNet/MD/IMetaData.cs index b0b1b7dc4..fb6a166b0 100644 --- a/src/DotNet/MD/IMetaData.cs +++ b/src/DotNet/MD/IMetaData.cs @@ -21,6 +21,11 @@ public interface IMetaData : IDisposable { /// bool IsCompressed { get; } + /// + /// true if this is standalone Portable PDB metadata + /// + bool IsStandalonePortablePdb { get; } + /// /// Gets the .NET header /// @@ -76,6 +81,11 @@ public interface IMetaData : IDisposable { /// TablesStream TablesStream { get; } + /// + /// Returns the #Pdb stream or null if it's not a standalone portable PDB file + /// + PdbStream PdbStream { get; } + /// /// Gets all streams /// diff --git a/src/DotNet/MD/MetaData.cs b/src/DotNet/MD/MetaData.cs index b68e7ca54..848734330 100644 --- a/src/DotNet/MD/MetaData.cs +++ b/src/DotNet/MD/MetaData.cs @@ -59,11 +59,23 @@ abstract class MetaData : IMetaData { /// protected TablesStream tablesStream; + /// + /// The #Pdb stream + /// + protected PdbStream pdbStream; + /// /// All the streams that are present in the PE image /// protected ThreadSafe.IList allStreams; + /// + public bool IsStandalonePortablePdb { + get { return isStandalonePortablePdb; } + } + /// true if this is standalone Portable PDB metadata + protected readonly bool isStandalonePortablePdb; + uint[] fieldRidToTypeDefRid; uint[] methodRidToTypeDefRid; uint[] eventRidToTypeDefRid; @@ -240,6 +252,11 @@ public TablesStream TablesStream { get { return tablesStream; } } + /// + public PdbStream PdbStream { + get { return pdbStream; } + } + /// public ThreadSafe.IList AllStreams { get { return allStreams; } @@ -257,6 +274,7 @@ protected MetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeade this.peImage = peImage; this.cor20Header = cor20Header; this.mdHeader = mdHeader; + isStandalonePortablePdb = false; } catch { if (peImage != null) @@ -265,11 +283,12 @@ protected MetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeade } } - internal MetaData(MetaDataHeader mdHeader) { + internal MetaData(MetaDataHeader mdHeader, bool isStandalonePortablePdb) { this.allStreams = ThreadSafeListCreator.Create(); this.peImage = null; this.cor20Header = null; this.mdHeader = mdHeader; + this.isStandalonePortablePdb = isStandalonePortablePdb; } /// @@ -280,6 +299,8 @@ public void Initialize(IImageStream mdStream) { if (tablesStream == null) throw new BadImageFormatException("Missing MD stream"); + if (isStandalonePortablePdb && pdbStream == null) + throw new BadImageFormatException("Missing #Pdb stream"); InitializeNonExistentHeaps(); } diff --git a/src/DotNet/MD/MetaDataCreator.cs b/src/DotNet/MD/MetaDataCreator.cs index 31bba7905..dcf6e10e5 100644 --- a/src/DotNet/MD/MetaDataCreator.cs +++ b/src/DotNet/MD/MetaDataCreator.cs @@ -184,12 +184,12 @@ static MetaData Create(IPEImage peImage, bool verify) { } /// - /// Create a instance + /// Create a standalone portable PDB instance /// /// Metadata stream /// true if we should verify that it's a .NET PE file /// A new instance - internal static MetaData Create(IImageStream mdStream, bool verify) { + internal static MetaData CreateStandalonePortablePDB(IImageStream mdStream, bool verify) { MetaData md = null; try { var mdHeader = new MetaDataHeader(mdStream, verify); @@ -202,11 +202,11 @@ internal static MetaData Create(IImageStream mdStream, bool verify) { switch (GetMetaDataType(mdHeader.StreamHeaders)) { case MetaDataType.Compressed: - md = new CompressedMetaData(mdHeader); + md = new CompressedMetaData(mdHeader, true); break; case MetaDataType.ENC: - md = new ENCMetaData(mdHeader); + md = new ENCMetaData(mdHeader, true); break; default: diff --git a/src/DotNet/MD/PdbStream.cs b/src/DotNet/MD/PdbStream.cs new file mode 100644 index 000000000..5d842caab --- /dev/null +++ b/src/DotNet/MD/PdbStream.cs @@ -0,0 +1,47 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.IO; + +namespace dnlib.DotNet.MD { + /// + /// #Pdb stream + /// + public sealed class PdbStream : HeapStream { + /// + /// Gets the PDB id + /// + public byte[] Id { get; private set; } + + /// + /// Gets the entry point token or 0 + /// + public MDToken EntryPoint { get; private set; } + + /// + /// Gets the referenced type system tables in the PE metadata file + /// + public ulong ReferencedTypeSystemTables { get; private set; } + + /// + /// Gets all type system table rows. This array has exactly 64 elements. + /// + public uint[] TypeSystemTableRows { get; private set; } + + /// + public PdbStream(IImageStream imageStream, StreamHeader streamHeader) + : base(imageStream, streamHeader) { + using (var stream = GetClonedImageStream()) { + Id = stream.ReadBytes(20); + EntryPoint = new MDToken(stream.ReadUInt32()); + var tables = stream.ReadUInt64(); + ReferencedTypeSystemTables = tables; + var rows = new uint[64]; + for (int i = 0; i < rows.Length; i++, tables >>= 1) { + if (((uint)tables & 1) != 0) + rows[i] = stream.ReadUInt32(); + } + TypeSystemTableRows = rows; + } + } + } +} diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 532293c6a..1f849d8d3 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -219,7 +219,8 @@ public TablesStream(IImageStream imageStream, StreamHeader streamHeader) /// /// Initializes MD tables /// - public void Initialize() { + /// Type system table rows (from #Pdb stream) + public void Initialize(uint[] typeSystemTableRows) { if (initialized) throw new Exception("Initialize() has already been called"); initialized = true; @@ -235,6 +236,8 @@ public void Initialize() { int maxPresentTables; var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables); + if (typeSystemTableRows != null) + maxPresentTables = DotNetTableSizes.normalMaxTables; mdTables = new MDTable[tableInfos.Length]; ulong valid = validMask; @@ -251,7 +254,18 @@ public void Initialize() { if (HasExtraData) extraData = imageStream.ReadUInt32(); - dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes); + var debugSizes = sizes; + if (typeSystemTableRows != null) { + debugSizes = new uint[sizes.Length]; + for (int i = 0; i < 64; i++) { + if (DotNetTableSizes.IsSystemTable((Table)i)) + debugSizes[i] = typeSystemTableRows[i]; + else + debugSizes[i] = sizes[i]; + } + } + + dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes, debugSizes); var currentPos = (FileOffset)imageStream.Position; foreach (var mdTable in mdTables) { diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 9ef9b45c7..f2958b691 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -17,16 +17,12 @@ sealed class PortablePdbReader : SymbolReader { readonly IMetaData pdbMetaData; SymbolDocument[] documents; - readonly Guid pdbId; - readonly uint timestamp; - readonly uint entryPointToken; - public override PdbFileKind PdbFileKind { get { return PdbFileKind.PortablePDB; } } public override int UserEntryPoint { - get { return (int)entryPointToken; } + get { return pdbMetaData.PdbStream.EntryPoint.ToInt32(); } } public override IList Documents { @@ -35,16 +31,7 @@ public override IList Documents { public PortablePdbReader(IMetaData moduleMetaData, IImageStream pdbStream) { this.moduleMetaData = moduleMetaData; - pdbMetaData = MetaDataCreator.Create(pdbStream, true); - var pdbHeap = GetPdbStream(pdbMetaData.AllStreams); - Debug.Assert(pdbHeap != null); - if (pdbHeap != null) { - using (var stream = pdbHeap.GetClonedImageStream()) { - pdbId = new Guid(stream.ReadBytes(16)); - timestamp = stream.ReadUInt32(); - entryPointToken = stream.ReadUInt32(); - } - } + pdbMetaData = MetaDataCreator.CreateStandalonePortablePDB(pdbStream, true); } public override void Initialize(ModuleDef module) { @@ -52,14 +39,6 @@ public override void Initialize(ModuleDef module) { documents = ReadDocuments(); } - static DotNetStream GetPdbStream(IList streams) { - foreach (var stream in streams) { - if (stream.Name == "#Pdb") - return stream; - } - return null; - } - static Guid GetLanguageVendor(Guid language) { if (language == Constants.LanguageCSharp || language == Constants.LanguageVisualBasic || language == Constants.LanguageFSharp) return Constants.LanguageVendorMicrosoft; diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 22334fa2e..35379ddea 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -304,7 +304,8 @@ public void CalculateLength() { var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion); - dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, GetRowCounts()); + var rowCounts = GetRowCounts(); + dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, rowCounts, rowCounts); for (int i = 0; i < Tables.Length; i++) Tables[i].TableInfo = tableInfos[i]; diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 6aac8f7b0..b461499eb 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -141,6 +141,7 @@ + From 8a194c38da6131266e29f5675d09732fb1ecc3e3 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 6 Nov 2017 23:28:37 +0100 Subject: [PATCH 055/511] Read portable PDB custom debug infos --- src/DotNet/MD/IMetaData.cs | 8 + src/DotNet/MD/MetaData.cs | 7 + src/DotNet/MD/TablesStream_Read.cs | 15 + src/DotNet/Pdb/CustomDebugInfoGuids.cs | 23 ++ src/DotNet/Pdb/PdbCustomDebugInfo.cs | 364 +++++++++++++++++++ src/DotNet/Pdb/PdbCustomDebugInfoReader.cs | 238 ++++++++++-- src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs | 1 - src/DotNet/Pdb/Portable/PortablePdbReader.cs | 26 +- src/dnlib.csproj | 1 + 9 files changed, 649 insertions(+), 34 deletions(-) create mode 100644 src/DotNet/Pdb/CustomDebugInfoGuids.cs diff --git a/src/DotNet/MD/IMetaData.cs b/src/DotNet/MD/IMetaData.cs index fb6a166b0..f9b990a56 100644 --- a/src/DotNet/MD/IMetaData.cs +++ b/src/DotNet/MD/IMetaData.cs @@ -349,5 +349,13 @@ public interface IMetaData : IDisposable { /// Owner Method rid /// uint GetStateMachineMethodRid(uint methodRid); + + /// + /// Finds all CustomDebugInformation rids owned by in table + /// + /// A HasCustomDebugInformation table + /// Owner rid + /// A instance containing the valid CustomDebugInformation rids + RidList GetCustomDebugInformationRidList(Table table, uint rid); } } diff --git a/src/DotNet/MD/MetaData.cs b/src/DotNet/MD/MetaData.cs index 848734330..c13d1acb3 100644 --- a/src/DotNet/MD/MetaData.cs +++ b/src/DotNet/MD/MetaData.cs @@ -855,6 +855,13 @@ public uint GetStateMachineMethodRid(uint methodRid) { return list.Length == 0 ? 0 : list[0]; } + public RidList GetCustomDebugInformationRidList(Table table, uint rid) { + uint codedToken; + if (!CodedToken.HasCustomDebugInformation.Encode(new MDToken(table, rid), out codedToken)) + return RidList.Empty; + return FindAllRows(tablesStream.CustomDebugInformationTable, 0, codedToken); + } + /// public void Dispose() { Dispose(true); diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index b2ec924f6..7a3f5ab88 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -1795,6 +1795,21 @@ internal uint ReadStateMachineMethodRow2(uint rid) { #endif } + internal uint ReadCustomDebugInformationRow2(uint rid, out uint kind) { + var table = CustomDebugInformationTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + reader.Position += columns[0].Size; + kind = columns[1].Read(reader); + return columns[2].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + /// /// Reads a column /// diff --git a/src/DotNet/Pdb/CustomDebugInfoGuids.cs b/src/DotNet/Pdb/CustomDebugInfoGuids.cs new file mode 100644 index 000000000..bfa2e3c79 --- /dev/null +++ b/src/DotNet/Pdb/CustomDebugInfoGuids.cs @@ -0,0 +1,23 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb { + /// + /// Custom debug info guids + /// + public static class CustomDebugInfoGuids { +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + // Roslyn: PortableCustomDebugInfoKinds.cs + public static readonly Guid AsyncMethodSteppingInformationBlob = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8"); + public static readonly Guid DefaultNamespace = new Guid("58b2eab6-209f-4e4e-a22c-b2d0f910c782"); + public static readonly Guid DynamicLocalVariables = new Guid("83C563C4-B4F3-47D5-B824-BA5441477EA8"); + public static readonly Guid EmbeddedSource = new Guid("0E8A571B-6926-466E-B4AD-8AB04611F5FE"); + public static readonly Guid EncLambdaAndClosureMap = new Guid("A643004C-0240-496F-A783-30D64F4979DE"); + public static readonly Guid EncLocalSlotMap = new Guid("755F52A8-91C5-45BE-B4B8-209571E552BD"); + public static readonly Guid SourceLink = new Guid("CC110556-A091-4D38-9FEC-25AB9A351A6A"); + public static readonly Guid StateMachineHoistedLocalScopes = new Guid("6DA9A61E-F8C7-4874-BE62-68BC5630DF71"); + public static readonly Guid TupleElementNames = new Guid("ED9FDF71-8879-4747-8ED3-FE5EDE3CE710"); +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member + } +} diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 9e342b673..fded427be 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -60,6 +60,41 @@ public enum PdbCustomDebugInfoKind { /// /// TupleElementNames, + + /// + /// Unknown + /// + Unknown = int.MinValue, + + /// + /// + /// + TupleElementNames_PortablePdb, + + /// + /// + /// + AsyncMethodSteppingInformation, + + /// + /// + /// + DefaultNamespace, + + /// + /// + /// + DynamicLocalVariables, + + /// + /// + /// + EmbeddedSource, + + /// + /// + /// + SourceLink, } /// @@ -70,6 +105,11 @@ public abstract class PdbCustomDebugInfo { /// Gets the custom debug info kind /// public abstract PdbCustomDebugInfoKind Kind { get; } + + /// + /// Gets the custom debug info guid, see + /// + public abstract Guid Guid { get; } } /// @@ -78,6 +118,7 @@ public abstract class PdbCustomDebugInfo { /// public sealed class PdbUnknownCustomDebugInfo : PdbCustomDebugInfo { readonly PdbCustomDebugInfoKind kind; + readonly Guid guid; readonly byte[] data; /// @@ -87,6 +128,13 @@ public override PdbCustomDebugInfoKind Kind { get { return kind; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return guid; } + } + /// /// Gets the data /// @@ -104,6 +152,20 @@ public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data) { throw new ArgumentNullException("data"); this.kind = kind; this.data = data; + guid = Guid.Empty; + } + + /// + /// Constructor + /// + /// Custom debug info guid + /// Raw custom debug info data + public PdbUnknownCustomDebugInfo(Guid guid, byte[] data) { + if (data == null) + throw new ArgumentNullException("data"); + this.kind = PdbCustomDebugInfoKind.Unknown; + this.data = data; + this.guid = guid; } } @@ -120,6 +182,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.UsingGroups; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + /// /// Gets the using counts /// @@ -156,6 +225,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.ForwardMethodInfo; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + /// /// Gets/sets the referenced method /// @@ -192,6 +268,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.ForwardModuleInfo; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + /// /// Gets/sets the referenced method /// @@ -261,6 +344,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.StateMachineHoistedLocalScopes; } + } + /// /// Gets the scopes /// @@ -295,6 +385,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.StateMachineTypeName; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + /// /// Gets/sets the state machine type /// @@ -328,6 +425,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.DynamicLocals; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + /// /// Gets the dynamic locals /// @@ -432,6 +536,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.EncLocalSlotMap; } + } + /// /// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLocalSlotMap /// @@ -463,6 +574,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.EditAndContinueLambdaMap; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.EncLambdaAndClosureMap; } + } + /// /// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLambdaAndClosureMap /// @@ -494,6 +612,13 @@ public override PdbCustomDebugInfoKind Kind { get { return PdbCustomDebugInfoKind.TupleElementNames; } } + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + /// /// Gets the tuple element names /// @@ -600,4 +725,243 @@ public PdbTupleElementNames(int capacity) { tupleElementNames = ThreadSafeListCreator.Create(capacity); } } + + /// + /// Contains tuple element names for local variables and constants + /// + public sealed class PortablePdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo { + readonly ThreadSafe.IList names; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.TupleElementNames_PortablePdb; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.TupleElementNames; } + } + + /// + /// Gets the tuple element names + /// + public ThreadSafe.IList Names { + get { return names; } + } + + /// + /// Constructor + /// + public PortablePdbTupleElementNamesCustomDebugInfo() { + names = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Initial capacity of + public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) { + names = ThreadSafeListCreator.Create(capacity); + } + } + + /// + /// Async method stepping info + /// + public sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { + readonly ThreadSafe.IList asyncStepInfos; + + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.AsyncMethodSteppingInformation; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob; } + } + + /// + /// Gets the catch handler instruction or null + /// + public Instruction CatchHandler { get; set; } + + /// + /// Gets all async step infos + /// + public ThreadSafe.IList AsyncStepInfos { + get { return asyncStepInfos; } + } + + /// + /// Constructor + /// + public PdbAsyncMethodSteppingInformationCustomDebugInfo() { + asyncStepInfos = ThreadSafeListCreator.Create(); + } + } + + /// + /// Default namespace + /// + public sealed class PdbDefaultNamespaceCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.DefaultNamespace; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.DefaultNamespace; } + } + + /// + /// Gets the default namespace + /// + public string Namespace { get; set; } + + /// + /// Constructor + /// + public PdbDefaultNamespaceCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// Default namespace + public PdbDefaultNamespaceCustomDebugInfo(string defaultNamespace) { + Namespace = defaultNamespace; + } + } + + /// + /// Dynamic flags + /// + public sealed class PdbDynamicLocalVariablesCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.DynamicLocalVariables; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.DynamicLocalVariables; } + } + + /// + /// Gets/sets the dynamic flags + /// + public bool[] Flags { get; set; } + + /// + /// Constructor + /// + public PdbDynamicLocalVariablesCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// Dynamic flags + public PdbDynamicLocalVariablesCustomDebugInfo(bool[] flags) { + Flags = flags; + } + } + + /// + /// Contains the source code + /// + public sealed class PdbEmbeddedSourceCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.EmbeddedSource; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.EmbeddedSource; } + } + + /// + /// Gets the source code blob. + /// + /// It's not decompressed and converted to a string because the encoding isn't specified. + /// + /// https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#embedded-source-c-and-vb-compilers + /// + public byte[] SourceCodeBlob { get; set; } + + /// + /// Constructor + /// + public PdbEmbeddedSourceCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// Source code blob + public PdbEmbeddedSourceCustomDebugInfo(byte[] sourceCodeBlob) { + SourceCodeBlob = sourceCodeBlob; + } + } + + /// + /// Contains the source link file + /// + public sealed class PdbSourceLinkCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.SourceLink; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return CustomDebugInfoGuids.SourceLink; } + } + + /// + /// Gets the source link file contents + /// + public byte[] SourceLinkBlob { get; set; } + + /// + /// Constructor + /// + public PdbSourceLinkCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// Source link file contents + public PdbSourceLinkCustomDebugInfo(byte[] sourceLinkBlob) { + SourceLinkBlob = sourceLinkBlob; + } + } } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs index 556e26d6a..2e6eb6975 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Compression; using System.Text; using dnlib.DotNet.Emit; +using dnlib.DotNet.MD; using dnlib.IO; using dnlib.Threading; @@ -27,21 +29,25 @@ struct PdbCustomDebugInfoReader : IDisposable { /// Place all custom debug info in this list /// Custom debug info from the PDB file public static void Read(MethodDef method, CilBody body, IList result, byte[] data) { - Read(method, body, result, MemoryImageStream.Create(data)); + try { + using (var reader = new PdbCustomDebugInfoReader(method, body, MemoryImageStream.Create(data))) + reader.Read(result); + } + catch (ArgumentException) { + } + catch (OutOfMemoryException) { + } + catch (IOException) { + } } - /// - /// Reads custom debug info - /// - /// Method - /// The method's body. Needs to be provided by the caller since we're called from - /// PDB-init code when the Body property hasn't been initialized yet - /// Place all custom debug info in this list - /// Custom debug info from the PDB file - public static void Read(MethodDef method, CilBody body, IList result, IBinaryReader stream) { + public static PdbCustomDebugInfo ReadPortablePdb(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, Guid kind, byte[] data) { try { - using (var reader = new PdbCustomDebugInfoReader(method, body, result, stream)) - reader.Read(); + using (var reader = new PdbCustomDebugInfoReader(module, typeOpt, bodyOpt, gpContext, MemoryImageStream.Create(data))) { + var cdi = reader.ReadPortablePdb(kind); + Debug.Assert(reader.reader.Position == reader.reader.Length); + return cdi; + } } catch (ArgumentException) { } @@ -49,21 +55,164 @@ public static void Read(MethodDef method, CilBody body, IList result; + readonly ModuleDef module; + readonly TypeDef typeOpt; + readonly CilBody bodyOpt; + readonly GenericParamContext gpContext; readonly IBinaryReader reader; - PdbCustomDebugInfoReader(MethodDef method, CilBody body, IList result, IBinaryReader reader) { - this.method = method; - this.body = body; - this.result = result; + PdbCustomDebugInfoReader(MethodDef method, CilBody body, IBinaryReader reader) { + module = method.Module; + typeOpt = method.DeclaringType; + bodyOpt = body; + gpContext = GenericParamContext.Create(method); + this.reader = reader; + } + + PdbCustomDebugInfoReader(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, IBinaryReader reader) { + this.module = module; + this.typeOpt = typeOpt; + this.bodyOpt = bodyOpt; + this.gpContext = gpContext; this.reader = reader; } - void Read() { + PdbCustomDebugInfo ReadPortablePdb(Guid kind) { + if (kind == CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob) + return ReadAsyncMethodSteppingInformationBlob(); + if (kind == CustomDebugInfoGuids.DefaultNamespace) + return ReadDefaultNamespace(); + if (kind == CustomDebugInfoGuids.DynamicLocalVariables) + return ReadDynamicLocalVariables(reader.Length); + if (kind == CustomDebugInfoGuids.EmbeddedSource) + return ReadEmbeddedSource(); + if (kind == CustomDebugInfoGuids.EncLambdaAndClosureMap) + return ReadEncLambdaAndClosureMap(reader.Length); + if (kind == CustomDebugInfoGuids.EncLocalSlotMap) + return ReadEncLocalSlotMap(reader.Length); + if (kind == CustomDebugInfoGuids.SourceLink) + return ReadSourceLink(); + if (kind == CustomDebugInfoGuids.StateMachineHoistedLocalScopes) + return ReadStateMachineHoistedLocalScopes_PortablePDB(); + if (kind == CustomDebugInfoGuids.TupleElementNames) + return ReadTupleElementNames_PortablePDB(); + Debug.Fail("Unknown custom debug info guid: " + kind.ToString()); + return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); + } + + PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { + if (bodyOpt == null) + return null; + uint catchHandlerOffset = reader.ReadUInt32() - 1; + Instruction catchHandler; + if (catchHandlerOffset == uint.MaxValue) + catchHandler = null; + else { + catchHandler = GetInstruction(catchHandlerOffset); + Debug.Assert(catchHandler != null); + if (catchHandler == null) + return null; + } + var asyncInfo = new PdbAsyncMethodSteppingInformationCustomDebugInfo(); + asyncInfo.CatchHandler = catchHandler; + while (reader.Position < reader.Length) { + var yieldInstr = GetInstruction(reader.ReadUInt32()); + Debug.Assert(yieldInstr != null); + if (yieldInstr == null) + return null; + uint resumeOffset = reader.ReadUInt32(); + var moveNextRid = reader.ReadCompressedUInt32(); + var moveNextToken = new MDToken(Table.Method, moveNextRid); + MethodDef moveNextMethod; + Instruction resumeInstr; + if (gpContext.Method != null && moveNextToken == gpContext.Method.MDToken) { + moveNextMethod = gpContext.Method; + resumeInstr = GetInstruction(resumeOffset); + } + else { + moveNextMethod = module.ResolveToken(moveNextToken, gpContext) as MethodDef; + Debug.Assert(moveNextMethod != null); + if (moveNextMethod == null) + return null; + resumeInstr = GetInstruction(moveNextMethod, resumeOffset); + } + Debug.Assert(resumeInstr != null); + if (resumeInstr == null) + return null; + asyncInfo.AsyncStepInfos.Add(new PdbAsyncStepInfo(yieldInstr, moveNextMethod, resumeInstr)); + } + return asyncInfo; + } + + PdbCustomDebugInfo ReadDefaultNamespace() { + var defaultNs = Encoding.UTF8.GetString(reader.ReadRemainingBytes()); + return new PdbDefaultNamespaceCustomDebugInfo(defaultNs); + } + + PdbCustomDebugInfo ReadDynamicLocalVariables(long recPosEnd) { + var flags = new bool[(int)reader.Length * 8]; + int w = 0; + while (reader.Position < reader.Length) { + int b = reader.ReadByte(); + for (int i = 1; i < 0x100; i <<= 1) + flags[w++] = (b & i) != 0; + } + return new PdbDynamicLocalVariablesCustomDebugInfo(flags); + } + + PdbCustomDebugInfo ReadEmbeddedSource() { + return new PdbEmbeddedSourceCustomDebugInfo(reader.ReadRemainingBytes()); + } + + PdbCustomDebugInfo ReadEncLambdaAndClosureMap(long recPosEnd) { + var data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLambdaMapCustomDebugInfo(data); + } + + PdbCustomDebugInfo ReadEncLocalSlotMap(long recPosEnd) { + var data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); + } + + PdbCustomDebugInfo ReadSourceLink() { + return new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); + } + + PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes_PortablePDB() { + if (bodyOpt == null) + return null; + int count = (int)(reader.Length / 8); + var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); + for (int i = 0; i < count; i++) { + uint startOffset = reader.ReadUInt32(); + uint length = reader.ReadUInt32(); + if (startOffset == 0 && length == 0) + smScope.Scopes.Add(new StateMachineHoistedLocalScope()); + else { + var start = GetInstruction(startOffset); + var end = GetInstruction(startOffset + length); + Debug.Assert(start != null); + if (start == null) + return null; + smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); + } + } + return smScope; + } + + PdbCustomDebugInfo ReadTupleElementNames_PortablePDB() { + var tupleListRec = new PortablePdbTupleElementNamesCustomDebugInfo(); + while (reader.Position < reader.Length) { + var name = ReadUTF8Z(reader.Length); + tupleListRec.Names.Add(name); + } + return tupleListRec; + } + + void Read(IList result) { if (reader.Length < 4) return; int version = reader.ReadByte(); @@ -122,18 +271,20 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { return usingCountRec; case PdbCustomDebugInfoKind.ForwardMethodInfo: - method = this.method.Module.ResolveToken(reader.ReadUInt32(), GenericParamContext.Create(this.method)) as IMethodDefOrRef; + method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef; if (method == null) return null; return new PdbForwardMethodInfoCustomDebugInfo(method); case PdbCustomDebugInfoKind.ForwardModuleInfo: - method = this.method.Module.ResolveToken(reader.ReadUInt32(), GenericParamContext.Create(this.method)) as IMethodDefOrRef; + method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef; if (method == null) return null; return new PdbForwardModuleInfoCustomDebugInfo(method); case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: + if (bodyOpt == null) + return null; count = reader.ReadInt32(); if (count < 0) return null; @@ -168,6 +319,8 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { return new PdbStateMachineTypeNameCustomDebugInfo(type); case PdbCustomDebugInfoKind.DynamicLocals: + if (bodyOpt == null) + return null; count = reader.ReadInt32(); const int dynLocalRecSize = 64 + 4 + 4 + 2 * 64; if (reader.Position + (long)(uint)count * dynLocalRecSize > recPosEnd) @@ -188,14 +341,14 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { localIndex = reader.ReadInt32(); // 'const' locals have index -1 but they're encoded as 0 by Roslyn - if (localIndex != 0 && (uint)localIndex >= (uint)body.Variables.Count) + if (localIndex != 0 && (uint)localIndex >= (uint)bodyOpt.Variables.Count) return null; var nameEndPos = reader.Position + 2 * 64; name = ReadUnicodeZ(nameEndPos, needZeroChar: false); reader.Position = nameEndPos; - local = localIndex < body.Variables.Count ? body.Variables[localIndex] : null; + local = localIndex < bodyOpt.Variables.Count ? bodyOpt.Variables[localIndex] : null; // Roslyn writes 0 to localIndex if it's a 'const' local, try to undo that now if (localIndex == 0 && local != null && local.Name != name) local = null; @@ -208,14 +361,14 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { return dynLocListRec; case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: - data = reader.ReadBytes((int)(recPosEnd - reader.Position)); - return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); + return ReadEncLocalSlotMap(recPosEnd); case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: - data = reader.ReadBytes((int)(recPosEnd - reader.Position)); - return new PdbEditAndContinueLambdaMapCustomDebugInfo(data); + return ReadEncLambdaAndClosureMap(recPosEnd); case PdbCustomDebugInfoKind.TupleElementNames: + if (bodyOpt == null) + return null; count = reader.ReadInt32(); if (count < 0) return null; @@ -251,9 +404,9 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { return null; } else { - if ((uint)localIndex >= (uint)body.Variables.Count) + if ((uint)localIndex >= (uint)bodyOpt.Variables.Count) return null; - local = body.Variables[localIndex]; + local = bodyOpt.Variables[localIndex]; } if (local != null && local.Name == name) @@ -273,7 +426,9 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { } TypeDef GetNestedType(string name) { - foreach (var type in method.DeclaringType.NestedTypes.GetSafeEnumerable()) { + if (typeOpt == null) + return null; + foreach (var type in typeOpt.NestedTypes.GetSafeEnumerable()) { if (UTF8String.IsNullOrEmpty(type.Namespace)) { if (type.Name == name) return type; @@ -325,6 +480,27 @@ string ReadUTF8Z(long recPosEnd) { } Instruction GetInstruction(uint offset) { + var instructions = bodyOpt.Instructions; + int lo = 0, hi = instructions.Count - 1; + while (lo <= hi && hi != -1) { + int i = (lo + hi) / 2; + var instr = instructions[i]; + if (instr.Offset == offset) + return instr; + if (offset < instr.Offset) + hi = i - 1; + else + lo = i + 1; + } + return null; + } + + static Instruction GetInstruction(MethodDef method, uint offset) { + if (method == null) + return null; + var body = method.Body; + if (body == null) + return null; var instructions = body.Instructions; int lo = 0, hi = instructions.Count - 1; while (lo <= hi && hi != -1) { diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs index e68177c80..1b0c1225a 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs @@ -3,7 +3,6 @@ // C# & Visual Basic compiler's Custom Debug Info is "documented" in source code only, see Roslyn classes: // CustomDebugInfoReader, CustomDebugInfoWriter, CustomDebugInfoEncoder -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index f2958b691..25b28b084 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -357,11 +357,33 @@ void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEn public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { Debug.Assert(method.Module == module); - //TODO: CustomDebugInformation table + GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body); } public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { - //TODO: CustomDebugInformation table + GetCustomDebugInfos(token, gpContext, result, null, null); + } + + void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result, MethodDef methodOpt, CilBody bodyOpt) { + var mdToken = new MDToken(token); + var ridList = pdbMetaData.GetCustomDebugInformationRidList(mdToken.Table, mdToken.Rid); + if (ridList.Count == 0) + return; + var typeOpt = methodOpt == null ? null : methodOpt.DeclaringType; + for (int i = 0; i < ridList.Count; i++) { + var rid = ridList[i]; + uint kind; + uint value = pdbMetaData.TablesStream.ReadCustomDebugInformationRow2(rid, out kind); + var guid = pdbMetaData.GuidStream.Read(kind); + var data = pdbMetaData.BlobStream.Read(value); + Debug.Assert(guid != null && data != null); + if (guid == null || data == null) + continue; + var cdi = PdbCustomDebugInfoReader.ReadPortablePdb(module, typeOpt, bodyOpt, gpContext, guid.Value, data); + Debug.Assert(cdi != null); + if (cdi != null) + result.Add(cdi); + } } public override void Dispose() { diff --git a/src/dnlib.csproj b/src/dnlib.csproj index b461499eb..815a8fac6 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -177,6 +177,7 @@ + From 26ef2afc6ae3267312855996be986f0195430a2e Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:48:02 +0100 Subject: [PATCH 056/511] Remove unecessary usings --- src/DotNet/MD/TablesStream.cs | 1 - src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 1 - src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 1 - src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 1 - src/DotNet/Pdb/Managed/DbiFunction.cs | 3 +-- src/DotNet/Pdb/Managed/DbiNamespace.cs | 1 - src/DotNet/Pdb/Managed/PdbReader.cs | 1 - src/DotNet/Pdb/PdbCustomDebugInfoReader.cs | 1 - src/DotNet/Pdb/PdbDocument.cs | 1 - src/DotNet/Pdb/PdbMethod.cs | 8 -------- src/DotNet/Pdb/Symbols/SymbolVariable.cs | 1 - src/DotNet/TypeDef.cs | 1 - src/DotNet/UTF8String.cs | 3 +-- src/IO/MemoryImageStream.cs | 3 +-- 14 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 1f849d8d3..981cc451f 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -2,7 +2,6 @@ using System; using dnlib.IO; -using dnlib.PE; using dnlib.Threading; namespace dnlib.DotNet.MD { diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index c33fb65d9..5e9abdad0 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System; using System.Collections.Generic; using System.Diagnostics.SymbolStore; using System.Threading; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 87281cdb5..9b7086b18 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; -using System.Threading; using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs index f87ab0e93..daeb695e9 100644 --- a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Threading; using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Dss { diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index fe236facf..d6347be74 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -1,8 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; -using System.Threading; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; diff --git a/src/DotNet/Pdb/Managed/DbiNamespace.cs b/src/DotNet/Pdb/Managed/DbiNamespace.cs index 54fb02a24..75a5d2399 100644 --- a/src/DotNet/Pdb/Managed/DbiNamespace.cs +++ b/src/DotNet/Pdb/Managed/DbiNamespace.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System; using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Managed { diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 276ad4494..04c400c06 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Text; -using System.Threading; using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs index 2e6eb6975..a057f5703 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.IO.Compression; using System.Text; using dnlib.DotNet.Emit; using dnlib.DotNet.MD; diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index 0684e6ea3..50b11f33a 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics; using System.Diagnostics.SymbolStore; -using System.Threading; using dnlib.DotNet.Pdb.Symbols; using dnlib.Threading; diff --git a/src/DotNet/Pdb/PdbMethod.cs b/src/DotNet/Pdb/PdbMethod.cs index 1e9422790..fe6538f13 100644 --- a/src/DotNet/Pdb/PdbMethod.cs +++ b/src/DotNet/Pdb/PdbMethod.cs @@ -1,13 +1,5 @@ // dnlib: See LICENSE.txt for more info -using dnlib.Threading; - -#if THREAD_SAFE -using ThreadSafe = dnlib.Threading.Collections; -#else -using ThreadSafe = System.Collections.Generic; -#endif - namespace dnlib.DotNet.Pdb { /// /// A PDB method diff --git a/src/DotNet/Pdb/Symbols/SymbolVariable.cs b/src/DotNet/Pdb/Symbols/SymbolVariable.cs index 840a23b5d..d99fa6afd 100644 --- a/src/DotNet/Pdb/Symbols/SymbolVariable.cs +++ b/src/DotNet/Pdb/Symbols/SymbolVariable.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System; namespace dnlib.DotNet.Pdb.Symbols { /// diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 337b141a3..6c527e0c8 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -7,7 +7,6 @@ using dnlib.DotNet.MD; using dnlib.DotNet.Emit; using dnlib.Threading; -using System.Text; using dnlib.DotNet.Pdb; #if THREAD_SAFE diff --git a/src/DotNet/UTF8String.cs b/src/DotNet/UTF8String.cs index 0f945dd9d..d14a7ddca 100644 --- a/src/DotNet/UTF8String.cs +++ b/src/DotNet/UTF8String.cs @@ -1,11 +1,10 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Text; -using System.Threading; namespace dnlib.DotNet { /// diff --git a/src/IO/MemoryImageStream.cs b/src/IO/MemoryImageStream.cs index 6b1b50269..192269610 100644 --- a/src/IO/MemoryImageStream.cs +++ b/src/IO/MemoryImageStream.cs @@ -1,9 +1,8 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Diagnostics; using System.IO; -using System.Text; namespace dnlib.IO { /// From 9a493e8df9390cc8e1a35ebc0a16db481b5a8643 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:48:13 +0100 Subject: [PATCH 057/511] Move portable PDB CDI reader code to a new class --- src/DotNet/Pdb/PdbCustomDebugInfoReader.cs | 185 +------------- .../PortablePdbCustomDebugInfoReader.cs | 230 ++++++++++++++++++ src/DotNet/Pdb/Portable/PortablePdbReader.cs | 2 +- src/dnlib.csproj | 1 + 4 files changed, 236 insertions(+), 182 deletions(-) create mode 100644 src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs index a057f5703..2398b445b 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs @@ -9,7 +9,6 @@ using System.IO; using System.Text; using dnlib.DotNet.Emit; -using dnlib.DotNet.MD; using dnlib.IO; using dnlib.Threading; @@ -40,23 +39,6 @@ public static void Read(MethodDef method, CilBody body, IList result) { if (reader.Length < 4) return; @@ -360,10 +202,12 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { return dynLocListRec; case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: - return ReadEncLocalSlotMap(recPosEnd); + data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: - return ReadEncLambdaAndClosureMap(recPosEnd); + data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLambdaMapCustomDebugInfo(data); case PdbCustomDebugInfoKind.TupleElementNames: if (bodyOpt == null) @@ -494,27 +338,6 @@ Instruction GetInstruction(uint offset) { return null; } - static Instruction GetInstruction(MethodDef method, uint offset) { - if (method == null) - return null; - var body = method.Body; - if (body == null) - return null; - var instructions = body.Instructions; - int lo = 0, hi = instructions.Count - 1; - while (lo <= hi && hi != -1) { - int i = (lo + hi) / 2; - var instr = instructions[i]; - if (instr.Offset == offset) - return instr; - if (offset < instr.Offset) - hi = i - 1; - else - lo = i + 1; - } - return null; - } - public void Dispose() { reader.Dispose(); } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs new file mode 100644 index 000000000..c3c043837 --- /dev/null +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -0,0 +1,230 @@ +// dnlib: See LICENSE.txt for more info + +// See Roslyn files: MethodDebugInfo.Portable.cs, MetadataWriter.PortablePdb.cs + +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using dnlib.DotNet.Emit; +using dnlib.DotNet.MD; +using dnlib.IO; + +namespace dnlib.DotNet.Pdb.Portable { + struct PortablePdbCustomDebugInfoReader : IDisposable { + public static PdbCustomDebugInfo Read(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, Guid kind, byte[] data) { + try { + using (var reader = new PortablePdbCustomDebugInfoReader(module, typeOpt, bodyOpt, gpContext, MemoryImageStream.Create(data))) { + var cdi = reader.Read(kind); + Debug.Assert(reader.reader.Position == reader.reader.Length); + return cdi; + } + } + catch (ArgumentException) { + } + catch (OutOfMemoryException) { + } + catch (IOException) { + } + return null; + } + + readonly ModuleDef module; + readonly TypeDef typeOpt; + readonly CilBody bodyOpt; + readonly GenericParamContext gpContext; + readonly IBinaryReader reader; + + PortablePdbCustomDebugInfoReader(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, IBinaryReader reader) { + this.module = module; + this.typeOpt = typeOpt; + this.bodyOpt = bodyOpt; + this.gpContext = gpContext; + this.reader = reader; + } + + PdbCustomDebugInfo Read(Guid kind) { + if (kind == CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob) + return ReadAsyncMethodSteppingInformationBlob(); + if (kind == CustomDebugInfoGuids.DefaultNamespace) + return ReadDefaultNamespace(); + if (kind == CustomDebugInfoGuids.DynamicLocalVariables) + return ReadDynamicLocalVariables(reader.Length); + if (kind == CustomDebugInfoGuids.EmbeddedSource) + return ReadEmbeddedSource(); + if (kind == CustomDebugInfoGuids.EncLambdaAndClosureMap) + return ReadEncLambdaAndClosureMap(reader.Length); + if (kind == CustomDebugInfoGuids.EncLocalSlotMap) + return ReadEncLocalSlotMap(reader.Length); + if (kind == CustomDebugInfoGuids.SourceLink) + return ReadSourceLink(); + if (kind == CustomDebugInfoGuids.StateMachineHoistedLocalScopes) + return ReadStateMachineHoistedLocalScopes(); + if (kind == CustomDebugInfoGuids.TupleElementNames) + return ReadTupleElementNames(); + Debug.Fail("Unknown custom debug info guid: " + kind.ToString()); + return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); + } + + PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { + if (bodyOpt == null) + return null; + uint catchHandlerOffset = reader.ReadUInt32() - 1; + Instruction catchHandler; + if (catchHandlerOffset == uint.MaxValue) + catchHandler = null; + else { + catchHandler = GetInstruction(catchHandlerOffset); + Debug.Assert(catchHandler != null); + if (catchHandler == null) + return null; + } + var asyncInfo = new PdbAsyncMethodSteppingInformationCustomDebugInfo(); + asyncInfo.CatchHandler = catchHandler; + while (reader.Position < reader.Length) { + var yieldInstr = GetInstruction(reader.ReadUInt32()); + Debug.Assert(yieldInstr != null); + if (yieldInstr == null) + return null; + uint resumeOffset = reader.ReadUInt32(); + var moveNextRid = reader.ReadCompressedUInt32(); + var moveNextToken = new MDToken(Table.Method, moveNextRid); + MethodDef moveNextMethod; + Instruction resumeInstr; + if (gpContext.Method != null && moveNextToken == gpContext.Method.MDToken) { + moveNextMethod = gpContext.Method; + resumeInstr = GetInstruction(resumeOffset); + } + else { + moveNextMethod = module.ResolveToken(moveNextToken, gpContext) as MethodDef; + Debug.Assert(moveNextMethod != null); + if (moveNextMethod == null) + return null; + resumeInstr = GetInstruction(moveNextMethod, resumeOffset); + } + Debug.Assert(resumeInstr != null); + if (resumeInstr == null) + return null; + asyncInfo.AsyncStepInfos.Add(new PdbAsyncStepInfo(yieldInstr, moveNextMethod, resumeInstr)); + } + return asyncInfo; + } + + PdbCustomDebugInfo ReadDefaultNamespace() { + var defaultNs = Encoding.UTF8.GetString(reader.ReadRemainingBytes()); + return new PdbDefaultNamespaceCustomDebugInfo(defaultNs); + } + + PdbCustomDebugInfo ReadDynamicLocalVariables(long recPosEnd) { + var flags = new bool[(int)reader.Length * 8]; + int w = 0; + while (reader.Position < reader.Length) { + int b = reader.ReadByte(); + for (int i = 1; i < 0x100; i <<= 1) + flags[w++] = (b & i) != 0; + } + return new PdbDynamicLocalVariablesCustomDebugInfo(flags); + } + + PdbCustomDebugInfo ReadEmbeddedSource() { + return new PdbEmbeddedSourceCustomDebugInfo(reader.ReadRemainingBytes()); + } + + PdbCustomDebugInfo ReadEncLambdaAndClosureMap(long recPosEnd) { + var data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLambdaMapCustomDebugInfo(data); + } + + PdbCustomDebugInfo ReadEncLocalSlotMap(long recPosEnd) { + var data = reader.ReadBytes((int)(recPosEnd - reader.Position)); + return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); + } + + PdbCustomDebugInfo ReadSourceLink() { + return new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); + } + + PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { + if (bodyOpt == null) + return null; + int count = (int)(reader.Length / 8); + var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); + for (int i = 0; i < count; i++) { + uint startOffset = reader.ReadUInt32(); + uint length = reader.ReadUInt32(); + if (startOffset == 0 && length == 0) + smScope.Scopes.Add(new StateMachineHoistedLocalScope()); + else { + var start = GetInstruction(startOffset); + var end = GetInstruction(startOffset + length); + Debug.Assert(start != null); + if (start == null) + return null; + smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); + } + } + return smScope; + } + + PdbCustomDebugInfo ReadTupleElementNames() { + var tupleListRec = new PortablePdbTupleElementNamesCustomDebugInfo(); + while (reader.Position < reader.Length) { + var name = ReadUTF8Z(reader.Length); + tupleListRec.Names.Add(name); + } + return tupleListRec; + } + + string ReadUTF8Z(long recPosEnd) { + if (reader.Position > recPosEnd) + return null; + var bytes = reader.ReadBytesUntilByte(0); + if (bytes == null) + return null; + var s = Encoding.UTF8.GetString(bytes); + reader.Position++; + return s; + } + + Instruction GetInstruction(uint offset) { + var instructions = bodyOpt.Instructions; + int lo = 0, hi = instructions.Count - 1; + while (lo <= hi && hi != -1) { + int i = (lo + hi) / 2; + var instr = instructions[i]; + if (instr.Offset == offset) + return instr; + if (offset < instr.Offset) + hi = i - 1; + else + lo = i + 1; + } + return null; + } + + static Instruction GetInstruction(MethodDef method, uint offset) { + if (method == null) + return null; + var body = method.Body; + if (body == null) + return null; + var instructions = body.Instructions; + int lo = 0, hi = instructions.Count - 1; + while (lo <= hi && hi != -1) { + int i = (lo + hi) / 2; + var instr = instructions[i]; + if (instr.Offset == offset) + return instr; + if (offset < instr.Offset) + hi = i - 1; + else + lo = i + 1; + } + return null; + } + + public void Dispose() { + reader.Dispose(); + } + } +} diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 25b28b084..be9431e3c 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -379,7 +379,7 @@ void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList + From 4b65b0a6919f2d4f4ef4a935c355a63ad7a8c1da Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:48:28 +0100 Subject: [PATCH 058/511] Reading PDB files is now enabled by default --- README.md | 12 +++--------- src/DotNet/ModuleCreationOptions.cs | 6 ++++-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8f517429f..69f37562c 100644 --- a/README.md +++ b/README.md @@ -104,15 +104,9 @@ To detect it at runtime, use this code: PDB files --------- -Right after opening the module, call one of its `LoadPdb()` methods. You can -also pass in a `ModuleCreationOptions` to `ModuleDefMD.Load()` and if one of -the PDB options is enabled, the PDB file will be opened before `Load()` -returns. - -```csharp - var mod = ModuleDefMD.Load(@"C:\myfile.dll"); - mod.LoadPdb(); // Will load C:\myfile.pdb if it exists -``` +PDB files are read from disk by default. You can change this behaviour by +creating a `ModuleCreationOptions` and passing it in to the code that creates +a module. To save a PDB file, create a `ModuleWriterOptions` / `NativeModuleWriterOptions` and set its `WritePdb` property to `true`. By diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 84567d693..2851f6b20 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -36,8 +36,8 @@ public sealed class ModuleCreationOptions { public object PdbFileOrData { get; set; } /// - /// If true, will load the PDB file from disk if present. You don't need to - /// initialize or . + /// If true, will load the PDB file from disk if present. The default value is true. + /// You don't need to initialize or . /// public bool TryToLoadPdbFromDisk { get; set; } @@ -52,6 +52,7 @@ public sealed class ModuleCreationOptions { /// public ModuleCreationOptions() { this.PdbImplementation = PdbImplType.Default; + this.TryToLoadPdbFromDisk = true; } /// @@ -61,6 +62,7 @@ public ModuleCreationOptions() { public ModuleCreationOptions(ModuleContext context) { this.Context = context; this.PdbImplementation = PdbImplType.Default; + this.TryToLoadPdbFromDisk = true; } } From f7ea6ddbcd6c81a23c4369d214a5e9b86240c7b6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:48:37 +0100 Subject: [PATCH 059/511] Move files --- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 1 + src/DotNet/Pdb/Dss/SymbolVariableImpl.cs | 1 + src/DotNet/Pdb/Dss/SymbolWriter.cs | 1 + src/DotNet/Pdb/Dss/SymbolWriterCreator.cs | 1 + src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs | 19 +++++++++++++++++++ src/DotNet/Pdb/Managed/PdbReader.cs | 1 + .../Pdb/{ => WindowsPdb}/CorSymVarFlag.cs | 2 +- .../CustomDebugInfoConstants.cs | 2 +- .../Pdb/{ => WindowsPdb}/ISymbolWriter2.cs | 18 +----------------- .../PdbCustomDebugInfoReader.cs | 2 +- .../PdbCustomDebugInfoWriter.cs | 2 +- src/DotNet/Pdb/{ => WindowsPdb}/PdbWriter.cs | 3 ++- .../{ => WindowsPdb}/SymbolWriterCreator.cs | 4 ++-- src/DotNet/Writer/ModuleWriterBase.cs | 1 + src/dnlib.csproj | 15 ++++++++------- 15 files changed, 42 insertions(+), 31 deletions(-) create mode 100644 src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs rename src/DotNet/Pdb/{ => WindowsPdb}/CorSymVarFlag.cs (77%) rename src/DotNet/Pdb/{ => WindowsPdb}/CustomDebugInfoConstants.cs (80%) rename src/DotNet/Pdb/{ => WindowsPdb}/ISymbolWriter2.cs (90%) rename src/DotNet/Pdb/{ => WindowsPdb}/PdbCustomDebugInfoReader.cs (99%) rename src/DotNet/Pdb/{ => WindowsPdb}/PdbCustomDebugInfoWriter.cs (99%) rename src/DotNet/Pdb/{ => WindowsPdb}/PdbWriter.cs (99%) rename src/DotNet/Pdb/{ => WindowsPdb}/SymbolWriterCreator.cs (92%) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 9b7086b18..98cecbfa7 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; +using dnlib.DotNet.Pdb.WindowsPdb; namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolReaderImpl : SymbolReader { diff --git a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs index 58071af6a..8c4649648 100644 --- a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using dnlib.DotNet.Pdb.Symbols; +using dnlib.DotNet.Pdb.WindowsPdb; namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolVariableImpl : SymbolVariable { diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index 230c704a7..6650f320b 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -5,6 +5,7 @@ using System.IO; using System.Reflection; using System.Runtime.InteropServices; +using dnlib.DotNet.Pdb.WindowsPdb; using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Dss { diff --git a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs index c06b76e08..e834219d3 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using dnlib.DotNet.Pdb.WindowsPdb; namespace dnlib.DotNet.Pdb.Dss { /// diff --git a/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs b/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs new file mode 100644 index 000000000..e397d49f7 --- /dev/null +++ b/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs @@ -0,0 +1,19 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb { + /// + /// IMAGE_DEBUG_DIRECTORY + /// + public struct IMAGE_DEBUG_DIRECTORY { +#pragma warning disable 1591 + public uint Characteristics; + public uint TimeDateStamp; + public ushort MajorVersion; + public ushort MinorVersion; + public uint Type; + public uint SizeOfData; + public uint AddressOfRawData; + public uint PointerToRawData; +#pragma warning restore 1591 + } +} diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 04c400c06..455779c9c 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -7,6 +7,7 @@ using System.Text; using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; +using dnlib.DotNet.Pdb.WindowsPdb; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { diff --git a/src/DotNet/Pdb/CorSymVarFlag.cs b/src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs similarity index 77% rename from src/DotNet/Pdb/CorSymVarFlag.cs rename to src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs index 6888ba858..ef1458847 100644 --- a/src/DotNet/Pdb/CorSymVarFlag.cs +++ b/src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs @@ -2,7 +2,7 @@ using System; -namespace dnlib.DotNet.Pdb { +namespace dnlib.DotNet.Pdb.WindowsPdb { [Flags] enum CorSymVarFlag : uint { VAR_IS_COMP_GEN = 0x00000001, diff --git a/src/DotNet/Pdb/CustomDebugInfoConstants.cs b/src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs similarity index 80% rename from src/DotNet/Pdb/CustomDebugInfoConstants.cs rename to src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs index af851b9c4..90def58ee 100644 --- a/src/DotNet/Pdb/CustomDebugInfoConstants.cs +++ b/src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Pdb { +namespace dnlib.DotNet.Pdb.WindowsPdb { static class CustomDebugInfoConstants { public const int Version = 4; public const int RecordVersion = 4; diff --git a/src/DotNet/Pdb/ISymbolWriter2.cs b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs similarity index 90% rename from src/DotNet/Pdb/ISymbolWriter2.cs rename to src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs index 7e9b35ae5..c2b358ef2 100644 --- a/src/DotNet/Pdb/ISymbolWriter2.cs +++ b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs @@ -4,23 +4,7 @@ using System.Diagnostics.SymbolStore; using dnlib.DotNet.Writer; -namespace dnlib.DotNet.Pdb { - /// - /// IMAGE_DEBUG_DIRECTORY - /// - public struct IMAGE_DEBUG_DIRECTORY { -#pragma warning disable 1591 - public uint Characteristics; - public uint TimeDateStamp; - public ushort MajorVersion; - public ushort MinorVersion; - public uint Type; - public uint SizeOfData; - public uint AddressOfRawData; - public uint PointerToRawData; -#pragma warning restore 1591 - } - +namespace dnlib.DotNet.Pdb.WindowsPdb { /// /// Implements and adds a few extra methods we need that are part of /// ISymUnmanagedWriter and ISymUnmanagedWriter2 but not present in diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs similarity index 99% rename from src/DotNet/Pdb/PdbCustomDebugInfoReader.cs rename to src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index 2398b445b..4068df3bf 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -12,7 +12,7 @@ using dnlib.IO; using dnlib.Threading; -namespace dnlib.DotNet.Pdb { +namespace dnlib.DotNet.Pdb.WindowsPdb { /// /// Reads custom debug infos produced by the C# and Visual Basic compilers. They're stored in PDB files /// as PDB method custom attributes with the name "MD2". diff --git a/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs similarity index 99% rename from src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs rename to src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs index 1b0c1225a..cbdce637e 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs @@ -10,7 +10,7 @@ using dnlib.DotNet.Emit; using dnlib.DotNet.Writer; -namespace dnlib.DotNet.Pdb { +namespace dnlib.DotNet.Pdb.WindowsPdb { sealed class PdbCustomDebugInfoWriterContext { public ILogger Logger; public readonly MemoryStream MemoryStream; diff --git a/src/DotNet/Pdb/PdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs similarity index 99% rename from src/DotNet/Pdb/PdbWriter.cs rename to src/DotNet/Pdb/WindowsPdb/PdbWriter.cs index 1062dc962..a98e4a7b9 100644 --- a/src/DotNet/Pdb/PdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs @@ -5,9 +5,10 @@ using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Emit; +using dnlib.DotNet.Pdb.WindowsPdb; using dnlib.DotNet.Writer; -namespace dnlib.DotNet.Pdb { +namespace dnlib.DotNet.Pdb.WindowsPdb { /// /// PDB writer /// diff --git a/src/DotNet/Pdb/SymbolWriterCreator.cs b/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs similarity index 92% rename from src/DotNet/Pdb/SymbolWriterCreator.cs rename to src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs index 98748344e..abb838ac4 100644 --- a/src/DotNet/Pdb/SymbolWriterCreator.cs +++ b/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs @@ -2,11 +2,11 @@ using System.IO; -namespace dnlib.DotNet.Pdb { +namespace dnlib.DotNet.Pdb.WindowsPdb { /// /// Creates a /// - public static class SymbolWriterCreator { + static class SymbolWriterCreator { /// /// Creates a new instance /// diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index c1d1f4b3d..7d4df92b7 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -9,6 +9,7 @@ using dnlib.W32Resources; using dnlib.DotNet.MD; using System.Diagnostics; +using dnlib.DotNet.Pdb.WindowsPdb; namespace dnlib.DotNet.Writer { /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index e5d2a4ca7..3b3a7b537 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -175,11 +175,10 @@ - - + @@ -187,8 +186,6 @@ - - @@ -215,6 +212,13 @@ + + + + + + + @@ -233,7 +237,6 @@ - @@ -250,10 +253,8 @@ - - From 326a008484fb4c69ea1c257369dd01416693c247 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:48:47 +0100 Subject: [PATCH 060/511] Convert async/iterator method info to CDIs --- src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 21 +-- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 8 +- src/DotNet/Pdb/Dss/SymbolWriter.cs | 1 + src/DotNet/Pdb/Managed/DbiFunction.cs | 17 +- src/DotNet/Pdb/Managed/PdbReader.cs | 15 +- src/DotNet/Pdb/PdbAsyncMethod.cs | 84 ---------- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 149 +++++++++++++++++- src/DotNet/Pdb/PdbIteratorMethod.cs | 19 --- src/DotNet/Pdb/PdbMethod.cs | 10 -- src/DotNet/Pdb/PdbState.cs | 94 +---------- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 75 ++++++--- src/DotNet/Pdb/Portable/SymbolMethodImpl.cs | 35 ++-- src/DotNet/Pdb/Symbols/SymbolMethod.cs | 37 +---- src/DotNet/Pdb/Symbols/SymbolReader.cs | 8 - src/DotNet/Pdb/WindowsPdb/PdbWriter.cs | 36 ++++- .../PseudoCustomDebugInfoFactory.cs | 75 +++++++++ src/dnlib.csproj | 3 +- 17 files changed, 358 insertions(+), 329 deletions(-) delete mode 100644 src/DotNet/Pdb/PdbAsyncMethod.cs delete mode 100644 src/DotNet/Pdb/PdbIteratorMethod.cs create mode 100644 src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index 5e9abdad0..3c1142db7 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -3,16 +3,19 @@ using System.Collections.Generic; using System.Diagnostics.SymbolStore; using System.Threading; +using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolMethodImpl : SymbolMethod { + readonly SymbolReaderImpl reader; readonly ISymUnmanagedMethod method; readonly ISymUnmanagedAsyncMethod asyncMethod; - public SymbolMethodImpl(ISymUnmanagedMethod method) { + public SymbolMethodImpl(SymbolReaderImpl reader, ISymUnmanagedMethod method) { + this.reader = reader; this.method = method; - this.asyncMethod = method as ISymUnmanagedAsyncMethod; + asyncMethod = method as ISymUnmanagedAsyncMethod; } public override int Token { @@ -70,11 +73,7 @@ public override IList SequencePoints { } volatile SymbolSequencePoint[] sequencePoints; - public override int IteratorKickoffMethod { - get { return 0; } - } - - public override int AsyncKickoffMethod { + public int AsyncKickoffMethod { get { if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) return 0; @@ -82,7 +81,7 @@ public override int AsyncKickoffMethod { } } - public override uint? AsyncCatchHandlerILOffset { + public uint? AsyncCatchHandlerILOffset { get { if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) return null; @@ -92,7 +91,7 @@ public override uint? AsyncCatchHandlerILOffset { } } - public override IList AsyncStepInfos { + public IList AsyncStepInfos { get { if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) return null; @@ -111,5 +110,9 @@ public override IList AsyncStepInfos { } } volatile SymbolAsyncStepInfo[] asyncStepInfos; + + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + reader.GetCustomDebugInfos(this, method, body, result); + } } } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 98cecbfa7..5f0d2b7e1 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -67,10 +67,14 @@ public override SymbolMethod GetMethod(MethodDef method, int version) { if (hr == E_FAIL) return null; Marshal.ThrowExceptionForHR(hr); - return unMethod == null ? null : new SymbolMethodImpl(unMethod); + return unMethod == null ? null : new SymbolMethodImpl(this, unMethod); } - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { + var asyncMethod = PseudoCustomDebugInfoFactory.TryCreateAsyncMethod(method.Module, method, body, symMethod.AsyncKickoffMethod, symMethod.AsyncStepInfos, symMethod.AsyncCatchHandlerILOffset); + if (asyncMethod != null) + result.Add(asyncMethod); + const string CDI_NAME = "MD2"; uint bufSize; reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, 0, out bufSize, null); diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index 6650f320b..7af579b35 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -47,6 +47,7 @@ public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbS if (pdbStream == null) throw new ArgumentNullException("pdbStream"); this.writer = writer; + this.asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; this.pdbStream = pdbStream; this.pdbFileName = pdbFileName; } diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index d6347be74..11ba5e28f 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; @@ -12,6 +13,8 @@ public override int Token { } internal int token; + internal PdbReader reader; + public string Name { get; private set; } public PdbAddress Address { get; private set; } public DbiScope Root { get; private set; } @@ -64,12 +67,8 @@ public override IList SequencePoints { } static readonly SymbolSequencePoint[] emptySymbolSequencePoints = new SymbolSequencePoint[0]; - public override int IteratorKickoffMethod { - get { return 0; } - } - const string asyncMethodInfoAttributeName = "asyncMethodInfo"; - public override int AsyncKickoffMethod { + public int AsyncKickoffMethod { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) @@ -78,7 +77,7 @@ public override int AsyncKickoffMethod { } } - public override uint? AsyncCatchHandlerILOffset { + public uint? AsyncCatchHandlerILOffset { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); if (data == null) @@ -88,7 +87,7 @@ public override uint? AsyncCatchHandlerILOffset { } } - public override IList AsyncStepInfos { + public IList AsyncStepInfos { get { if (asyncStepInfos == null) asyncStepInfos = CreateSymbolAsyncStepInfos(); @@ -116,5 +115,9 @@ SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { return res; } static readonly SymbolAsyncStepInfo[] emptySymbolAsyncStepInfos = new SymbolAsyncStepInfo[0]; + + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + reader.GetCustomDebugInfos(this, method, body, result); + } } } diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 455779c9c..54504d870 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -3,7 +3,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.Text; using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; @@ -132,6 +131,7 @@ void ReadInternal(IImageStream stream) { functions = new Dictionary(); foreach (var module in modules) { foreach (var func in module.Functions) { + func.reader = this; functions.Add(func.Token, func); } } @@ -351,14 +351,13 @@ public override int UserEntryPoint { get { return (int)entryPt; } } - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + internal void GetCustomDebugInfos(DbiFunction symMethod, MethodDef method, CilBody body, IList result) { const string CDI_NAME = "MD2"; - DbiFunction func; - bool b = functions.TryGetValue(method.MDToken.ToInt32(), out func); - Debug.Assert(b); - if (!b) - return; - var cdiData = func.Root.GetSymAttribute(CDI_NAME); + var asyncMethod = PseudoCustomDebugInfoFactory.TryCreateAsyncMethod(method.Module, method, body, symMethod.AsyncKickoffMethod, symMethod.AsyncStepInfos, symMethod.AsyncCatchHandlerILOffset); + if (asyncMethod != null) + result.Add(asyncMethod); + + var cdiData = symMethod.Root.GetSymAttribute(CDI_NAME); if (cdiData == null) return; PdbCustomDebugInfoReader.Read(method, body, result, cdiData); diff --git a/src/DotNet/Pdb/PdbAsyncMethod.cs b/src/DotNet/Pdb/PdbAsyncMethod.cs deleted file mode 100644 index 4f4b51c78..000000000 --- a/src/DotNet/Pdb/PdbAsyncMethod.cs +++ /dev/null @@ -1,84 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.DotNet.Emit; -using dnlib.Threading; - -#if THREAD_SAFE -using ThreadSafe = dnlib.Threading.Collections; -#else -using ThreadSafe = System.Collections.Generic; -#endif - -namespace dnlib.DotNet.Pdb { - /// - /// Async method info - /// - public sealed class PdbAsyncMethod { - readonly ThreadSafe.IList asyncStepInfos; - - /// - /// Gets/sets the starting method that initiates the async operation - /// - public MethodDef KickoffMethod { get; set; } - - /// - /// Gets/sets the instruction for the compiler generated catch handler that wraps an async method. - /// This can be null. - /// - public Instruction CatchHandlerInstruction { get; set; } - - /// - /// Gets all step infos used by the debugger - /// - public ThreadSafe.IList StepInfos { - get { return asyncStepInfos; } - } - - /// - /// Constructor - /// - public PdbAsyncMethod() { - asyncStepInfos = ThreadSafeListCreator.Create(); - } - - /// - /// Constructor - /// - /// Default capacity for - public PdbAsyncMethod(int stepInfosCapacity) { - asyncStepInfos = ThreadSafeListCreator.Create(stepInfosCapacity); - } - } - - /// - /// Async step info used by debuggers - /// - public struct PdbAsyncStepInfo { - /// - /// The yield instruction - /// - public Instruction YieldInstruction; - - /// - /// Resume method - /// - public MethodDef BreakpointMethod; - - /// - /// Resume instruction (where the debugger puts a breakpoint) - /// - public Instruction BreakpointInstruction; - - /// - /// Constructor - /// - /// The yield instruction - /// Resume method - /// Resume instruction (where the debugger puts a breakpoint) - public PdbAsyncStepInfo(Instruction yieldInstruction, MethodDef breakpointMethod, Instruction breakpointInstruction) { - YieldInstruction = yieldInstruction; - BreakpointMethod = breakpointMethod; - BreakpointInstruction = breakpointInstruction; - } - } -} diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index fded427be..310da675d 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -61,6 +61,8 @@ public enum PdbCustomDebugInfoKind { /// TupleElementNames, + // Values 0x00-0xFF are reserved for Windows PDB CDIs. + /// /// Unknown /// @@ -71,11 +73,6 @@ public enum PdbCustomDebugInfoKind { /// TupleElementNames_PortablePdb, - /// - /// - /// - AsyncMethodSteppingInformation, - /// /// /// @@ -95,6 +92,16 @@ public enum PdbCustomDebugInfoKind { /// /// SourceLink, + + /// + /// + /// + AsyncMethod, + + /// + /// + /// + IteratorMethod, } /// @@ -771,15 +778,17 @@ public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) { /// /// Async method stepping info + /// + /// It's internal and translated to a /// - public sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { + internal sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { readonly ThreadSafe.IList asyncStepInfos; /// - /// Returns + /// Returns /// public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.AsyncMethodSteppingInformation; } + get { return PdbCustomDebugInfoKind.Unknown; } } /// @@ -964,4 +973,128 @@ public PdbSourceLinkCustomDebugInfo(byte[] sourceLinkBlob) { SourceLinkBlob = sourceLinkBlob; } } + + /// + /// Async method info + /// + public sealed class PdbAsyncMethodCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.AsyncMethod; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + + readonly ThreadSafe.IList asyncStepInfos; + + /// + /// Gets/sets the starting method that initiates the async operation + /// + public MethodDef KickoffMethod { get; set; } + + /// + /// Gets/sets the instruction for the compiler generated catch handler that wraps an async method. + /// This can be null. + /// + public Instruction CatchHandlerInstruction { get; set; } + + /// + /// Gets all step infos used by the debugger + /// + public ThreadSafe.IList StepInfos { + get { return asyncStepInfos; } + } + + /// + /// Constructor + /// + public PdbAsyncMethodCustomDebugInfo() { + asyncStepInfos = ThreadSafeListCreator.Create(); + } + + /// + /// Constructor + /// + /// Default capacity for + public PdbAsyncMethodCustomDebugInfo(int stepInfosCapacity) { + asyncStepInfos = ThreadSafeListCreator.Create(stepInfosCapacity); + } + } + + /// + /// Async step info used by debuggers + /// + public struct PdbAsyncStepInfo { + /// + /// The yield instruction + /// + public Instruction YieldInstruction; + + /// + /// Resume method + /// + public MethodDef BreakpointMethod; + + /// + /// Resume instruction (where the debugger puts a breakpoint) + /// + public Instruction BreakpointInstruction; + + /// + /// Constructor + /// + /// The yield instruction + /// Resume method + /// Resume instruction (where the debugger puts a breakpoint) + public PdbAsyncStepInfo(Instruction yieldInstruction, MethodDef breakpointMethod, Instruction breakpointInstruction) { + YieldInstruction = yieldInstruction; + BreakpointMethod = breakpointMethod; + BreakpointInstruction = breakpointInstruction; + } + } + + /// + /// Iterator method + /// + public sealed class PdbIteratorMethodCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind { + get { return PdbCustomDebugInfoKind.AsyncMethod; } + } + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid { + get { return Guid.Empty; } + } + + /// + /// Gets the kickoff method + /// + public MethodDef KickoffMethod { get; set; } + + /// + /// Constructor + /// + public PdbIteratorMethodCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// Kickoff method + public PdbIteratorMethodCustomDebugInfo(MethodDef kickoffMethod) { + KickoffMethod = kickoffMethod; + } + } } diff --git a/src/DotNet/Pdb/PdbIteratorMethod.cs b/src/DotNet/Pdb/PdbIteratorMethod.cs deleted file mode 100644 index 1c2c41840..000000000 --- a/src/DotNet/Pdb/PdbIteratorMethod.cs +++ /dev/null @@ -1,19 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb { - /// - /// Iterator method info - /// - public sealed class PdbIteratorMethod { - /// - /// Gets/sets the kickoff method - /// - public MethodDef KickoffMethod { get; set; } - - /// - /// Constructor - /// - public PdbIteratorMethod() { - } - } -} diff --git a/src/DotNet/Pdb/PdbMethod.cs b/src/DotNet/Pdb/PdbMethod.cs index fe6538f13..619dfdf1b 100644 --- a/src/DotNet/Pdb/PdbMethod.cs +++ b/src/DotNet/Pdb/PdbMethod.cs @@ -10,16 +10,6 @@ public sealed class PdbMethod { /// public PdbScope Scope { get; set; } - /// - /// Gets/sets the async method info or null if there's none - /// - public PdbAsyncMethod AsyncMethod { get; set; } - - /// - /// Gets/sets the iterator method info or null if there's none - /// - public PdbIteratorMethod IteratorMethod { get; set; } - /// /// Constructor /// diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 6735702cf..6cd2370d2 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -188,7 +188,7 @@ internal Compiler Compiler { } internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, IList customDebugInfos) { - if (reader == null || body == null) + if (reader == null) return; SymbolMethod method; @@ -201,13 +201,8 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); - if (method.IsAsyncMethod) - pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method); - if (method.IsIteratorMethod) - pdbMethod.IteratorMethod = CreateIteratorMethod(module, ownerMethod, body, method); - // Read the custom debug info last so eg. local names have been initialized - reader.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); + method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); body.PdbMethod = pdbMethod; } @@ -235,85 +230,6 @@ static Compiler CalculateCompiler(ModuleDef module) { } static readonly UTF8String nameAssemblyVisualBasic = new UTF8String("Microsoft.VisualBasic"); - PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { - var kickoffToken = new MDToken(symMethod.AsyncKickoffMethod); - if (kickoffToken.Table != Table.Method) - return null; - var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); - - var asyncStepInfos = symMethod.AsyncStepInfos; - - var asyncMethod = new PdbAsyncMethod(asyncStepInfos.Count); - asyncMethod.KickoffMethod = kickoffMethod; - - var catchHandlerILOffset = symMethod.AsyncCatchHandlerILOffset; - if (catchHandlerILOffset != null) { - asyncMethod.CatchHandlerInstruction = GetInstruction(body, catchHandlerILOffset.Value); - Debug.Assert(asyncMethod.CatchHandlerInstruction != null); - } - - foreach (var rawInfo in asyncStepInfos) { - var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); - Debug.Assert(yieldInstruction != null); - if (yieldInstruction == null) - continue; - MethodDef breakpointMethod; - Instruction breakpointInstruction; - if (method.MDToken.Raw == rawInfo.BreakpointMethod) { - breakpointMethod = method; - breakpointInstruction = GetInstruction(body, rawInfo.BreakpointOffset); - } - else { - var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); - Debug.Assert(breakpointMethodToken.Table == Table.Method); - if (breakpointMethodToken.Table != Table.Method) - continue; - breakpointMethod = module.ResolveMethod(breakpointMethodToken.Rid); - Debug.Assert(breakpointMethod != null); - if (breakpointMethod == null) - continue; - breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); - } - Debug.Assert(breakpointInstruction != null); - if (breakpointInstruction == null) - continue; - - asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); - } - - return asyncMethod; - } - - PdbIteratorMethod CreateIteratorMethod(ModuleDefMD module, MethodDef method, CilBody body, SymbolMethod symMethod) { - var kickoffToken = new MDToken(symMethod.IteratorKickoffMethod); - if (kickoffToken.Table != Table.Method) - return null; - - var iteratorMethod = new PdbIteratorMethod(); - - iteratorMethod.KickoffMethod = module.ResolveMethod(kickoffToken.Rid); - - return iteratorMethod; - } - - Instruction GetInstruction(CilBody body, uint offset) { - if (body == null) - return null; - var instructions = body.Instructions; - int lo = 0, hi = instructions.Count - 1; - while (lo <= hi && hi != -1) { - int i = (lo + hi) / 2; - var instr = instructions[i]; - if (instr.Offset == offset) - return instr; - if (offset < instr.Offset) - hi = i - 1; - else - lo = i + 1; - } - return null; - } - void AddSequencePoints(CilBody body, SymbolMethod method) { int instrIndex = 0; foreach (var sp in method.SequencePoints) { @@ -501,11 +417,13 @@ static Instruction GetInstruction(IList instrs, int offset, ref int internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { Debug.Assert(token.Table != Table.Method, "Methods get initialized when reading the method bodies"); - reader.GetCustomDebugInfos(token.ToInt32(), gpContext, result); + if (reader != null) + reader.GetCustomDebugInfos(token.ToInt32(), gpContext, result); } internal void Dispose() { - reader.Dispose(); + if (reader != null) + reader.Dispose(); } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index be9431e3c..0f4bdce92 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -96,29 +96,12 @@ public override SymbolMethod GetMethod(MethodDef method, int version) { var rootScope = ReadScope(methodRid, gpContext); var kickoffMethod = GetKickoffMethod(methodRid); - bool isAsyncMethod = kickoffMethod != 0 && IsAsyncMethod(method); - bool isIteratorMethod = kickoffMethod != 0 && !isAsyncMethod; - int iteratorKickoffMethod = isIteratorMethod ? kickoffMethod : 0; - int asyncKickoffMethod = isAsyncMethod ? kickoffMethod : 0; - uint? asyncCatchHandlerILOffset = null; - var asyncStepInfos = emptySymbolAsyncStepInfos; - var symbolMethod = new SymbolMethodImpl(method.MDToken.ToInt32(), rootScope, sequencePoints, iteratorKickoffMethod, asyncKickoffMethod, asyncCatchHandlerILOffset, asyncStepInfos); + var symbolMethod = new SymbolMethodImpl(this, method.MDToken.ToInt32(), rootScope, sequencePoints, kickoffMethod); rootScope.method = symbolMethod; return symbolMethod; } static readonly SymbolAsyncStepInfo[] emptySymbolAsyncStepInfos = new SymbolAsyncStepInfo[0]; - static bool IsAsyncMethod(MethodDef method) { - foreach (var iface in method.DeclaringType.Interfaces) { - if (iface.Interface.Name != stringIAsyncStateMachine) - continue; - if (iface.Interface.FullName == "System.Runtime.CompilerServices.IAsyncStateMachine") - return true; - } - return false; - } - static readonly UTF8String stringIAsyncStateMachine = new UTF8String("IAsyncStateMachine"); - int GetKickoffMethod(uint methodRid) { uint rid = pdbMetaData.GetStateMachineMethodRid(methodRid); if (rid == 0) @@ -355,16 +338,53 @@ void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEn scope.SetConstants(pdbMetaData, constantList, constantListEnd); } - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { Debug.Assert(method.Module == module); - GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body); + PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo; + GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out asyncStepInfo); + if (asyncStepInfo != null) { + var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); + Debug.Assert(asyncMethod != null); + if (asyncMethod != null) + result.Add(asyncMethod); + } + else if (symMethod.KickoffMethod != 0) { + var iteratorMethod = TryCreateIteratorMethod(module, symMethod.KickoffMethod); + Debug.Assert(iteratorMethod != null); + if (iteratorMethod != null) + result.Add(iteratorMethod); + } + } + + PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef module, int asyncKickoffMethod, IList asyncStepInfos, Instruction asyncCatchHandler) { + var kickoffToken = new MDToken(asyncKickoffMethod); + if (kickoffToken.Table != Table.Method) + return null; + + var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); + asyncMethod.KickoffMethod = module.ResolveToken(kickoffToken) as MethodDef; + asyncMethod.CatchHandlerInstruction = asyncCatchHandler; + foreach (var info in asyncStepInfos) + asyncMethod.StepInfos.Add(info); + return asyncMethod; + } + + PdbIteratorMethodCustomDebugInfo TryCreateIteratorMethod(ModuleDef module, int iteratorKickoffMethod) { + var kickoffToken = new MDToken(iteratorKickoffMethod); + if (kickoffToken.Table != Table.Method) + return null; + var kickoffMethod = module.ResolveToken(kickoffToken) as MethodDef; + return new PdbIteratorMethodCustomDebugInfo(kickoffMethod); } public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { - GetCustomDebugInfos(token, gpContext, result, null, null); + PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo; + GetCustomDebugInfos(token, gpContext, result, null, null, out asyncStepInfo); + Debug.Assert(asyncStepInfo == null); } - void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result, MethodDef methodOpt, CilBody bodyOpt) { + void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result, MethodDef methodOpt, CilBody bodyOpt, out PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo) { + asyncStepInfo = null; var mdToken = new MDToken(token); var ridList = pdbMetaData.GetCustomDebugInformationRidList(mdToken.Table, mdToken.Rid); if (ridList.Count == 0) @@ -381,8 +401,15 @@ void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList SequencePoints { get { return sequencePoints; } } - public override int IteratorKickoffMethod { - get { return iteratorKickoffMethod; } + public int KickoffMethod { + get { return kickoffMethod; } } - public override int AsyncKickoffMethod { - get { return asyncKickoffMethod; } - } - - public override uint? AsyncCatchHandlerILOffset { - get { return asyncCatchHandlerILOffset; } - } - - public override IList AsyncStepInfos { - get { return asyncStepInfos; } - } - - public SymbolMethodImpl(int token, SymbolScope rootScope, SymbolSequencePoint[] sequencePoints, int iteratorKickoffMethod, int asyncKickoffMethod, uint? asyncCatchHandlerILOffset, SymbolAsyncStepInfo[] asyncStepInfos) { + public SymbolMethodImpl(PortablePdbReader reader, int token, SymbolScope rootScope, SymbolSequencePoint[] sequencePoints, int kickoffMethod) { + this.reader = reader; this.token = token; this.rootScope = rootScope; this.sequencePoints = sequencePoints; - this.iteratorKickoffMethod = iteratorKickoffMethod; - this.asyncKickoffMethod = asyncKickoffMethod; - this.asyncCatchHandlerILOffset = asyncCatchHandlerILOffset; - this.asyncStepInfos = asyncStepInfos; + this.kickoffMethod = kickoffMethod; + } + + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + reader.GetCustomDebugInfos(this, method, body, result); } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolMethod.cs b/src/DotNet/Pdb/Symbols/SymbolMethod.cs index cd64d4cba..6943621fb 100644 --- a/src/DotNet/Pdb/Symbols/SymbolMethod.cs +++ b/src/DotNet/Pdb/Symbols/SymbolMethod.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System.Collections.Generic; +using dnlib.DotNet.Emit; namespace dnlib.DotNet.Pdb.Symbols { /// @@ -23,37 +24,11 @@ public abstract class SymbolMethod { public abstract IList SequencePoints { get; } /// - /// true if this is an iterator method + /// Reads custom debug info /// - public bool IsIteratorMethod { - get { return IteratorKickoffMethod != 0; } - } - - /// - /// Gets the kick off method if it's an iterator method, otherwise 0 - /// - public abstract int IteratorKickoffMethod { get; } - - /// - /// true if this is an async method - /// - public bool IsAsyncMethod { - get { return AsyncKickoffMethod != 0; } - } - - /// - /// Gets the kick off method if it's an async method, otherwise 0 - /// - public abstract int AsyncKickoffMethod { get; } - - /// - /// Gets the catch handler IL offset if it's an async method () - /// - public abstract uint? AsyncCatchHandlerILOffset { get; } - - /// - /// Gets the async step infos if it's an async method () - /// - public abstract IList AsyncStepInfos { get; } + /// Method + /// Method body + /// Updated with custom debug info + public abstract void GetCustomDebugInfos(MethodDef method, CilBody body, IList result); } } diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index e32c52d7a..ace39d842 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -38,14 +38,6 @@ public abstract class SymbolReader : IDisposable { /// public abstract SymbolMethod GetMethod(MethodDef method, int version); - /// - /// Reads custom debug info - /// - /// Method - /// Method body - /// Updated with custom debug info - public abstract void GetCustomDebugInfos(MethodDef method, CilBody body, IList result); - /// /// Reads custom debug info /// diff --git a/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs index a98e4a7b9..26b96ff1d 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs @@ -99,6 +99,7 @@ ISymbolDocumentWriter Add(PdbDocument pdbDoc) { public void Write() { writer.SetUserEntryPoint(new SymbolToken(GetUserEntryPointToken())); + var cdiBuilder = new List(); foreach (var type in module.GetTypes()) { if (type == null) continue; @@ -107,7 +108,7 @@ public void Write() { continue; if (!ShouldAddMethod(method)) continue; - Write(method); + Write(method, cdiBuilder); } } } @@ -224,7 +225,7 @@ public int GetOffset(Instruction instr) { } } - void Write(MethodDef method) { + void Write(MethodDef method, List cdiBuilder) { uint rid = metaData.GetRid(method); if (rid == 0) { Error("Method {0} ({1:X8}) is not defined in this module ({2})", method, method.MDToken.Raw, module); @@ -261,14 +262,15 @@ void Write(MethodDef method) { WriteScope(ref info, scope, 0); } - if (method.CustomDebugInfos.Count != 0) { + PdbAsyncMethodCustomDebugInfo asyncMethod; + GetPseudoCustomDebugInfos(method.CustomDebugInfos, cdiBuilder, out asyncMethod); + if (cdiBuilder.Count != 0) { customDebugInfoWriterContext.Logger = GetLogger(); - var cdiData = PdbCustomDebugInfoWriter.Write(metaData, method, customDebugInfoWriterContext, method.CustomDebugInfos); + var cdiData = PdbCustomDebugInfoWriter.Write(metaData, method, customDebugInfoWriterContext, cdiBuilder); if (cdiData != null) writer.SetSymAttribute(symbolToken, "MD2", cdiData); } - var asyncMethod = pdbMethod.AsyncMethod; if (asyncMethod != null) { if (writer3 == null || !writer3.SupportsAsyncMethods) Error("PDB symbol writer doesn't support writing async methods"); @@ -279,6 +281,28 @@ void Write(MethodDef method) { writer.CloseMethod(); } + void GetPseudoCustomDebugInfos(IList customDebugInfos, List cdiBuilder, out PdbAsyncMethodCustomDebugInfo asyncMethod) { + cdiBuilder.Clear(); + asyncMethod = null; + foreach (var cdi in customDebugInfos) { + switch (cdi.Kind) { + case PdbCustomDebugInfoKind.AsyncMethod: + if (asyncMethod != null) + Error("Duplicate async method custom debug info"); + else + asyncMethod = (PdbAsyncMethodCustomDebugInfo)cdi; + break; + + default: + if ((uint)cdi.Kind > byte.MaxValue) + Error("Custom debug info {0} isn't supported by Windows PDB files", cdi.Kind); + else + cdiBuilder.Add(cdi); + break; + } + } + } + uint GetMethodToken(MethodDef method) { uint rid = metaData.GetRid(method); if (rid == 0) @@ -286,7 +310,7 @@ uint GetMethodToken(MethodDef method) { return new MDToken(MD.Table.Method, rid).Raw; } - void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethod asyncMethod) { + void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyncMethod) { if (asyncMethod.KickoffMethod == null) { Error("KickoffMethod is null"); return; diff --git a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs new file mode 100644 index 000000000..a52c3c7d2 --- /dev/null +++ b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs @@ -0,0 +1,75 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Diagnostics; +using dnlib.DotNet.Emit; +using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb.Symbols; + +namespace dnlib.DotNet.Pdb.WindowsPdb { + static class PseudoCustomDebugInfoFactory { + public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef module, MethodDef method, CilBody body, int asyncKickoffMethod, IList asyncStepInfos, uint? asyncCatchHandlerILOffset) { + var kickoffToken = new MDToken(asyncKickoffMethod); + if (kickoffToken.Table != Table.Method) + return null; + var kickoffMethod = module.ResolveToken(kickoffToken) as MethodDef; + + var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); + asyncMethod.KickoffMethod = kickoffMethod; + + if (asyncCatchHandlerILOffset != null) { + asyncMethod.CatchHandlerInstruction = GetInstruction(body, asyncCatchHandlerILOffset.Value); + Debug.Assert(asyncMethod.CatchHandlerInstruction != null); + } + + foreach (var rawInfo in asyncStepInfos) { + var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); + Debug.Assert(yieldInstruction != null); + if (yieldInstruction == null) + continue; + MethodDef breakpointMethod; + Instruction breakpointInstruction; + if (method.MDToken.Raw == rawInfo.BreakpointMethod) { + breakpointMethod = method; + breakpointInstruction = GetInstruction(body, rawInfo.BreakpointOffset); + } + else { + var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); + Debug.Assert(breakpointMethodToken.Table == Table.Method); + if (breakpointMethodToken.Table != Table.Method) + continue; + breakpointMethod = module.ResolveToken(breakpointMethodToken) as MethodDef; + Debug.Assert(breakpointMethod != null); + if (breakpointMethod == null) + continue; + breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); + } + Debug.Assert(breakpointInstruction != null); + if (breakpointInstruction == null) + continue; + + asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); + } + + return asyncMethod; + } + + static Instruction GetInstruction(CilBody body, uint offset) { + if (body == null) + return null; + var instructions = body.Instructions; + int lo = 0, hi = instructions.Count - 1; + while (lo <= hi && hi != -1) { + int i = (lo + hi) / 2; + var instr = instructions[i]; + if (instr.Offset == offset) + return instr; + if (offset < instr.Offset) + hi = i - 1; + else + lo = i + 1; + } + return null; + } + } +} diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 3b3a7b537..afc38930c 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -183,12 +183,10 @@ - - @@ -218,6 +216,7 @@ + From f05b1f5b07744f6257f2a196712a89fcf544bdf2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:49:06 +0100 Subject: [PATCH 061/511] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 69f37562c..87fe89edc 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ For another application using dnlib, see [ConfuserEx](https://github.com/yck1509 a look at its writer code which gets executed during the assembly writing process. +Want to say thanks? Click the star at the top of the page. + Compiling --------- From b2a3d0ea8fcabb97345fe2d6598fe6ca0cde1901 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 7 Nov 2017 20:49:32 +0100 Subject: [PATCH 062/511] Move constants class and make it public --- src/DotNet/Pdb/PdbDocument.cs | 17 ++++++++--------- .../Constants.cs => PdbDocumentConstants.cs} | 10 ++++++++-- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 6 +++--- src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs | 10 +++++----- src/dnlib.csproj | 2 +- 5 files changed, 25 insertions(+), 20 deletions(-) rename src/DotNet/Pdb/{Portable/Constants.cs => PdbDocumentConstants.cs} (70%) diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index 50b11f33a..234026009 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -2,7 +2,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.SymbolStore; using dnlib.DotNet.Pdb.Symbols; using dnlib.Threading; @@ -24,22 +23,22 @@ public sealed class PdbDocument : IHasCustomDebugInformation { public string Url { get; set; } /// - /// Gets/sets the language GUID. See + /// Gets/sets the language GUID. See /// public Guid Language { get; set; } /// - /// Gets/sets the language vendor GUID. See + /// Gets/sets the language vendor GUID. See /// public Guid LanguageVendor { get; set; } /// - /// Gets/sets the document type GUID. See + /// Gets/sets the document type GUID. See /// public Guid DocumentType { get; set; } /// - /// Gets/sets the checksum algorithm ID + /// Gets/sets the checksum algorithm ID. See /// public Guid CheckSumAlgorithmId { get; set; } @@ -93,10 +92,10 @@ public PdbDocument(SymbolDocument symDoc) { /// Constructor /// /// Document URL - /// Language. See - /// Language vendor. See - /// Document type. See - /// Checksum algorithm ID + /// Language. See + /// Language vendor. See + /// Document type. See + /// Checksum algorithm ID. See /// Checksum public PdbDocument(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum) { this.Url = url; diff --git a/src/DotNet/Pdb/Portable/Constants.cs b/src/DotNet/Pdb/PdbDocumentConstants.cs similarity index 70% rename from src/DotNet/Pdb/Portable/Constants.cs rename to src/DotNet/Pdb/PdbDocumentConstants.cs index 7295cf977..8775cbb66 100644 --- a/src/DotNet/Pdb/Portable/Constants.cs +++ b/src/DotNet/Pdb/PdbDocumentConstants.cs @@ -2,8 +2,12 @@ using System; -namespace dnlib.DotNet.Pdb.Portable { - static class Constants { +namespace dnlib.DotNet.Pdb { + /// + /// PDB document constants + /// + public static class PdbDocumentConstants { +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member public static readonly Guid LanguageCSharp = new Guid("3F5162F8-07C6-11D3-9053-00C04FA302A1"); public static readonly Guid LanguageVisualBasic = new Guid("3A12D0B8-C26C-11D0-B442-00A0244A1DD2"); public static readonly Guid LanguageFSharp = new Guid("AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3"); @@ -12,6 +16,8 @@ static class Constants { public static readonly Guid HashSHA256 = new Guid("8829D00F-11B8-4213-878B-770E8597AC16"); public static readonly Guid LanguageVendorMicrosoft = new Guid("994B45C4-E6E9-11D2-903F-00C04FA302A1"); + public static readonly Guid DocumentTypeText = new Guid("5A869D0B-6611-11D3-BD2A-0000F80849BD"); +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 0f4bdce92..47034daf1 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -40,8 +40,8 @@ public override void Initialize(ModuleDef module) { } static Guid GetLanguageVendor(Guid language) { - if (language == Constants.LanguageCSharp || language == Constants.LanguageVisualBasic || language == Constants.LanguageFSharp) - return Constants.LanguageVendorMicrosoft; + if (language == PdbDocumentConstants.LanguageCSharp || language == PdbDocumentConstants.LanguageVisualBasic || language == PdbDocumentConstants.LanguageFSharp) + return PdbDocumentConstants.LanguageVendorMicrosoft; return Guid.Empty; } @@ -58,7 +58,7 @@ SymbolDocument[] ReadDocuments() { var url = nameReader.ReadDocumentName(nameOffset); var language = pdbMetaData.GuidStream.Read(languageIndex) ?? Guid.Empty; var languageVendor = GetLanguageVendor(language); - var documentType = Constants.DocumentTypeText; + var documentType = PdbDocumentConstants.DocumentTypeText; var checkSumAlgorithmId = pdbMetaData.GuidStream.Read(hashAlgorithmIndex) ?? Guid.Empty; var checkSum = pdbMetaData.BlobStream.ReadNoNull(hashOffset); diff --git a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs index b894901f7..1d0331b22 100644 --- a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs @@ -18,18 +18,18 @@ sealed class SymbolDocumentImpl : SymbolDocument { string GetDebuggerString() { var sb = new StringBuilder(); - if (language == Constants.LanguageCSharp) + if (language == PdbDocumentConstants.LanguageCSharp) sb.Append("C#"); - else if (language == Constants.LanguageVisualBasic) + else if (language == PdbDocumentConstants.LanguageVisualBasic) sb.Append("VB"); - else if (language == Constants.LanguageFSharp) + else if (language == PdbDocumentConstants.LanguageFSharp) sb.Append("F#"); else sb.Append(language.ToString()); sb.Append(", "); - if (checkSumAlgorithmId == Constants.HashSHA1) + if (checkSumAlgorithmId == PdbDocumentConstants.HashSHA1) sb.Append("SHA-1"); - else if (checkSumAlgorithmId == Constants.HashSHA256) + else if (checkSumAlgorithmId == PdbDocumentConstants.HashSHA256) sb.Append("SHA-256"); else sb.Append(checkSumAlgorithmId.ToString()); diff --git a/src/dnlib.csproj b/src/dnlib.csproj index afc38930c..82c7ef700 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -185,12 +185,12 @@ + - From 1a837a967dc2070f63f572b54ef4c23dfd851543 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 8 Nov 2017 18:55:46 +0100 Subject: [PATCH 063/511] Add portable PDB writer --- src/DotNet/MD/ENCMetaData.cs | 17 +- src/DotNet/MD/MDHeaderRuntimeVersion.cs | 5 + src/DotNet/MD/RawRowEqualityComparer.cs | 102 +- src/DotNet/MD/RawTableRows.cs | 344 +++++++ src/DotNet/MD/TablesStream_Read.cs | 192 +++- src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs | 4 +- src/DotNet/Pdb/ImageStreamUtils.cs | 3 +- src/DotNet/Pdb/ManagedSymbolReaderCreator.cs | 11 +- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 6 +- src/DotNet/Pdb/PdbFileKind.cs | 5 + src/DotNet/Pdb/PdbState.cs | 5 +- .../Pdb/Portable/ImportDefinitionKindUtils.cs | 42 + .../Pdb/Portable/ImportScopeBlobReader.cs | 23 +- .../Pdb/Portable/ImportScopeBlobWriter.cs | 103 ++ .../Portable/LocalConstantSigBlobReader.cs | 39 +- .../Portable/LocalConstantSigBlobWriter.cs | 316 ++++++ .../PortablePdbCustomDebugInfoWriter.cs | 263 +++++ src/DotNet/Pdb/Portable/PortablePdbReader.cs | 24 +- .../Pdb/Portable/SequencePointConstants.cs | 8 + .../Pdb/Portable/SymbolReaderCreator.cs | 43 +- src/DotNet/Pdb/SymbolReaderCreator.cs | 2 +- .../{PdbWriter.cs => WindowsPdbWriter.cs} | 15 +- src/DotNet/Writer/DebugDirectory.cs | 127 ++- src/DotNet/Writer/GuidHeap.cs | 24 +- src/DotNet/Writer/IChunk.cs | 15 - src/DotNet/Writer/MetaData.cs | 935 ++++++++++++++++-- src/DotNet/Writer/MetaDataHeader.cs | 16 + src/DotNet/Writer/ModuleWriter.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 204 +++- src/DotNet/Writer/NativeModuleWriter.cs | 22 +- src/DotNet/Writer/NormalMetaData.cs | 17 +- src/DotNet/Writer/PEHeaders.cs | 2 +- src/DotNet/Writer/PdbHeap.cs | 98 ++ src/DotNet/Writer/PortablePdbConstants.cs | 21 + src/DotNet/Writer/PreserveTokensMetaData.cs | 17 +- src/DotNet/Writer/SerializerMethodContext.cs | 68 ++ src/DotNet/Writer/TablesHeap.cs | 93 +- src/PE/IPEImage.cs | 5 + src/PE/ImageDebugDirectory.cs | 97 ++ src/PE/ImageDebugType.cs | 42 + src/PE/PEImage.cs | 41 +- src/dnlib.csproj | 12 +- 42 files changed, 3108 insertions(+), 322 deletions(-) create mode 100644 src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs create mode 100644 src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs create mode 100644 src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs create mode 100644 src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs create mode 100644 src/DotNet/Pdb/Portable/SequencePointConstants.cs rename src/DotNet/Pdb/WindowsPdb/{PdbWriter.cs => WindowsPdbWriter.cs} (96%) create mode 100644 src/DotNet/Writer/PdbHeap.cs create mode 100644 src/DotNet/Writer/PortablePdbConstants.cs create mode 100644 src/DotNet/Writer/SerializerMethodContext.cs create mode 100644 src/PE/ImageDebugDirectory.cs create mode 100644 src/PE/ImageDebugType.cs diff --git a/src/DotNet/MD/ENCMetaData.cs b/src/DotNet/MD/ENCMetaData.cs index 996967073..95783b99d 100644 --- a/src/DotNet/MD/ENCMetaData.cs +++ b/src/DotNet/MD/ENCMetaData.cs @@ -98,6 +98,17 @@ protected override void InitializeInternal(IImageStream mdStream) { continue; } break; + + case "#PDB": + // Case sensitive comparison since it's a stream that's not read by the CLR, + // only by other libraries eg. System.Reflection.Metadata. + if (isStandalonePortablePdb && pdbStream == null && sh.Name == "#Pdb") { + pdbStream = new PdbStream(imageStream, sh); + imageStream = null; + allStreams.Add(pdbStream); + continue; + } + break; } dns = new DotNetStream(imageStream, sh); imageStream = null; @@ -116,7 +127,11 @@ protected override void InitializeInternal(IImageStream mdStream) { if (tablesStream == null) throw new BadImageFormatException("Missing MD stream"); - tablesStream.Initialize(null); + + if (pdbStream != null) + tablesStream.Initialize(pdbStream.TypeSystemTableRows); + else + tablesStream.Initialize(null); // The pointer tables are used iff row count != 0 hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty; diff --git a/src/DotNet/MD/MDHeaderRuntimeVersion.cs b/src/DotNet/MD/MDHeaderRuntimeVersion.cs index 8b04f347e..0eec0e7cc 100644 --- a/src/DotNet/MD/MDHeaderRuntimeVersion.cs +++ b/src/DotNet/MD/MDHeaderRuntimeVersion.cs @@ -74,5 +74,10 @@ public static class MDHeaderRuntimeVersion { /// ECMA 2005 version string /// public const string ECMA_2005 = "Standard CLI 2005"; + + /// + /// Portable PDB v1.0 + /// + public const string PORTABLE_PDB_V1_0 = "PDB v1.0"; } } diff --git a/src/DotNet/MD/RawRowEqualityComparer.cs b/src/DotNet/MD/RawRowEqualityComparer.cs index 0bcaa0101..51b64db35 100644 --- a/src/DotNet/MD/RawRowEqualityComparer.cs +++ b/src/DotNet/MD/RawRowEqualityComparer.cs @@ -30,7 +30,11 @@ public sealed class RawRowEqualityComparer : IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer { + IEqualityComparer, IEqualityComparer, + IEqualityComparer, IEqualityComparer, + IEqualityComparer, IEqualityComparer, + IEqualityComparer, IEqualityComparer, + IEqualityComparer, IEqualityComparer { /// /// Default instance @@ -574,5 +578,101 @@ public int GetHashCode(RawGenericParamConstraintRow obj) { return (int)obj.Owner + rol(obj.Constraint, 3); } + + public bool Equals(RawDocumentRow x, RawDocumentRow y) { + return x.Name == y.Name && + x.HashAlgorithm == y.HashAlgorithm && + x.Hash == y.Hash && + x.Language == y.Language; + } + + public int GetHashCode(RawDocumentRow obj) { + return (int)obj.Name + + rol(obj.HashAlgorithm, 3) + + rol(obj.Hash, 7) + + rol(obj.Language, 11); + } + + public bool Equals(RawMethodDebugInformationRow x, RawMethodDebugInformationRow y) { + return x.Document == y.Document && + x.SequencePoints == y.SequencePoints; + } + + public int GetHashCode(RawMethodDebugInformationRow obj) { + return (int)obj.Document + + rol(obj.SequencePoints, 3); + } + + public bool Equals(RawLocalScopeRow x, RawLocalScopeRow y) { + return x.Method == y.Method && + x.ImportScope == y.ImportScope && + x.VariableList == y.VariableList && + x.ConstantList == y.ConstantList && + x.StartOffset == y.StartOffset && + x.Length == y.Length; + } + + public int GetHashCode(RawLocalScopeRow obj) { + return (int)obj.Method + + rol(obj.ImportScope, 3) + + rol(obj.VariableList, 7) + + rol(obj.ConstantList, 11) + + rol(obj.StartOffset, 15) + + rol(obj.Length, 19); + } + + public bool Equals(RawLocalVariableRow x, RawLocalVariableRow y) { + return x.Attributes == y.Attributes && + x.Index == y.Index && + x.Name == y.Name; + } + + public int GetHashCode(RawLocalVariableRow obj) { + return obj.Attributes + + rol(obj.Index, 3) + + rol(obj.Name, 7); + } + + public bool Equals(RawLocalConstantRow x, RawLocalConstantRow y) { + return x.Name == y.Name && + x.Signature == y.Signature; + } + + public int GetHashCode(RawLocalConstantRow obj) { + return (int)obj.Name + + rol(obj.Signature, 3); + } + + public bool Equals(RawImportScopeRow x, RawImportScopeRow y) { + return x.Parent == y.Parent && + x.Imports == y.Imports; + } + + public int GetHashCode(RawImportScopeRow obj) { + return (int)obj.Parent + + rol(obj.Imports, 3); + } + + public bool Equals(RawStateMachineMethodRow x, RawStateMachineMethodRow y) { + return x.MoveNextMethod == y.MoveNextMethod && + x.KickoffMethod == y.KickoffMethod; + } + + public int GetHashCode(RawStateMachineMethodRow obj) { + return (int)obj.MoveNextMethod + + rol(obj.KickoffMethod, 3); + } + + public bool Equals(RawCustomDebugInformationRow x, RawCustomDebugInformationRow y) { + return x.Parent == y.Parent && + x.Kind == y.Kind && + x.Value == y.Value; + } + + public int GetHashCode(RawCustomDebugInformationRow obj) { + return (int)obj.Parent + + rol(obj.Kind, 3) + + rol(obj.Value, 7); + } } } diff --git a/src/DotNet/MD/RawTableRows.cs b/src/DotNet/MD/RawTableRows.cs index 255bab4be..406e7cfbb 100644 --- a/src/DotNet/MD/RawTableRows.cs +++ b/src/DotNet/MD/RawTableRows.cs @@ -1945,4 +1945,348 @@ public void Write(int index, uint value) { } } } + + /// + /// Raw contents of an uncompressed Document table row + /// + public sealed class RawDocumentRow : IRawRow { + /// + public uint Name; + /// + public uint HashAlgorithm; + /// + public uint Hash; + /// + public uint Language; + + /// Default constructor + public RawDocumentRow() { + } + + /// Constructor + public RawDocumentRow(uint Name, uint HashAlgorithm, uint Hash, uint Language) { + this.Name = Name; + this.HashAlgorithm = HashAlgorithm; + this.Hash = Hash; + this.Language = Language; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Name; + case 1: return HashAlgorithm; + case 2: return Hash; + case 3: return Language; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Name = value; break; + case 1: HashAlgorithm = value; break; + case 2: Hash = value; break; + case 3: Language = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed MethodDebugInformation table row + /// + public sealed class RawMethodDebugInformationRow : IRawRow { + /// + public uint Document; + /// + public uint SequencePoints; + + /// Default constructor + public RawMethodDebugInformationRow() { + } + + /// Constructor + public RawMethodDebugInformationRow(uint Document, uint SequencePoints) { + this.Document = Document; + this.SequencePoints = SequencePoints; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Document; + case 1: return SequencePoints; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Document = value; break; + case 1: SequencePoints = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed LocalScope table row + /// + public sealed class RawLocalScopeRow : IRawRow { + /// + public uint Method; + /// + public uint ImportScope; + /// + public uint VariableList; + /// + public uint ConstantList; + /// + public uint StartOffset; + /// + public uint Length; + + /// Default constructor + public RawLocalScopeRow() { + } + + /// Constructor + public RawLocalScopeRow(uint Method, uint ImportScope, uint VariableList, uint ConstantList, uint StartOffset, uint Length) { + this.Method = Method; + this.ImportScope = ImportScope; + this.VariableList = VariableList; + this.ConstantList = ConstantList; + this.StartOffset = StartOffset; + this.Length = Length; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Method; + case 1: return ImportScope; + case 2: return VariableList; + case 3: return ConstantList; + case 4: return StartOffset; + case 5: return Length; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Method = value; break; + case 1: ImportScope = value; break; + case 2: VariableList = value; break; + case 3: ConstantList = value; break; + case 4: StartOffset = value; break; + case 5: Length = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed LocalVariable table row + /// + public sealed class RawLocalVariableRow : IRawRow { + /// + public ushort Attributes; + /// + public ushort Index; + /// + public uint Name; + + /// Default constructor + public RawLocalVariableRow() { + } + + /// Constructor + public RawLocalVariableRow(ushort Attributes, ushort Index, uint Name) { + this.Attributes = Attributes; + this.Index = Index; + this.Name = Name; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Attributes; + case 1: return Index; + case 2: return Name; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Attributes = (ushort)value; break; + case 1: Index = (ushort)value; break; + case 2: Name = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed LocalConstant table row + /// + public sealed class RawLocalConstantRow : IRawRow { + /// + public uint Name; + /// + public uint Signature; + + /// Default constructor + public RawLocalConstantRow() { + } + + /// Constructor + public RawLocalConstantRow(uint Name, uint Signature) { + this.Name = Name; + this.Signature = Signature; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Name; + case 1: return Signature; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Name = value; break; + case 1: Signature = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed ImportScope table row + /// + public sealed class RawImportScopeRow : IRawRow { + /// + public uint Parent; + /// + public uint Imports; + + /// Default constructor + public RawImportScopeRow() { + } + + /// Constructor + public RawImportScopeRow(uint Parent, uint Imports) { + this.Parent = Parent; + this.Imports = Imports; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Parent; + case 1: return Imports; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Parent = value; break; + case 1: Imports = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed StateMachineMethod table row + /// + public sealed class RawStateMachineMethodRow : IRawRow { + /// + public uint MoveNextMethod; + /// + public uint KickoffMethod; + + /// Default constructor + public RawStateMachineMethodRow() { + } + + /// Constructor + public RawStateMachineMethodRow(uint MoveNextMethod, uint KickoffMethod) { + this.MoveNextMethod = MoveNextMethod; + this.KickoffMethod = KickoffMethod; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return MoveNextMethod; + case 1: return KickoffMethod; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: MoveNextMethod = value; break; + case 1: KickoffMethod = value; break; + default: break; + } + } + } + + /// + /// Raw contents of an uncompressed CustomDebugInformation table row + /// + public sealed class RawCustomDebugInformationRow : IRawRow { + /// + public uint Parent; + /// + public uint Kind; + /// + public uint Value; + + /// Default constructor + public RawCustomDebugInformationRow() { + } + + /// Constructor + public RawCustomDebugInformationRow(uint Parent, uint Kind, uint Value) { + this.Parent = Parent; + this.Kind = Kind; + this.Value = Value; + } + + /// + public uint Read(int index) { + switch (index) { + case 0: return Parent; + case 1: return Kind; + case 2: return Value; + default: return 0; + } + } + + /// + public void Write(int index, uint value) { + switch (index) { + case 0: Parent = value; break; + case 1: Kind = value; break; + case 2: Value = value; break; + default: break; + } + } + } } diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index 7a3f5ab88..310dadcc3 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -1690,15 +1690,24 @@ internal uint ReadGenericParamConstraintRow2(uint rid) { #endif } - internal uint ReadMethodDebugInformationRow2(uint rid, out uint document) { - var table = MethodDebugInformationTable; + /// + /// Reads a raw Document row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawDocumentRow ReadDocumentRow(uint rid) { + var table = DocumentTable; + if (table.IsInvalidRID(rid)) + return null; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif var reader = GetReader_NoLock(table, rid); var columns = table.TableInfo.Columns; - document = columns[0].Read(reader); - return columns[1].Read(reader); + return new RawDocumentRow(columns[0].Read(reader), + columns[1].Read(reader), + columns[2].Read(reader), + columns[3].Read(reader)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -1720,6 +1729,66 @@ internal uint ReadDocumentRow2(uint rid, out uint name, out uint hashAlgorithm, #endif } + /// + /// Reads a raw MethodDebugInformation row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawMethodDebugInformationRow ReadMethodDebugInformationRow(uint rid) { + var table = MethodDebugInformationTable; + if (table.IsInvalidRID(rid)) + return null; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + return new RawMethodDebugInformationRow(columns[0].Read(reader), + columns[1].Read(reader)); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadMethodDebugInformationRow2(uint rid, out uint document) { + var table = MethodDebugInformationTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + document = columns[0].Read(reader); + return columns[1].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + /// + /// Reads a raw LocalScope row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawLocalScopeRow ReadLocalScopeRow(uint rid) { + var table = LocalScopeTable; + if (table.IsInvalidRID(rid)) + return null; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + return new RawLocalScopeRow(columns[0].Read(reader), + columns[1].Read(reader), + columns[2].Read(reader), + columns[3].Read(reader), + reader.ReadUInt32(), + reader.ReadUInt32()); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + internal uint ReadLocalScopeRow2(uint rid, out uint importScope, out uint variableList, out uint constantList, out uint startOffset) { var table = LocalScopeTable; #if THREAD_SAFE @@ -1738,15 +1807,23 @@ internal uint ReadLocalScopeRow2(uint rid, out uint importScope, out uint variab #endif } - internal uint ReadImportScopeRow2(uint rid, out uint parent) { - var table = ImportScopeTable; + /// + /// Reads a raw LocalVariable row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawLocalVariableRow ReadLocalVariableRow(uint rid) { + var table = LocalVariableTable; + if (table.IsInvalidRID(rid)) + return null; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif var reader = GetReader_NoLock(table, rid); var columns = table.TableInfo.Columns; - parent = columns[0].Read(reader); - return columns[1].Read(reader); + return new RawLocalVariableRow(reader.ReadUInt16(), + reader.ReadUInt16(), + columns[2].Read(reader)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -1767,6 +1844,27 @@ internal uint ReadLocalVariableRow2(uint rid, out ushort attributes, out ushort #endif } + /// + /// Reads a raw LocalConstant row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawLocalConstantRow ReadLocalConstantRow(uint rid) { + var table = LocalConstantTable; + if (table.IsInvalidRID(rid)) + return null; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + return new RawLocalConstantRow(columns[0].Read(reader), + columns[1].Read(reader)); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + internal uint ReadLocalConstantRow2(uint rid, out uint name) { var table = LocalConstantTable; #if THREAD_SAFE @@ -1781,6 +1879,62 @@ internal uint ReadLocalConstantRow2(uint rid, out uint name) { #endif } + /// + /// Reads a raw ImportScope row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawImportScopeRow ReadImportScopeRow(uint rid) { + var table = ImportScopeTable; + if (table.IsInvalidRID(rid)) + return null; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + return new RawImportScopeRow(columns[0].Read(reader), + columns[1].Read(reader)); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + internal uint ReadImportScopeRow2(uint rid, out uint parent) { + var table = ImportScopeTable; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + parent = columns[0].Read(reader); + return columns[1].Read(reader); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + + /// + /// Reads a raw StateMachineMethod row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawStateMachineMethodRow ReadStateMachineMethodRow(uint rid) { + var table = StateMachineMethodTable; + if (table.IsInvalidRID(rid)) + return null; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + return new RawStateMachineMethodRow(columns[0].Read(reader), + columns[1].Read(reader)); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + internal uint ReadStateMachineMethodRow2(uint rid) { var table = StateMachineMethodTable; #if THREAD_SAFE @@ -1795,6 +1949,28 @@ internal uint ReadStateMachineMethodRow2(uint rid) { #endif } + /// + /// Reads a raw CustomDebugInformation row + /// + /// Row ID + /// The row or null if table doesn't exist or if is invalid + public RawCustomDebugInformationRow ReadCustomDebugInformationRow(uint rid) { + var table = CustomDebugInformationTable; + if (table.IsInvalidRID(rid)) + return null; +#if THREAD_SAFE + theLock.EnterWriteLock(); try { +#endif + var reader = GetReader_NoLock(table, rid); + var columns = table.TableInfo.Columns; + return new RawCustomDebugInformationRow(columns[0].Read(reader), + columns[1].Read(reader), + columns[2].Read(reader)); +#if THREAD_SAFE + } finally { theLock.ExitWriteLock(); } +#endif + } + internal uint ReadCustomDebugInformationRow2(uint rid, out uint kind) { var table = CustomDebugInformationTable; #if THREAD_SAFE diff --git a/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs b/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs index e397d49f7..7b38564e9 100644 --- a/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs +++ b/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs @@ -1,5 +1,7 @@ // dnlib: See LICENSE.txt for more info +using dnlib.PE; + namespace dnlib.DotNet.Pdb { /// /// IMAGE_DEBUG_DIRECTORY @@ -10,7 +12,7 @@ public struct IMAGE_DEBUG_DIRECTORY { public uint TimeDateStamp; public ushort MajorVersion; public ushort MinorVersion; - public uint Type; + public ImageDebugType Type; public uint SizeOfData; public uint AddressOfRawData; public uint PointerToRawData; diff --git a/src/DotNet/Pdb/ImageStreamUtils.cs b/src/DotNet/Pdb/ImageStreamUtils.cs index 1538154a2..4dd6ab923 100644 --- a/src/DotNet/Pdb/ImageStreamUtils.cs +++ b/src/DotNet/Pdb/ImageStreamUtils.cs @@ -11,7 +11,8 @@ public static IImageStream OpenImageStream(string fileName) { try { if (!File.Exists(fileName)) return null; - return ImageStreamCreator.CreateImageStream(fileName); + // Don't use memory mapped I/O + return MemoryImageStream.Create(File.ReadAllBytes(fileName)); } catch (IOException) { } diff --git a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs index 8b65f23e8..9ad8375f4 100644 --- a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs +++ b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs @@ -23,10 +23,13 @@ public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { try { // Embedded pdbs have priority var res = Create(metaData); - if (res != null) + if (res != null) { + if (pdbStream != null) + pdbStream.Dispose(); return res; + } - return CreateCore(metaData, pdbStream); + return CreateCore(pdbStream); } catch { if (pdbStream != null) @@ -35,14 +38,14 @@ public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { } } - static SymbolReader CreateCore(IMetaData metaData, IImageStream pdbStream) { + static SymbolReader CreateCore(IImageStream pdbStream) { if (pdbStream == null) return null; try { uint sig = pdbStream.ReadUInt32(); pdbStream.Position = 0; if (sig == 0x424A5342) - return Portable.SymbolReaderCreator.TryCreate(metaData, pdbStream); + return Portable.SymbolReaderCreator.TryCreate(pdbStream, false); return Managed.SymbolReaderCreator.Create(pdbStream); } catch (IOException) { diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 310da675d..356eb422a 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -781,7 +781,7 @@ public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) { /// /// It's internal and translated to a /// - internal sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { + sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { readonly ThreadSafe.IList asyncStepInfos; /// @@ -1065,10 +1065,10 @@ public PdbAsyncStepInfo(Instruction yieldInstruction, MethodDef breakpointMethod /// public sealed class PdbIteratorMethodCustomDebugInfo : PdbCustomDebugInfo { /// - /// Returns + /// Returns /// public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.AsyncMethod; } + get { return PdbCustomDebugInfoKind.IteratorMethod; } } /// diff --git a/src/DotNet/Pdb/PdbFileKind.cs b/src/DotNet/Pdb/PdbFileKind.cs index 941746f2d..72f7ce47a 100644 --- a/src/DotNet/Pdb/PdbFileKind.cs +++ b/src/DotNet/Pdb/PdbFileKind.cs @@ -14,5 +14,10 @@ public enum PdbFileKind { /// Portable PDB /// PortablePDB, + + /// + /// Embedded portable PDB + /// + EmbeddedPortablePDB, } } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 6cd2370d2..0324195cf 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -23,9 +23,10 @@ public sealed class PdbState { #endif /// - /// Gets the PDB file kind + /// Gets/sets the PDB file kind. You can change it from portable PDB to embedded portable PDB + /// and vice versa. Converting a Windows PDB to a portable PDB isn't supported. /// - public PdbFileKind PdbFileKind { get; private set; } + public PdbFileKind PdbFileKind { get; set; } /// /// Gets/sets the user entry point method. diff --git a/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs b/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs new file mode 100644 index 000000000..6e92e3f0c --- /dev/null +++ b/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs @@ -0,0 +1,42 @@ +// dnlib: See LICENSE.txt for more info + +using System.Diagnostics; + +namespace dnlib.DotNet.Pdb.Portable { + static class ImportDefinitionKindUtils { + public const PdbImportDefinitionKind UNKNOWN_IMPORT_KIND = (PdbImportDefinitionKind)(-1); + + public static PdbImportDefinitionKind ToPdbImportDefinitionKind(uint value) { + // See System.Reflection.Metadata.ImportDefinitionKind + switch (value) { + case 1: return PdbImportDefinitionKind.ImportNamespace; + case 2: return PdbImportDefinitionKind.ImportAssemblyNamespace; + case 3: return PdbImportDefinitionKind.ImportType; + case 4: return PdbImportDefinitionKind.ImportXmlNamespace; + case 5: return PdbImportDefinitionKind.ImportAssemblyReferenceAlias; + case 6: return PdbImportDefinitionKind.AliasAssemblyReference; + case 7: return PdbImportDefinitionKind.AliasNamespace; + case 8: return PdbImportDefinitionKind.AliasAssemblyNamespace; + case 9: return PdbImportDefinitionKind.AliasType; + default: + Debug.Fail("Unknown import definition kind: 0x" + value.ToString("X")); + return UNKNOWN_IMPORT_KIND; + } + } + + public static bool ToImportDefinitionKind(PdbImportDefinitionKind kind, out uint rawKind) { + switch (kind) { + case PdbImportDefinitionKind.ImportNamespace: rawKind = 1; return true; + case PdbImportDefinitionKind.ImportAssemblyNamespace: rawKind = 2; return true; + case PdbImportDefinitionKind.ImportType: rawKind = 3; return true; + case PdbImportDefinitionKind.ImportXmlNamespace: rawKind = 4; return true; + case PdbImportDefinitionKind.ImportAssemblyReferenceAlias: rawKind = 5; return true; + case PdbImportDefinitionKind.AliasAssemblyReference: rawKind = 6; return true; + case PdbImportDefinitionKind.AliasNamespace: rawKind = 7; return true; + case PdbImportDefinitionKind.AliasAssemblyNamespace: rawKind = 8; return true; + case PdbImportDefinitionKind.AliasType: rawKind = 9; return true; + default: rawKind = uint.MaxValue; return false; + } + } + } +} diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index 1c53e3d27..ad41cf60d 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -9,7 +9,6 @@ namespace dnlib.DotNet.Pdb.Portable { // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#imports-blob struct ImportScopeBlobReader { - const PdbImportDefinitionKind UNKNOWN_IMPORT_KIND = (PdbImportDefinitionKind)(-1); readonly ModuleDef module; readonly BlobStream blobStream; @@ -28,7 +27,7 @@ public void Read(uint imports, IList result) { return; using (var stream = blobStream.CreateStream(imports)) { while (stream.Position < stream.Length) { - var kind = ToPdbImportDefinitionKind(stream.ReadCompressedUInt32()); + var kind = ImportDefinitionKindUtils.ToPdbImportDefinitionKind(stream.ReadCompressedUInt32()); string targetNamespace, alias; AssemblyRef targetAssembly; PdbImport import; @@ -95,7 +94,7 @@ public void Read(uint imports, IList result) { import = new PdbAliasType(alias, targetType); break; - case UNKNOWN_IMPORT_KIND: + case ImportDefinitionKindUtils.UNKNOWN_IMPORT_KIND: import = null; break; @@ -132,23 +131,5 @@ string ReadUTF8(uint offset) { var bytes = blobStream.ReadNoNull(offset); return Encoding.UTF8.GetString(bytes); } - - static PdbImportDefinitionKind ToPdbImportDefinitionKind(uint value) { - // See System.Reflection.Metadata.ImportDefinitionKind - switch (value) { - case 1: return PdbImportDefinitionKind.ImportNamespace; - case 2: return PdbImportDefinitionKind.ImportAssemblyNamespace; - case 3: return PdbImportDefinitionKind.ImportType; - case 4: return PdbImportDefinitionKind.ImportXmlNamespace; - case 5: return PdbImportDefinitionKind.ImportAssemblyReferenceAlias; - case 6: return PdbImportDefinitionKind.AliasAssemblyReference; - case 7: return PdbImportDefinitionKind.AliasNamespace; - case 8: return PdbImportDefinitionKind.AliasAssemblyNamespace; - case 9: return PdbImportDefinitionKind.AliasType; - default: - Debug.Fail("Unknown import definition kind: 0x" + value.ToString("X")); - return UNKNOWN_IMPORT_KIND; - } - } } } diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs new file mode 100644 index 000000000..7264957cc --- /dev/null +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -0,0 +1,103 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.IO; +using System.Text; +using dnlib.DotNet.Writer; + +namespace dnlib.DotNet.Pdb.Portable { + // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#imports-blob + struct ImportScopeBlobWriter { + readonly IWriterError helper; + readonly MetaData systemMetaData; + readonly BlobHeap blobHeap; + + ImportScopeBlobWriter(IWriterError helper, MetaData systemMetaData, BlobHeap blobHeap) { + this.helper = helper; + this.systemMetaData = systemMetaData; + this.blobHeap = blobHeap; + } + + public static void Write(IWriterError helper, MetaData systemMetaData, BinaryWriter writer, BlobHeap blobHeap, IList imports) { + var blobWriter = new ImportScopeBlobWriter(helper, systemMetaData, blobHeap); + blobWriter.Write(writer, imports); + } + + uint WriteUTF8(string s) { + if (s == null) { + helper.Error("String is null"); + s = string.Empty; + } + var bytes = Encoding.UTF8.GetBytes(s); + return blobHeap.Add(bytes); + } + + void Write(BinaryWriter writer, IList imports) { + foreach (var import in imports) { + uint rawKind; + if (!ImportDefinitionKindUtils.ToImportDefinitionKind(import.Kind, out rawKind)) { + helper.Error("Unknown import definition kind: " + import.Kind.ToString()); + return; + } + writer.WriteCompressedUInt32(rawKind); + switch (import.Kind) { + case PdbImportDefinitionKind.ImportNamespace: + // ::= ImportNamespace + writer.WriteCompressedUInt32(WriteUTF8(((PdbImportNamespace)import).TargetNamespace)); + break; + + case PdbImportDefinitionKind.ImportAssemblyNamespace: + // ::= ImportAssemblyNamespace + writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbImportAssemblyNamespace)import).TargetAssembly).Rid); + writer.WriteCompressedUInt32(WriteUTF8(((PdbImportAssemblyNamespace)import).TargetNamespace)); + break; + + case PdbImportDefinitionKind.ImportType: + // ::= ImportType + writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbImportType)import).TargetType).Rid); + break; + + case PdbImportDefinitionKind.ImportXmlNamespace: + // ::= ImportXmlNamespace + writer.WriteCompressedUInt32(WriteUTF8(((PdbImportXmlNamespace)import).Alias)); + writer.WriteCompressedUInt32(WriteUTF8(((PdbImportXmlNamespace)import).TargetNamespace)); + break; + + case PdbImportDefinitionKind.ImportAssemblyReferenceAlias: + // ::= ImportReferenceAlias + writer.WriteCompressedUInt32(WriteUTF8(((PdbImportAssemblyReferenceAlias)import).Alias)); + break; + + case PdbImportDefinitionKind.AliasAssemblyReference: + // ::= AliasAssemblyReference + writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasAssemblyReference)import).Alias)); + writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbAliasAssemblyReference)import).TargetAssembly).Rid); + break; + + case PdbImportDefinitionKind.AliasNamespace: + // ::= AliasNamespace + writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasNamespace)import).Alias)); + writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasNamespace)import).TargetNamespace)); + break; + + case PdbImportDefinitionKind.AliasAssemblyNamespace: + // ::= AliasAssemblyNamespace + writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasAssemblyNamespace)import).Alias)); + writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbAliasAssemblyNamespace)import).TargetAssembly).Rid); + writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasAssemblyNamespace)import).TargetNamespace)); + break; + + case PdbImportDefinitionKind.AliasType: + // ::= AliasType + writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasType)import).Alias)); + writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbAliasType)import).TargetType).Rid); + break; + + default: + helper.Error("Unknown import definition kind: " + import.Kind.ToString()); + return; + } + } + } + } +} diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index dd5234d25..a77c61b71 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -46,7 +46,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.Boolean; value = reader.ReadBoolean(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -54,7 +54,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.Char; value = (char)reader.ReadUInt16(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -62,7 +62,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.SByte; value = reader.ReadSByte(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -70,7 +70,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.Byte; value = reader.ReadByte(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -78,7 +78,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.Int16; value = reader.ReadInt16(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -86,7 +86,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.UInt16; value = reader.ReadUInt16(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -94,7 +94,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.Int32; value = reader.ReadInt32(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -102,7 +102,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.UInt32; value = reader.ReadUInt32(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -110,7 +110,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.Int64; value = reader.ReadInt64(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -118,7 +118,7 @@ bool ReadCore(out TypeSig type, out object value) { type = module.CorLibTypes.UInt64; value = reader.ReadUInt64(); if (reader.Position < reader.Length) - type = new ValueTypeSig(ReadTypeDefOrRef()); + type = ReadTypeDefOrRefSig(); res = true; break; @@ -140,7 +140,6 @@ bool ReadCore(out TypeSig type, out object value) { res = true; break; - case ElementType.Ptr: res = Read(out type, out value); if (res) @@ -160,7 +159,8 @@ bool ReadCore(out TypeSig type, out object value) { break; case ElementType.ValueType: - type = new ValueTypeSig(tdr = ReadTypeDefOrRef()); + tdr = ReadTypeDefOrRef(); + type = tdr.ToTypeSig(); value = null; if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib()) { if (name == stringDecimal) { @@ -262,12 +262,25 @@ static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String return false; } + TypeSig ReadTypeDefOrRefSig() { + uint codedToken; + if (!reader.ReadCompressedUInt32(out codedToken)) + return null; + ISignatureReaderHelper helper = module; + var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); + return tdr.ToTypeSig(); + } + ITypeDefOrRef ReadTypeDefOrRef() { uint codedToken; if (!reader.ReadCompressedUInt32(out codedToken)) return null; ISignatureReaderHelper helper = module; - return helper.ResolveTypeDefOrRef(codedToken, gpContext); + var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); + var corType = module.CorLibTypes.GetCorLibTypeSig(tdr); + if (corType != null) + return corType.TypeDefOrRef; + return tdr; } string ReadString() { diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs new file mode 100644 index 000000000..5b088e907 --- /dev/null +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -0,0 +1,316 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; +using System.Text; +using dnlib.DotNet.Writer; + +namespace dnlib.DotNet.Pdb.Portable { + struct LocalConstantSigBlobWriter { + readonly IWriterError helper; + readonly MetaData systemMetaData; + + LocalConstantSigBlobWriter(IWriterError helper, MetaData systemMetaData) { + this.helper = helper; + this.systemMetaData = systemMetaData; + } + + public static void Write(IWriterError helper, MetaData systemMetaData, BinaryWriter writer, TypeSig type, object value) { + var sigWriter = new LocalConstantSigBlobWriter(helper, systemMetaData); + sigWriter.Write(writer, type, value); + } + + void Write(BinaryWriter writer, TypeSig type, object value) { + for (; ; type = type.Next) { + if (type == null) + return; + + var et = type.ElementType; + writer.Write((byte)et); + switch (et) { + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I1: + case ElementType.U1: + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + WritePrimitiveValue(writer, et, value); + return; + + case ElementType.R4: + if (value is float) + writer.Write((float)value); + else { + helper.Error("Expected a Single constant"); + writer.Write((float)0); + } + return; + + case ElementType.R8: + if (value is double) + writer.Write((double)value); + else { + helper.Error("Expected a Double constant"); + writer.Write((double)0); + } + return; + + case ElementType.String: + if (value == null) + writer.Write((byte)0xFF); + else if (value is string) + writer.Write(Encoding.Unicode.GetBytes((string)value)); + else + helper.Error("Expected a String constant"); + return; + + case ElementType.Ptr: + case ElementType.ByRef: + WriteTypeDefOrRef(writer, new TypeSpecUser(type)); + return; + + case ElementType.Object: + return; + + case ElementType.ValueType: + var tdr = ((ValueTypeSig)type).TypeDefOrRef; + var td = tdr.ResolveTypeDef(); + if (td == null) + helper.Error(string.Format("Couldn't resolve type 0x{0:X8}", tdr == null ? 0 : tdr.MDToken.Raw)); + else if (td.IsEnum) { + var underlyingType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers(); + switch (underlyingType.GetElementType()) { + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I1: + case ElementType.U1: + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + writer.BaseStream.Position--; + writer.Write((byte)underlyingType.GetElementType()); + WritePrimitiveValue(writer, underlyingType.GetElementType(), value); + WriteTypeDefOrRef(writer, tdr); + return; + default: + helper.Error("Invalid enum underlying type"); + return; + } + } + else { + WriteTypeDefOrRef(writer, tdr); + UTF8String ns, name; + bool valueWritten = false; + if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib()) { + if (name == stringDecimal) { + if (value is decimal) { + var bits = decimal.GetBits((decimal)value); + writer.Write((byte)((((uint)bits[3] >> 31) << 7) | (((uint)bits[3] >> 16) & 0x7F))); + writer.Write(bits[0]); + writer.Write(bits[1]); + writer.Write(bits[2]); + } + else { + helper.Error("Expected a Decimal constant"); + writer.Write(new byte[13]); + } + valueWritten = true; + } + else if (name == stringDateTime) { + if (value is DateTime) + writer.Write(((DateTime)value).Ticks); + else { + helper.Error("Expected a DateTime constant"); + writer.Write(0L); + } + valueWritten = true; + } + } + if (!valueWritten) { + if (value is byte[]) + writer.Write((byte[])value); + else if (value != null) { + helper.Error("Unsupported constant: " + value.GetType().FullName); + return; + } + } + } + return; + + case ElementType.Class: + WriteTypeDefOrRef(writer, ((ClassSig)type).TypeDefOrRef); + if (value is byte[]) + writer.Write((byte[])value); + else if (value != null) + helper.Error("Expected a null constant"); + return; + + case ElementType.CModReqd: + case ElementType.CModOpt: + WriteTypeDefOrRef(writer, ((ModifierSig)type).Modifier); + break; + + case ElementType.Var: + case ElementType.Array: + case ElementType.GenericInst: + case ElementType.TypedByRef: + case ElementType.I: + case ElementType.U: + case ElementType.FnPtr: + case ElementType.SZArray: + case ElementType.MVar: + WriteTypeDefOrRef(writer, new TypeSpecUser(type)); + return; + + case ElementType.End: + case ElementType.Void: + case ElementType.ValueArray: + case ElementType.R: + case ElementType.Internal: + case ElementType.Module: + case ElementType.Sentinel: + case ElementType.Pinned: + default: + helper.Error("Unsupported element type in LocalConstant sig blob: " + et.ToString()); + return; + } + } + } + static readonly UTF8String stringSystem = new UTF8String("System"); + static readonly UTF8String stringDecimal = new UTF8String("Decimal"); + static readonly UTF8String stringDateTime = new UTF8String("DateTime"); + + static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String name) { + var tr = tdr as TypeRef; + if (tr != null) { + @namespace = tr.Namespace; + name = tr.Name; + return true; + } + + var td = tdr as TypeDef; + if (td != null) { + @namespace = td.Namespace; + name = td.Name; + return true; + } + + @namespace = null; + name = null; + return false; + } + + void WritePrimitiveValue(BinaryWriter writer, ElementType et, object value) { + switch (et) { + case ElementType.Boolean: + if (value is bool) + writer.Write((bool)value); + else { + helper.Error("Expected a Boolean constant"); + writer.Write(false); + } + break; + + case ElementType.Char: + if (value is char) + writer.Write((ushort)(char)value); + else { + helper.Error("Expected a Char constant"); + writer.Write((ushort)0); + } + break; + + case ElementType.I1: + if (value is sbyte) + writer.Write((sbyte)value); + else { + helper.Error("Expected a SByte constant"); + writer.Write((sbyte)0); + } + break; + + case ElementType.U1: + if (value is byte) + writer.Write((byte)value); + else { + helper.Error("Expected a Byte constant"); + writer.Write((byte)0); + } + break; + + case ElementType.I2: + if (value is short) + writer.Write((short)value); + else { + helper.Error("Expected an Int16 constant"); + writer.Write((short)0); + } + break; + + case ElementType.U2: + if (value is ushort) + writer.Write((ushort)value); + else { + helper.Error("Expected a UInt16 constant"); + writer.Write((ushort)0); + } + break; + + case ElementType.I4: + if (value is int) + writer.Write((int)value); + else { + helper.Error("Expected an Int32 constant"); + writer.Write((int)0); + } + break; + + case ElementType.U4: + if (value is uint) + writer.Write((uint)value); + else { + helper.Error("Expected a UInt32 constant"); + writer.Write((uint)0); + } + break; + + case ElementType.I8: + if (value is long) + writer.Write((long)value); + else { + helper.Error("Expected an Int64 constant"); + writer.Write((long)0); + } + break; + + case ElementType.U8: + if (value is ulong) + writer.Write((ulong)value); + else { + helper.Error("Expected a UInt64 constant"); + writer.Write((ulong)0); + } + break; + + default: + throw new InvalidOperationException(); + } + } + + void WriteTypeDefOrRef(BinaryWriter writer, ITypeDefOrRef tdr) { + uint codedToken; + if (!MD.CodedToken.TypeDefOrRef.Encode(systemMetaData.GetToken(tdr), out codedToken)) { + helper.Error("Couldn't encode a TypeDefOrRef"); + return; + } + writer.WriteCompressedUInt32(codedToken); + } + } +} diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs new file mode 100644 index 000000000..f8038d6bf --- /dev/null +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -0,0 +1,263 @@ +// dnlib: See LICENSE.txt for more info + +using System.IO; +using System.Text; +using dnlib.DotNet.Emit; +using dnlib.DotNet.Writer; + +namespace dnlib.DotNet.Pdb.Portable { + interface IPortablePdbCustomDebugInfoWriterHelper : IWriterError { + } + + struct PortablePdbCustomDebugInfoWriter { + readonly IPortablePdbCustomDebugInfoWriterHelper helper; + readonly SerializerMethodContext methodContext; + readonly MetaData systemMetaData; + readonly MemoryStream outStream; + readonly BinaryWriter writer; + + public static byte[] Write(IPortablePdbCustomDebugInfoWriterHelper helper, SerializerMethodContext methodContext, MetaData systemMetaData, PdbCustomDebugInfo cdi, BinaryWriterContext context) { + var writer = new PortablePdbCustomDebugInfoWriter(helper, methodContext, systemMetaData, context); + return writer.Write(cdi); + } + + PortablePdbCustomDebugInfoWriter(IPortablePdbCustomDebugInfoWriterHelper helper, SerializerMethodContext methodContext, MetaData systemMetaData, BinaryWriterContext context) { + this.helper = helper; + this.methodContext = methodContext; + this.systemMetaData = systemMetaData; + this.outStream = context.OutStream; + this.writer = context.Writer; + outStream.SetLength(0); + outStream.Position = 0; + } + + byte[] Write(PdbCustomDebugInfo cdi) { + switch (cdi.Kind) { + case PdbCustomDebugInfoKind.UsingGroups: + case PdbCustomDebugInfoKind.ForwardMethodInfo: + case PdbCustomDebugInfoKind.ForwardModuleInfo: + case PdbCustomDebugInfoKind.StateMachineTypeName: + case PdbCustomDebugInfoKind.DynamicLocals: + case PdbCustomDebugInfoKind.TupleElementNames: + case PdbCustomDebugInfoKind.IteratorMethod: + default: + helper.Error("Unreachable code, caller should filter these out"); + return null; + + case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: + WriteStateMachineHoistedLocalScopes((PdbStateMachineHoistedLocalScopesCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: + WriteEditAndContinueLocalSlotMap((PdbEditAndContinueLocalSlotMapCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: + WriteEditAndContinueLambdaMap((PdbEditAndContinueLambdaMapCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.Unknown: + WriteUnknown((PdbUnknownCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.TupleElementNames_PortablePdb: + WriteTupleElementNames((PortablePdbTupleElementNamesCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.DefaultNamespace: + WriteDefaultNamespace((PdbDefaultNamespaceCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.DynamicLocalVariables: + WriteDynamicLocalVariables((PdbDynamicLocalVariablesCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.EmbeddedSource: + WriteEmbeddedSource((PdbEmbeddedSourceCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.SourceLink: + WriteSourceLink((PdbSourceLinkCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.AsyncMethod: + WriteAsyncMethodSteppingInformation((PdbAsyncMethodCustomDebugInfo)cdi); + break; + } + return outStream.ToArray(); + } + + void WriteUTF8Z(string s) { + var bytes = Encoding.UTF8.GetBytes(s); + writer.Write(bytes); + writer.Write((byte)0); + } + + void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi) { + if (!methodContext.HasBody) { + helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind); + return; + } + foreach (var scope in cdi.Scopes) { + uint startOffset, endOffset; + if (scope.IsSynthesizedLocal) { + startOffset = 0; + endOffset = 0; + } + else { + var startInstr = scope.Start; + if (startInstr == null) { + helper.Error("Instruction is null"); + return; + } + startOffset = methodContext.GetOffset(startInstr); + endOffset = methodContext.GetOffset(scope.End); + } + if (startOffset > endOffset) { + helper.Error("End instruction is before start instruction"); + return; + } + writer.Write(startOffset); + writer.Write(endOffset - startOffset); + } + } + + void WriteEditAndContinueLocalSlotMap(PdbEditAndContinueLocalSlotMapCustomDebugInfo cdi) { + var d = cdi.Data; + if (d == null) { + helper.Error("Data blob is null"); + return; + } + writer.Write(d); + } + + void WriteEditAndContinueLambdaMap(PdbEditAndContinueLambdaMapCustomDebugInfo cdi) { + var d = cdi.Data; + if (d == null) { + helper.Error("Data blob is null"); + return; + } + writer.Write(d); + } + + void WriteUnknown(PdbUnknownCustomDebugInfo cdi) { + var d = cdi.Data; + if (d == null) { + helper.Error("Data blob is null"); + return; + } + writer.Write(d); + } + + void WriteTupleElementNames(PortablePdbTupleElementNamesCustomDebugInfo cdi) { + foreach (var name in cdi.Names) { + if (name == null) { + helper.Error("Tuple name is null"); + return; + } + WriteUTF8Z(name); + } + } + + void WriteDefaultNamespace(PdbDefaultNamespaceCustomDebugInfo cdi) { + var ns = cdi.Namespace; + if (ns == null) { + helper.Error("Default namespace is null"); + return; + } + var bytes = Encoding.UTF8.GetBytes(ns); + writer.Write(bytes); + } + + void WriteDynamicLocalVariables(PdbDynamicLocalVariablesCustomDebugInfo cdi) { + var flags = cdi.Flags; + for (int i = 0; i < flags.Length; i += 8) + writer.Write(ToByte(flags, i)); + } + + static byte ToByte(bool[] flags, int index) { + int res = 0; + int bit = 1; + for (int i = index; i < flags.Length; i++, bit <<= 1) { + if (flags[i]) + res |= bit; + } + return (byte)res; + } + + void WriteEmbeddedSource(PdbEmbeddedSourceCustomDebugInfo cdi) { + var d = cdi.SourceCodeBlob; + if (d == null) { + helper.Error("Source code blob is null"); + return; + } + writer.Write(d); + } + + void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { + var d = cdi.SourceLinkBlob; + if (d == null) { + helper.Error("Source link blob is null"); + return; + } + writer.Write(d); + } + + void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { + if (!methodContext.HasBody) { + helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind); + return; + } + + uint catchHandlerOffset; + if (cdi.CatchHandlerInstruction == null) + catchHandlerOffset = 0; + else + catchHandlerOffset = methodContext.GetOffset(cdi.CatchHandlerInstruction) + 1; + writer.Write(catchHandlerOffset); + + foreach (var info in cdi.StepInfos) { + if (info.YieldInstruction == null) { + helper.Error("YieldInstruction is null"); + return; + } + if (info.BreakpointMethod == null) { + helper.Error("BreakpointMethod is null"); + return; + } + if (info.BreakpointInstruction == null) { + helper.Error("BreakpointInstruction is null"); + return; + } + uint yieldOffset = methodContext.GetOffset(info.YieldInstruction); + uint resumeOffset; + if (methodContext.IsSameMethod(info.BreakpointMethod)) + resumeOffset = methodContext.GetOffset(info.BreakpointInstruction); + else + resumeOffset = GetOffsetSlow(info.BreakpointMethod, info.BreakpointInstruction); + uint resumeMethodRid = systemMetaData.GetRid(info.BreakpointMethod); + writer.Write(yieldOffset); + writer.Write(resumeOffset); + writer.WriteCompressedUInt32(resumeMethodRid); + } + } + + uint GetOffsetSlow(MethodDef method, Instruction instr) { + var body = method.Body; + if (body == null) { + helper.Error("Method has no body"); + return uint.MaxValue; + } + var instrs = body.Instructions; + uint offset = 0; + for (int i = 0; i < instrs.Count; i++) { + var instr2 = instrs[i]; + if (instr2 == instr) + return offset; + offset += (uint)instr2.GetSize(); + } + helper.Error("Couldn't find an instruction, maybe it was removed. It's still being referenced by some code or by the PDB"); + return uint.MaxValue; + } + } +} diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 47034daf1..f5ff1068c 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -12,13 +12,13 @@ namespace dnlib.DotNet.Pdb.Portable { sealed class PortablePdbReader : SymbolReader { + readonly PdbFileKind pdbFileKind; ModuleDef module; - readonly IMetaData moduleMetaData; readonly IMetaData pdbMetaData; SymbolDocument[] documents; public override PdbFileKind PdbFileKind { - get { return PdbFileKind.PortablePDB; } + get { return pdbFileKind; } } public override int UserEntryPoint { @@ -29,8 +29,8 @@ public override IList Documents { get { return documents; } } - public PortablePdbReader(IMetaData moduleMetaData, IImageStream pdbStream) { - this.moduleMetaData = moduleMetaData; + public PortablePdbReader(IImageStream pdbStream, PdbFileKind pdbFileKind) { + this.pdbFileKind = pdbFileKind; pdbMetaData = MetaDataCreator.CreateStandalonePortablePDB(pdbStream, true); } @@ -106,10 +106,14 @@ int GetKickoffMethod(uint methodRid) { uint rid = pdbMetaData.GetStateMachineMethodRid(methodRid); if (rid == 0) return 0; + if (!pdbMetaData.TablesStream.StateMachineMethodTable.IsValidRID(rid)) + return 0; return 0x06000000 + (int)pdbMetaData.TablesStream.ReadStateMachineMethodRow2(rid); } SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { + if (!pdbMetaData.TablesStream.MethodDebugInformationTable.IsValidRID(methodRid)) + return null; uint documentRid; uint sequencePointsOffset = pdbMetaData.TablesStream.ReadMethodDebugInformationRow2(methodRid, out documentRid); if (sequencePointsOffset == 0) @@ -162,12 +166,10 @@ SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { if (dlines == 0 && dcolumns == 0) { // hidden-sequence-point-record - const int HIDDEN_LINE = 0xFEEFEE; - const int HIDDEN_COLUMN = 0; - symSeqPoint.Line = HIDDEN_LINE; - symSeqPoint.EndLine = HIDDEN_LINE; - symSeqPoint.Column = HIDDEN_COLUMN; - symSeqPoint.EndColumn = HIDDEN_COLUMN; + symSeqPoint.Line = SequencePointConstants.HIDDEN_LINE; + symSeqPoint.EndLine = SequencePointConstants.HIDDEN_LINE; + symSeqPoint.Column = SequencePointConstants.HIDDEN_COLUMN; + symSeqPoint.EndColumn = SequencePointConstants.HIDDEN_COLUMN; } else { // sequence-point-record @@ -273,6 +275,8 @@ PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReade if (i >= MAX) return null; int token = new MDToken(Table.ImportScope, importScope).ToInt32(); + if (!pdbMetaData.TablesStream.ImportScopeTable.IsValidRID(importScope)) + return null; uint imports = pdbMetaData.TablesStream.ReadImportScopeRow2(importScope, out importScope); var scope = new PdbImportScope(); GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos); diff --git a/src/DotNet/Pdb/Portable/SequencePointConstants.cs b/src/DotNet/Pdb/Portable/SequencePointConstants.cs new file mode 100644 index 000000000..159e559dd --- /dev/null +++ b/src/DotNet/Pdb/Portable/SequencePointConstants.cs @@ -0,0 +1,8 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb.Portable { + static class SequencePointConstants { + public const int HIDDEN_LINE = 0xFEEFEE; + public const int HIDDEN_COLUMN = 0; + } +} diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index 11483ecfd..7baba660e 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -1,19 +1,21 @@ // dnlib: See LICENSE.txt for more info using System.IO; +using System.IO.Compression; using dnlib.DotNet.MD; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; +using dnlib.PE; namespace dnlib.DotNet.Pdb.Portable { static class SymbolReaderCreator { - public static SymbolReader TryCreate(IMetaData metaData, IImageStream pdbStream) { + public static SymbolReader TryCreate(IImageStream pdbStream, bool isEmbeddedPortablePdb) { try { - if (metaData != null && pdbStream != null) { + if (pdbStream != null) { pdbStream.Position = 0; if (pdbStream.ReadUInt32() == 0x424A5342) { pdbStream.Position = 0; - return new PortablePdbReader(metaData, pdbStream); + return new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB); } } } @@ -28,11 +30,44 @@ public static SymbolReader TryCreate(IMetaData metaData) { if (metaData == null) return null; try { - //TODO: + var peImage = metaData.PEImage; + var embeddedDir = TryGetEmbeddedDebugDirectory(peImage); + if (embeddedDir == null) + return null; + using (var reader = peImage.CreateStream(embeddedDir.PointerToRawData, embeddedDir.SizeOfData)) { + // "MPDB" = 0x4244504D + if (reader.ReadUInt32() != 0x4244504D) + return null; + uint uncompressedSize = reader.ReadUInt32(); + if (uncompressedSize > int.MaxValue) + return null; + var decompressedBytes = new byte[uncompressedSize]; + using (var deflateStream = new DeflateStream(new MemoryStream(reader.ReadRemainingBytes()), CompressionMode.Decompress)) { + int pos = 0; + while (pos < decompressedBytes.Length) { + int read = deflateStream.Read(decompressedBytes, pos, decompressedBytes.Length - pos); + if (read == 0) + break; + pos += read; + } + if (pos != decompressedBytes.Length) + return null; + var stream = MemoryImageStream.Create(decompressedBytes); + return TryCreate(stream, true); + } + } } catch (IOException) { } return null; } + + static ImageDebugDirectory TryGetEmbeddedDebugDirectory(IPEImage peImage) { + foreach (var idd in peImage.ImageDebugDirectories) { + if (idd.Type == ImageDebugType.EmbeddedPortablePdb) + return idd; + } + return null; + } } } diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderCreator.cs index bb1b15d75..c3bf15197 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderCreator.cs @@ -93,7 +93,7 @@ public static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData, IImag } } - internal static SymbolReader Create(PdbImplType pdbImpl, MetaData metaData) { + internal static SymbolReader Create(PdbImplType pdbImpl, IMetaData metaData) { switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return null; diff --git a/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs similarity index 96% rename from src/DotNet/Pdb/WindowsPdb/PdbWriter.cs rename to src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 26b96ff1d..2d9b9cd7a 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Emit; -using dnlib.DotNet.Pdb.WindowsPdb; using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.WindowsPdb { @@ -13,7 +12,7 @@ namespace dnlib.DotNet.Pdb.WindowsPdb { /// PDB writer /// /// This class is not thread safe because it's a writer class - public sealed class PdbWriter : IDisposable { + public sealed class WindowsPdbWriter : IDisposable { ISymbolWriter2 writer; ISymbolWriter3 writer3; readonly PdbState pdbState; @@ -36,7 +35,7 @@ public sealed class PdbWriter : IDisposable { /// Symbol writer, it should implement /// PDB state /// Meta data - public PdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) + public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) : this(pdbState, metaData) { if (writer == null) throw new ArgumentNullException("writer"); @@ -56,7 +55,7 @@ public PdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) /// Symbol writer /// PDB state /// Meta data - public PdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) + public WindowsPdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) : this(pdbState, metaData) { if (writer == null) throw new ArgumentNullException("writer"); @@ -69,7 +68,7 @@ public PdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) writer.Initialize(metaData); } - PdbWriter(PdbState pdbState, MetaData metaData) { + WindowsPdbWriter(PdbState pdbState, MetaData metaData) { this.pdbState = pdbState; this.metaData = metaData; this.module = metaData.Module; @@ -145,7 +144,7 @@ sealed class SequencePointHelper { int[] endLines; int[] endColumns; - public void Write(PdbWriter pdbWriter, IList instrs) { + public void Write(WindowsPdbWriter pdbWriter, IList instrs) { checkedPdbDocs.Clear(); while (true) { PdbDocument currPdbDoc = null; @@ -196,12 +195,12 @@ public void Write(PdbWriter pdbWriter, IList instrs) { } struct CurrentMethod { - readonly PdbWriter pdbWriter; + readonly WindowsPdbWriter pdbWriter; public readonly MethodDef Method; readonly Dictionary toOffset; public readonly uint BodySize; - public CurrentMethod(PdbWriter pdbWriter, MethodDef method, Dictionary toOffset) { + public CurrentMethod(WindowsPdbWriter pdbWriter, MethodDef method, Dictionary toOffset) { this.pdbWriter = pdbWriter; Method = method; this.toOffset = toOffset; diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index 750f4327d..c087e0763 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -1,58 +1,47 @@ // dnlib: See LICENSE.txt for more info -using System; -using System.IO; +using System.Collections.Generic; +using System.IO; using dnlib.DotNet.Pdb; using dnlib.IO; using dnlib.PE; namespace dnlib.DotNet.Writer { /// - /// Debug directory chunk + /// Debug directory entry /// - public sealed class DebugDirectory : IChunk { - FileOffset offset; - RVA rva; - bool dontWriteAnything; - uint length; - internal IMAGE_DEBUG_DIRECTORY debugDirData; - uint timeDateStamp; - byte[] data; - + public sealed class DebugDirectoryEntry { /// - /// Size of + /// Gets the header /// - public const int HEADER_SIZE = 28; + public IMAGE_DEBUG_DIRECTORY DebugDirectory; /// - /// Gets/sets the time date stamp that should be written. This should be the same time date - /// stamp that is written to the PE header. + /// Gets the data /// - public uint TimeDateStamp { - get { return timeDateStamp; } - set { timeDateStamp = value; } - } + public readonly IChunk Chunk; /// - /// Gets/sets the raw debug data + /// Constructor /// - public byte[] Data { - get { return data; } - set { data = value; } + /// Data + public DebugDirectoryEntry(IChunk chunk) { + Chunk = chunk; } + } - /// - /// Set it to true if eg. the PDB file couldn't be created. If true, the size - /// of this chunk will be 0. - /// - public bool DontWriteAnything { - get { return dontWriteAnything; } - set { - if (length != 0) - throw new InvalidOperationException("SetOffset() has already been called"); - dontWriteAnything = value; - } - } + /// + /// Debug directory chunk + /// + public sealed class DebugDirectory : IChunk { + /// Default debug directory alignment + public const uint DEFAULT_DEBUGDIRECTORY_ALIGNMENT = 4; + const int HEADER_SIZE = 28; + + FileOffset offset; + RVA rva; + uint length; + readonly List entries; /// public FileOffset FileOffset { @@ -64,20 +53,39 @@ public RVA RVA { get { return rva; } } + /// + /// Constructor + /// + public DebugDirectory() { + entries = new List(); + } + + /// + /// Adds data + /// + /// Data + /// + public DebugDirectoryEntry Add(IChunk chunk) { + var entry = new DebugDirectoryEntry(chunk); + entries.Add(entry); + return entry; + } + /// public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; - length = HEADER_SIZE; - if (data != null) // Could be null if dontWriteAnything is true - length += (uint)data.Length; + length = HEADER_SIZE * (uint)entries.Count; + foreach (var entry in entries) { + length = Utils.AlignUp(length, DEFAULT_DEBUGDIRECTORY_ALIGNMENT); + entry.Chunk.SetOffset(offset + length, rva + length); + length += entry.Chunk.GetFileLength(); + } } /// public uint GetFileLength() { - if (dontWriteAnything) - return 0; return length; } @@ -88,18 +96,31 @@ public uint GetVirtualSize() { /// public void WriteTo(BinaryWriter writer) { - if (dontWriteAnything) - return; - - writer.Write(debugDirData.Characteristics); - writer.Write(timeDateStamp); - writer.Write(debugDirData.MajorVersion); - writer.Write(debugDirData.MinorVersion); - writer.Write(debugDirData.Type); - writer.Write(debugDirData.SizeOfData); - writer.Write((uint)rva + HEADER_SIZE); - writer.Write((uint)offset + HEADER_SIZE); - writer.Write(data); + uint offset = 0; + foreach (var entry in entries) { + var debugDirData = entry.DebugDirectory; + writer.Write(debugDirData.Characteristics); + writer.Write(debugDirData.TimeDateStamp); + writer.Write(debugDirData.MajorVersion); + writer.Write(debugDirData.MinorVersion); + writer.Write((uint)debugDirData.Type); + writer.Write(entry.Chunk.GetVirtualSize()); + writer.Write((uint)entry.Chunk.RVA); + writer.Write((uint)entry.Chunk.FileOffset); + offset += HEADER_SIZE; + } + + foreach (var entry in entries) { + WriteAlign(writer, ref offset); + entry.Chunk.VerifyWriteTo(writer); + offset += entry.Chunk.GetFileLength(); + } + } + + static void WriteAlign(BinaryWriter writer, ref uint offs) { + uint align = Utils.AlignUp(offs, DEFAULT_DEBUGDIRECTORY_ALIGNMENT) - offs; + offs += align; + writer.WriteZeros((int)align); } } } diff --git a/src/DotNet/Writer/GuidHeap.cs b/src/DotNet/Writer/GuidHeap.cs index 42c4e2336..3c27e846c 100644 --- a/src/DotNet/Writer/GuidHeap.cs +++ b/src/DotNet/Writer/GuidHeap.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.Writer { /// #GUID heap /// public sealed class GuidHeap : HeapBase, IOffsetHeap { - readonly List guids = new List(); + readonly Dictionary guids = new Dictionary(); Dictionary userRawData; /// @@ -28,15 +28,13 @@ public uint Add(Guid? guid) { if (guid == null) return 0; - // The number of GUIDs will almost always be 1 so there's no need for a dictionary. - // The only table that contains GUIDs is the Module table, and it has three GUID - // columns. Only one of them (Mvid) is normally set and the others are null. - int index = guids.IndexOf(guid.Value); - if (index >= 0) - return (uint)index + 1; + uint index; + if (guids.TryGetValue(guid.Value, out index)) + return index; - guids.Add(guid.Value); - return (uint)guids.Count; + index = (uint)guids.Count + 1; + guids.Add(guid.Value, index); + return index; } /// @@ -47,10 +45,10 @@ public override uint GetRawLength() { /// protected override void WriteToImpl(BinaryWriter writer) { uint offset = 0; - foreach (var guid in guids) { + foreach (var kv in guids) { byte[] rawData; if (userRawData == null || !userRawData.TryGetValue(offset, out rawData)) - rawData = guid.ToByteArray(); + rawData = kv.Key.ToByteArray(); writer.Write(rawData); offset += 16; } @@ -73,8 +71,8 @@ public void SetRawData(uint offset, byte[] rawData) { /// public IEnumerable> GetAllRawData() { uint offset = 0; - foreach (var guid in guids) { - yield return new KeyValuePair(offset, guid.ToByteArray()); + foreach (var kv in guids) { + yield return new KeyValuePair(offset, kv.Key.ToByteArray()); offset += 16; } } diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index ed1161361..a9f88a1fe 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -77,20 +77,5 @@ internal static void WriteDataDirectory(this BinaryWriter writer, IChunk chunk) writer.Write(chunk.GetVirtualSize()); } } - - /// - /// Writes a data directory - /// - /// Writer - /// The data - /// Fixed size of - internal static void WriteDataDirectory(this BinaryWriter writer, IChunk chunk, uint size) { - if (chunk == null || chunk.GetVirtualSize() == 0 || size == 0) - writer.Write(0UL); - else { - writer.Write((uint)chunk.RVA); - writer.Write(size); - } - } } } diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 8753042c8..21255485f 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -8,6 +8,9 @@ using dnlib.PE; using dnlib.DotNet.MD; using dnlib.DotNet.Emit; +using System.Diagnostics; +using dnlib.DotNet.Pdb; +using dnlib.DotNet.Pdb.Portable; namespace dnlib.DotNet.Writer { /// @@ -159,6 +162,7 @@ public enum MetaDataFlags : uint { /// public sealed class MetaDataOptions { MetaDataHeaderOptions metaDataHeaderOptions; + MetaDataHeaderOptions debugMetaDataHeaderOptions; TablesHeapOptions tablesHeapOptions; List otherHeaps; List otherHeapsEnd; @@ -171,6 +175,14 @@ public MetaDataHeaderOptions MetaDataHeaderOptions { set { metaDataHeaderOptions = value; } } + /// + /// Gets/sets the debug (portable PDB) options. This is never null. + /// + public MetaDataHeaderOptions DebugMetaDataHeaderOptions { + get { return debugMetaDataHeaderOptions ?? (debugMetaDataHeaderOptions = MetaDataHeaderOptions.CreatePortablePdbV1_0()); } + set { debugMetaDataHeaderOptions = value; } + } + /// /// Gets/sets the options. This is never null. /// @@ -179,6 +191,14 @@ public TablesHeapOptions TablesHeapOptions { set { tablesHeapOptions = value; } } + /// + /// Gets/sets the debug (portable PDB) options. This is never null. + /// + public TablesHeapOptions DebugTablesHeapOptions { + get { return tablesHeapOptions ?? (tablesHeapOptions = TablesHeapOptions.CreatePortablePdbV1_0()); } + set { tablesHeapOptions = value; } + } + /// /// Various options /// @@ -240,22 +260,40 @@ public BinaryWriterContext() { } } + /// + /// Portable PDB metadata kind + /// + public enum DebugMetaDataKind { + /// + /// No debugging metadata + /// + None, + + /// + /// Standalone / embedded portable PDB metadata + /// + Standalone, + } + /// /// .NET meta data /// - public abstract class MetaData : IChunk, ISignatureWriterHelper, ITokenCreator, ICustomAttributeWriterHelper { + public abstract class MetaData : IChunk, ISignatureWriterHelper, ITokenCreator, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper { uint length; FileOffset offset; RVA rva; readonly MetaDataOptions options; IMetaDataListener listener; ILogger logger; + readonly NormalMetaData debugMetaData; + readonly bool isStandaloneDebugMetadata; internal readonly ModuleDef module; internal readonly UniqueChunkList constants; internal readonly MethodBodyChunks methodBodies; internal readonly NetResources netResources; internal readonly MetaDataHeader metaDataHeader; internal HotHeap hotHeap; + internal readonly PdbHeap pdbHeap; internal readonly TablesHeap tablesHeap; internal readonly StringsHeap stringsHeap; internal readonly USHeap usHeap; @@ -289,7 +327,16 @@ public abstract class MetaData : IChunk, ISignatureWriterHelper, ITokenCreator, internal readonly Dictionary methodToNativeBody = new Dictionary(); internal readonly Dictionary embeddedResourceToByteArray = new Dictionary(); readonly Dictionary fieldToInitialValue = new Dictionary(); - readonly BinaryWriterContext binaryWriterContext = new BinaryWriterContext(); + readonly Rows pdbDocumentInfos = new Rows(); + bool methodDebugInformationInfosUsed; + readonly SortedRows localScopeInfos = new SortedRows(); + readonly Rows localVariableInfos = new Rows(); + readonly Rows localConstantInfos = new Rows(); + readonly Rows importScopeInfos = new Rows(); + readonly SortedRows stateMachineMethodInfos = new SortedRows(); + readonly SortedRows customDebugInfos = new SortedRows(); + readonly List binaryWriterContexts = new List(); + readonly List serializerMethodContexts = new List(); /// /// Gets/sets the listener @@ -390,6 +437,13 @@ public BlobHeap BlobHeap { get { return blobHeap; } } + /// + /// Gets the #Pdb heap. It's only used if it's portable PDB metadata + /// + public PdbHeap PdbHeap { + get { return pdbHeap; } + } + /// /// The public key that should be used instead of the one in . /// @@ -469,18 +523,6 @@ public void SetRid(T value, uint rid) { } } - /// - /// Creates a instance - /// - /// Module - /// Constants list - /// Method bodies list - /// .NET resources list - /// A new instance - public static MetaData Create(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources) { - return Create(module, constants, methodBodies, netResources, null); - } - /// /// Creates a instance /// @@ -489,13 +531,14 @@ public static MetaData Create(ModuleDef module, UniqueChunkList /// Method bodies list /// .NET resources list /// Options + /// Debug metadata kind /// A new instance - public static MetaData Create(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options) { + public static MetaData Create(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options = null, DebugMetaDataKind debugKind = DebugMetaDataKind.None) { if (options == null) options = new MetaDataOptions(); if ((options.Flags & MetaDataFlags.PreserveRids) != 0 && module is ModuleDefMD) - return new PreserveTokensMetaData(module, constants, methodBodies, netResources, options); - return new NormalMetaData(module, constants, methodBodies, netResources, options); + return new PreserveTokensMetaData(module, constants, methodBodies, netResources, options, debugKind, false); + return new NormalMetaData(module, constants, methodBodies, netResources, options, debugKind, false); } /// @@ -713,26 +756,34 @@ public bool AlwaysCreateBlobHeap { /// protected abstract int NumberOfMethods { get; } - /// - /// Constructor - /// - /// Module - /// Constants list - /// Method bodies list - /// .NET resources list - /// Options - internal MetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options) { + internal MetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options, DebugMetaDataKind debugKind, bool isStandaloneDebugMetadata) { this.module = module; this.constants = constants; this.methodBodies = methodBodies; this.netResources = netResources; this.options = options ?? new MetaDataOptions(); - this.metaDataHeader = new MetaDataHeader(this.options.MetaDataHeaderOptions); - this.tablesHeap = new TablesHeap(this.options.TablesHeapOptions); + this.metaDataHeader = new MetaDataHeader(isStandaloneDebugMetadata ? this.options.DebugMetaDataHeaderOptions : this.options.MetaDataHeaderOptions); + this.tablesHeap = new TablesHeap(isStandaloneDebugMetadata ? this.options.DebugTablesHeapOptions : this.options.TablesHeapOptions); this.stringsHeap = new StringsHeap(); this.usHeap = new USHeap(); this.guidHeap = new GuidHeap(); this.blobHeap = new BlobHeap(); + this.pdbHeap = new PdbHeap(); + + this.isStandaloneDebugMetadata = isStandaloneDebugMetadata; + switch (debugKind) { + case DebugMetaDataKind.None: + break; + + case DebugMetaDataKind.Standalone: + Debug.Assert(!isStandaloneDebugMetadata); + //TODO: Refactor this into a smaller class + debugMetaData = new NormalMetaData(module, constants, methodBodies, netResources, options, DebugMetaDataKind.None, true); + break; + + default: + throw new ArgumentOutOfRangeException("debugKind"); + } } /// @@ -1054,6 +1105,110 @@ public uint GetRid(GenericParamConstraint gpc) { return rid; } + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetRid(PdbDocument doc) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.pdbDocumentInfos.TryGetRid(doc, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetRid(PdbScope scope) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.localScopeInfos.TryGetRid(scope, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetRid(PdbLocal local) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.localVariableInfos.TryGetRid(local, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetRid(PdbConstant constant) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.localConstantInfos.TryGetRid(constant, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetRid(PdbImportScope importScope) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.importScopeInfos.TryGetRid(importScope, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetStateMachineMethodRid(PdbAsyncMethodCustomDebugInfo asyncMethod) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.stateMachineMethodInfos.TryGetRid(asyncMethod, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetStateMachineMethodRid(PdbIteratorMethodCustomDebugInfo iteratorMethod) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.stateMachineMethodInfos.TryGetRid(iteratorMethod, out rid); + return rid; + } + + /// + /// Gets the new rid + /// + /// Value + /// Its new rid or 0 + public uint GetCustomDebugInfoRid(PdbCustomDebugInfo cdi) { + if (debugMetaData == null) + return 0; + uint rid; + debugMetaData.customDebugInfos.TryGetRid(cdi, out rid); + return rid; + } + /// /// Gets the /// @@ -1181,6 +1336,7 @@ void UpdateFieldRvas() { } void Create() { + Debug.Assert(!isStandaloneDebugMetadata); Initialize(); allTypeDefs = GetAllTypeDefs(); Listener.OnMetaDataEvent(this, MetaDataEvent.AllocateTypeDefRids); @@ -1190,6 +1346,8 @@ void Create() { Listener.OnMetaDataEvent(this, MetaDataEvent.MemberDefRidsAllocated); AddModule(module); + AddPdbDocuments(); + InitializeMethodDebugInformation(); InitializeTypeDefsAndMemberDefs(); Listener.OnMetaDataEvent(this, MetaDataEvent.MemberDefsInitialized); @@ -1205,7 +1363,7 @@ void Create() { InitializeGenericParamConstraintTable(); Listener.OnMetaDataEvent(this, MetaDataEvent.MostTablesSorted); - WriteTypeDefAndMemberDefCustomAttributes(); + WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos(); Listener.OnMetaDataEvent(this, MetaDataEvent.MemberDefCustomAttributesWritten); Listener.OnMetaDataEvent(this, MetaDataEvent.BeginAddResources); @@ -1217,7 +1375,7 @@ void Create() { Listener.OnMetaDataEvent(this, MetaDataEvent.EndWriteMethodBodies); BeforeSortingCustomAttributes(); - InitializeCustomAttributeTable(); + InitializeCustomAttributeAndCustomDebugInfoTables(); Listener.OnMetaDataEvent(this, MetaDataEvent.OnAllTablesSorted); EverythingInitialized(); @@ -1343,15 +1501,16 @@ void InitializeTypeDefsAndMemberDefs() { /// /// Writes TypeDef, Field, Method, Event, - /// Property and Param custom attributes. + /// Property and Param custom attributes and custom debug infos. /// - void WriteTypeDefAndMemberDefCustomAttributes() { + void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { int numTypes = allTypeDefs.Count; int typeNum = 0; int notifyNum = 0; const int numNotifyEvents = 5; // WriteTypeDefAndMemberDefCustomAttributes0 - WriteTypeDefAndMemberDefCustomAttributes4 int notifyAfter = numTypes / numNotifyEvents; + uint rid; foreach (var type in allTypeDefs) { if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { Listener.OnMetaDataEvent(this, MetaDataEvent.WriteTypeDefAndMemberDefCustomAttributes0 + notifyNum++); @@ -1360,33 +1519,44 @@ void WriteTypeDefAndMemberDefCustomAttributes() { if (type == null) continue; - AddCustomAttributes(Table.TypeDef, GetRid(type), type); + rid = GetRid(type); + AddCustomAttributes(Table.TypeDef, rid, type); + AddCustomDebugInformationList(Table.TypeDef, rid, type); foreach (var field in type.Fields) { if (field == null) continue; - AddCustomAttributes(Table.Field, GetRid(field), field); + rid = GetRid(field); + AddCustomAttributes(Table.Field, rid, field); + AddCustomDebugInformationList(Table.Field, rid, field); } foreach (var method in type.Methods) { if (method == null) continue; AddCustomAttributes(Table.Method, GetRid(method), method); + // Method custom debug info is added later when writing method bodies foreach (var pd in method.ParamDefs) { if (pd == null) continue; - AddCustomAttributes(Table.Param, GetRid(pd), pd); + rid = GetRid(pd); + AddCustomAttributes(Table.Param, rid, pd); + AddCustomDebugInformationList(Table.Param, rid, pd); } } foreach (var evt in type.Events) { if (evt == null) continue; - AddCustomAttributes(Table.Event, GetRid(evt), evt); + rid = GetRid(evt); + AddCustomAttributes(Table.Event, rid, evt); + AddCustomDebugInformationList(Table.Event, rid, evt); } foreach (var prop in type.Properties) { if (prop == null) continue; - AddCustomAttributes(Table.Property, GetRid(prop), prop); + rid = GetRid(prop); + AddCustomAttributes(Table.Property, rid, prop); + AddCustomDebugInformationList(Table.Property, rid, prop); } } while (notifyNum < numNotifyEvents) @@ -1486,12 +1656,21 @@ void SortTables() { foreach (var info in methodSemanticsInfos.infos) tablesHeap.MethodSemanticsTable.Create(info.row); foreach (var info in nestedClassInfos.infos) tablesHeap.NestedClassTable.Create(info.row); - foreach (var info in interfaceImplInfos.infos) - AddCustomAttributes(Table.InterfaceImpl, interfaceImplInfos.Rid(info.data), info.data); - foreach (var info in declSecurityInfos.infos) - AddCustomAttributes(Table.DeclSecurity, declSecurityInfos.Rid(info.data), info.data); - foreach (var info in genericParamInfos.infos) - AddCustomAttributes(Table.GenericParam, genericParamInfos.Rid(info.data), info.data); + foreach (var info in interfaceImplInfos.infos) { + uint rid = interfaceImplInfos.Rid(info.data); + AddCustomAttributes(Table.InterfaceImpl, rid, info.data); + AddCustomDebugInformationList(Table.InterfaceImpl, rid, info.data); + } + foreach (var info in declSecurityInfos.infos) { + uint rid = declSecurityInfos.Rid(info.data); + AddCustomAttributes(Table.DeclSecurity, rid, info.data); + AddCustomDebugInformationList(Table.DeclSecurity, rid, info.data); + } + foreach (var info in genericParamInfos.infos) { + uint rid = genericParamInfos.Rid(info.data); + AddCustomAttributes(Table.GenericParam, rid, info.data); + AddCustomDebugInformationList(Table.GenericParam, rid, info.data); + } } /// @@ -1512,30 +1691,67 @@ void InitializeGenericParamConstraintTable() { tablesHeap.GenericParamConstraintTable.IsSorted = true; foreach (var info in genericParamConstraintInfos.infos) tablesHeap.GenericParamConstraintTable.Create(info.row); - foreach (var info in genericParamConstraintInfos.infos) - AddCustomAttributes(Table.GenericParamConstraint, genericParamConstraintInfos.Rid(info.data), info.data); + foreach (var info in genericParamConstraintInfos.infos) { + uint rid = genericParamConstraintInfos.Rid(info.data); + AddCustomAttributes(Table.GenericParamConstraint, rid, info.data); + AddCustomDebugInformationList(Table.GenericParamConstraint, rid, info.data); + } } /// - /// Inserts all custom attribute rows in the table and sorts it + /// Inserts all custom attribute / custom debug info rows in the tables and sort them /// - void InitializeCustomAttributeTable() { + void InitializeCustomAttributeAndCustomDebugInfoTables() { customAttributeInfos.Sort((a, b) => a.row.Parent.CompareTo(b.row.Parent)); tablesHeap.CustomAttributeTable.IsSorted = true; foreach (var info in customAttributeInfos.infos) tablesHeap.CustomAttributeTable.Create(info.row); + + if (debugMetaData != null) { + debugMetaData.stateMachineMethodInfos.Sort((a, b) => a.row.MoveNextMethod.CompareTo(b.row.MoveNextMethod)); + debugMetaData.tablesHeap.StateMachineMethodTable.IsSorted = true; + foreach (var info in debugMetaData.stateMachineMethodInfos.infos) + debugMetaData.tablesHeap.StateMachineMethodTable.Create(info.row); + + debugMetaData.customDebugInfos.Sort((a, b) => a.row.Parent.CompareTo(b.row.Parent)); + debugMetaData.tablesHeap.CustomDebugInformationTable.IsSorted = true; + foreach (var info in debugMetaData.customDebugInfos.infos) + debugMetaData.tablesHeap.CustomDebugInformationTable.Create(info.row); + } + } + + struct MethodScopeDebugInfo { + public uint MethodRid; + public PdbScope Scope; + public uint ScopeStart; + public uint ScopeLength; } /// /// Writes all method bodies /// void WriteMethodBodies() { + Debug.Assert(!isStandaloneDebugMetadata); int numMethods = NumberOfMethods; int methodNum = 0; int notifyNum = 0; const int numNotifyEvents = 10; // WriteMethodBodies0 - WriteMethodBodies9 int notifyAfter = numMethods / numNotifyEvents; + List methodScopeDebugInfos; + List scopeStack; + SerializerMethodContext serializerMethodContext; + if (debugMetaData == null) { + methodScopeDebugInfos = null; + scopeStack = null; + serializerMethodContext = null; + } + else { + methodScopeDebugInfos = new List(); + scopeStack = new List(); + serializerMethodContext = AllocSerializerMethodContext(); + } + bool keepMaxStack = KeepOldMaxStack; var writer = new MethodBodyWriter(this); foreach (var type in allTypeDefs) { @@ -1551,29 +1767,86 @@ void WriteMethodBodies() { notifyAfter += numMethods / numNotifyEvents; } - if (method.MethodBody == null) - continue; + uint localVarSigTok = 0; + uint rid = GetRid(method); var cilBody = method.Body; if (cilBody != null) { - if (cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0) - continue; - writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); - writer.Write(); - var mb = methodBodies.Add(new MethodBody(writer.Code, writer.ExtraSections, writer.LocalVarSigTok)); - methodToBody[method] = mb; - continue; + if (!(cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0)) { + writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); + writer.Write(); + var mb = methodBodies.Add(new MethodBody(writer.Code, writer.ExtraSections, writer.LocalVarSigTok)); + methodToBody[method] = mb; + localVarSigTok = writer.LocalVarSigTok; + } } - - var nativeBody = method.NativeBody; - if (nativeBody != null) { - methodToNativeBody[method] = nativeBody; - continue; + else { + var nativeBody = method.NativeBody; + if (nativeBody != null) + methodToNativeBody[method] = nativeBody; + else if (method.MethodBody != null) + Error("Unsupported method body"); } - Error("Unsupported method body"); + if (debugMetaData != null) { + if (cilBody != null) { + var pdbMethod = cilBody.PdbMethod; + if (pdbMethod != null) { + serializerMethodContext.SetBody(method); + scopeStack.Add(pdbMethod.Scope); + while (scopeStack.Count > 0) { + var scope = scopeStack[scopeStack.Count - 1]; + scopeStack.RemoveAt(scopeStack.Count - 1); + scopeStack.AddRange(scope.Scopes); + uint scopeStart = serializerMethodContext.GetOffset(scope.Start); + uint scopeEnd = serializerMethodContext.GetOffset(scope.End); + methodScopeDebugInfos.Add(new MethodScopeDebugInfo() { + MethodRid = rid, + Scope = scope, + ScopeStart = scopeStart, + ScopeLength = scopeEnd - scopeStart, + }); + } + } + } + } + // Always add CDIs even if it has no managed method body + AddCustomDebugInformationList(method, rid, localVarSigTok); } } + if (debugMetaData != null) { + methodScopeDebugInfos.Sort((a, b) => { + int c = a.MethodRid.CompareTo(b.MethodRid); + if (c != 0) + return c; + c = a.ScopeStart.CompareTo(b.ScopeStart); + if (c != 0) + return c; + return b.ScopeLength.CompareTo(a.ScopeLength); + }); + foreach (var info in methodScopeDebugInfos) { + var row = new RawLocalScopeRow(); + debugMetaData.localScopeInfos.Add(info.Scope, row); + uint localScopeRid = (uint)debugMetaData.localScopeInfos.infos.Count; + row.Method = info.MethodRid; + row.ImportScope = AddImportScope(info.Scope.ImportScope); + row.VariableList = (uint)debugMetaData.tablesHeap.LocalVariableTable.Rows + 1; + row.ConstantList = (uint)debugMetaData.tablesHeap.LocalConstantTable.Rows + 1; + row.StartOffset = info.ScopeStart; + row.Length = info.ScopeLength; + foreach (var local in info.Scope.Variables) + AddLocalVariable(local); + foreach (var constant in info.Scope.Constants) + AddLocalConstant(constant); + AddCustomDebugInformationList(Table.LocalScope, localScopeRid, info.Scope.CustomDebugInfos); + } + + debugMetaData.tablesHeap.LocalScopeTable.IsSorted = true; + foreach (var info in debugMetaData.localScopeInfos.infos) + debugMetaData.tablesHeap.LocalScopeTable.Create(info.row); + } + if (serializerMethodContext != null) + Free(ref serializerMethodContext); while (notifyNum < numNotifyEvents) Listener.OnMetaDataEvent(this, MetaDataEvent.WriteMethodBodies0 + notifyNum++); } @@ -1627,6 +1900,7 @@ public virtual MDToken GetToken(IList locals, uint origToken) { var row = new RawStandAloneSigRow(GetSignature(new LocalSig(locals, false))); uint rid = tablesHeap.StandAloneSigTable.Add(row); //TODO: Add custom attributes + //TODO: Add custom debug infos return new MDToken(Table.StandAloneSig, rid); } @@ -1645,6 +1919,7 @@ protected virtual uint AddStandAloneSig(MethodSig methodSig, uint origToken) { var row = new RawStandAloneSigRow(GetSignature(methodSig)); uint rid = tablesHeap.StandAloneSigTable.Add(row); //TODO: Add custom attributes + //TODO: Add custom debug infos return rid; } @@ -1663,6 +1938,7 @@ protected virtual uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { var row = new RawStandAloneSigRow(GetSignature(fieldSig)); uint rid = tablesHeap.StandAloneSigTable.Add(row); //TODO: Add custom attributes + //TODO: Add custom debug infos return rid; } @@ -1927,6 +2203,7 @@ protected uint AddModule(ModuleDef module) { rid = tablesHeap.ModuleTable.Add(row); moduleDefInfos.Add(module, rid); AddCustomAttributes(Table.Module, rid, module); + AddCustomDebugInformationList(Table.Module, rid, module); return rid; } @@ -1947,6 +2224,7 @@ protected uint AddModuleRef(ModuleRef modRef) { rid = tablesHeap.ModuleRefTable.Add(row); moduleRefInfos.Add(modRef, rid); AddCustomAttributes(Table.ModuleRef, rid, modRef); + AddCustomDebugInformationList(Table.ModuleRef, rid, modRef); return rid; } @@ -1976,6 +2254,7 @@ protected uint AddAssemblyRef(AssemblyRef asmRef) { rid = tablesHeap.AssemblyRefTable.Add(row); assemblyRefInfos.Add(asmRef, rid); AddCustomAttributes(Table.AssemblyRef, rid, asmRef); + AddCustomDebugInformationList(Table.AssemblyRef, rid, asmRef); return rid; } @@ -2014,6 +2293,7 @@ protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { assemblyInfos.Add(asm, rid); AddDeclSecurities(new MDToken(Table.Assembly, rid), asm.DeclSecurities); AddCustomAttributes(Table.Assembly, rid, asm); + AddCustomDebugInformationList(Table.Assembly, rid, asm); return rid; } @@ -2140,6 +2420,7 @@ protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { /// /// The field protected void AddFieldRVA(FieldDef field) { + Debug.Assert(!isStandaloneDebugMetadata); if (field.RVA != 0 && KeepFieldRVA) { uint rid = GetRid(field); var row = new RawFieldRVARow((uint)field.RVA, rid); @@ -2297,14 +2578,16 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit Error("Can't encode HasDeclSecurity token {0:X8}", parent.Raw); encodedParent = 0; } + var bwctx = AllocBinaryWriterContext(); foreach (var decl in declSecurities) { if (decl == null) continue; var row = new RawDeclSecurityRow((short)decl.Action, encodedParent, - blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this, binaryWriterContext))); + blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this, bwctx))); declSecurityInfos.Add(decl, row); } + Free(ref bwctx); } /// @@ -2428,6 +2711,7 @@ void AddResource(Resource resource) { } uint AddEmbeddedResource(EmbeddedResource er) { + Debug.Assert(!isStandaloneDebugMetadata); if (er == null) { Error("EmbeddedResource is null"); return 0; @@ -2443,6 +2727,7 @@ uint AddEmbeddedResource(EmbeddedResource er) { manifestResourceInfos.Add(er, rid); embeddedResourceToByteArray[er] = netResources.Add(er.Data); //TODO: Add custom attributes + //TODO: Add custom debug infos return rid; } @@ -2461,6 +2746,7 @@ uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { rid = tablesHeap.ManifestResourceTable.Add(row); manifestResourceInfos.Add(alr, rid); //TODO: Add custom attributes + //TODO: Add custom debug infos return rid; } @@ -2479,6 +2765,7 @@ uint AddLinkedResource(LinkedResource lr) { rid = tablesHeap.ManifestResourceTable.Add(row); manifestResourceInfos.Add(lr, rid); //TODO: Add custom attributes + //TODO: Add custom debug infos return rid; } @@ -2501,6 +2788,7 @@ protected uint AddFile(FileDef file) { rid = tablesHeap.FileTable.Add(row); fileDefInfos.Add(file, rid); AddCustomAttributes(Table.File, rid, file); + AddCustomDebugInformationList(Table.File, rid, file); return rid; } @@ -2526,6 +2814,7 @@ protected uint AddExportedType(ExportedType et) { rid = tablesHeap.ExportedTypeTable.Add(row); exportedTypeInfos.SetRid(et, rid); AddCustomAttributes(Table.ExportedType, rid, et); + AddCustomDebugInformationList(Table.ExportedType, rid, et); return rid; } @@ -2542,8 +2831,11 @@ protected uint GetSignature(TypeSig ts, byte[] extraData) { Error("TypeSig is null"); blob = null; } - else - blob = SignatureWriter.Write(this, ts, binaryWriterContext); + else { + var bwctx = AllocBinaryWriterContext(); + blob = SignatureWriter.Write(this, ts, bwctx); + Free(ref bwctx); + } AppendExtraData(ref blob, extraData); return blobHeap.Add(blob); } @@ -2559,7 +2851,9 @@ protected uint GetSignature(CallingConventionSig sig) { return 0; } - var blob = SignatureWriter.Write(this, sig, binaryWriterContext); + var bwctx = AllocBinaryWriterContext(); + var blob = SignatureWriter.Write(this, sig, bwctx); + Free(ref bwctx); AppendExtraData(ref blob, sig.ExtraData); return blobHeap.Add(blob); } @@ -2598,13 +2892,423 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { Error("Can't encode HasCustomAttribute token {0:X8}", token.Raw); encodedToken = 0; } - var caBlob = CustomAttributeWriter.Write(this, ca, binaryWriterContext); + var bwctx = AllocBinaryWriterContext(); + var caBlob = CustomAttributeWriter.Write(this, ca, bwctx); + Free(ref bwctx); var row = new RawCustomAttributeRow(encodedToken, AddCustomAttributeType(ca.Constructor), blobHeap.Add(caBlob)); customAttributeInfos.Add(ca, row); } + void AddCustomDebugInformationList(MethodDef method, uint rid, uint localVarSigToken) { + if (debugMetaData == null) + return; + var serializerMethodContext = AllocSerializerMethodContext(); + serializerMethodContext.SetBody(method); + if (method.CustomDebugInfos.Count != 0) + AddCustomDebugInformationCore(serializerMethodContext, Table.Method, rid, method.CustomDebugInfos); + AddMethodDebugInformation(method, rid, localVarSigToken); + Free(ref serializerMethodContext); + } + + void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken) { + Debug.Assert(debugMetaData != null); + var body = method.Body; + if (body == null) + return; + + bool hasNoSeqPoints; + PdbDocument singleDoc, firstDoc; + GetSingleDocument(body, out singleDoc, out firstDoc, out hasNoSeqPoints); + if (hasNoSeqPoints) + return; + + var bwctx = AllocBinaryWriterContext(); + var outStream = bwctx.OutStream; + var writer = bwctx.Writer; + outStream.SetLength(0); + outStream.Position = 0; + + writer.WriteCompressedUInt32(localVarSigToken); + if (singleDoc == null) + writer.WriteCompressedUInt32(VerifyGetRid(firstDoc)); + + var instrs = body.Instructions; + var currentDoc = firstDoc; + uint ilOffset = uint.MaxValue; + int line = -1, column = 0; + uint instrOffset = 0; + Instruction instr = null; + for (int i = 0; i < instrs.Count; i++, instrOffset += (uint)instr.GetSize()) { + instr = instrs[i]; + var seqPoint = instr.SequencePoint; + if (seqPoint == null) + continue; + if (seqPoint.Document == null) { + Error("PDB document is null"); + return; + } + if (currentDoc != seqPoint.Document) { + // document-record + + currentDoc = seqPoint.Document; + writer.WriteCompressedUInt32(0); + writer.WriteCompressedUInt32(VerifyGetRid(currentDoc)); + } + + // SequencePointRecord + + if (ilOffset == uint.MaxValue) + writer.WriteCompressedUInt32(instrOffset); + else + writer.WriteCompressedUInt32(instrOffset - ilOffset); + ilOffset = instrOffset; + + if (seqPoint.StartLine == SequencePointConstants.HIDDEN_LINE && seqPoint.EndLine == SequencePointConstants.HIDDEN_LINE) { + // hidden-sequence-point-record + + writer.WriteCompressedUInt32(0); + writer.WriteCompressedUInt32(0); + } + else { + // sequence-point-record + + uint dlines = (uint)(seqPoint.EndLine - seqPoint.StartLine); + int dcolumns = seqPoint.EndColumn - seqPoint.StartColumn; + writer.WriteCompressedUInt32(dlines); + if (dlines == 0) + writer.WriteCompressedUInt32((uint)dcolumns); + else + writer.WriteCompressedInt32(dcolumns); + + if (line < 0) { + writer.WriteCompressedUInt32((uint)seqPoint.StartLine); + writer.WriteCompressedUInt32((uint)seqPoint.StartColumn); + } + else { + writer.WriteCompressedInt32(seqPoint.StartLine - line); + writer.WriteCompressedInt32(seqPoint.StartColumn - column); + } + line = seqPoint.StartLine; + column = seqPoint.StartColumn; + } + } + + var seqPointsBlob = outStream.ToArray(); + var row = debugMetaData.tablesHeap.MethodDebugInformationTable[rid]; + row.Document = singleDoc == null ? 0 : AddPdbDocument(singleDoc); + row.SequencePoints = debugMetaData.blobHeap.Add(seqPointsBlob); + debugMetaData.methodDebugInformationInfosUsed = true; + Free(ref bwctx); + } + + uint VerifyGetRid(PdbDocument doc) { + Debug.Assert(debugMetaData != null); + uint rid; + if (!debugMetaData.pdbDocumentInfos.TryGetRid(doc, out rid)) { + Error("PDB document has been removed"); + return 0; + } + return rid; + } + + static void GetSingleDocument(CilBody body, out PdbDocument singleDoc, out PdbDocument firstDoc, out bool hasNoSeqPoints) { + var instrs = body.Instructions; + int docCount = 0; + singleDoc = null; + firstDoc = null; + for (int i = 0; i < instrs.Count; i++) { + var seqPt = instrs[i].SequencePoint; + if (seqPt == null) + continue; + var doc = seqPt.Document; + if (doc == null) + continue; + if (firstDoc == null) + firstDoc = doc; + if (singleDoc != doc) { + singleDoc = doc; + docCount++; + if (docCount > 1) + break; + } + } + hasNoSeqPoints = docCount == 0; + if (docCount != 1) + singleDoc = null; + } + + /// + /// Adds a CustomDebugInformation row + /// + /// Owner table + /// New owner rid + /// Onwer + protected void AddCustomDebugInformationList(Table table, uint rid, IHasCustomDebugInformation hcdi) { + Debug.Assert(table != Table.Method); + if (debugMetaData == null) + return; + if (hcdi.CustomDebugInfos.Count == 0) + return; + var serializerMethodContext = AllocSerializerMethodContext(); + serializerMethodContext.SetBody(null); + AddCustomDebugInformationCore(serializerMethodContext, table, rid, hcdi.CustomDebugInfos); + Free(ref serializerMethodContext); + } + + void AddCustomDebugInformationList(Table table, uint rid, IList cdis) { + Debug.Assert(table != Table.Method); + if (debugMetaData == null) + return; + if (cdis.Count == 0) + return; + var serializerMethodContext = AllocSerializerMethodContext(); + serializerMethodContext.SetBody(null); + AddCustomDebugInformationCore(serializerMethodContext, table, rid, cdis); + Free(ref serializerMethodContext); + } + + void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodContext, Table table, uint rid, IList cdis) { + Debug.Assert(debugMetaData != null); + Debug.Assert(cdis.Count != 0); + + var token = new MDToken(table, rid); + uint encodedToken; + if (!CodedToken.HasCustomDebugInformation.Encode(token, out encodedToken)) { + Error("Couldn't encode HasCustomDebugInformation token {0:X8}", token.Raw); + return; + } + + for (int i = 0; i < cdis.Count; i++) { + var cdi = cdis[i]; + if (cdi == null) { + Error("Custom debug info is null"); + continue; + } + + AddCustomDebugInformation(serializerMethodContext, token.Raw, encodedToken, cdi); + } + } + + void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, uint token, uint encodedToken, PdbCustomDebugInfo cdi) { + Debug.Assert(debugMetaData != null); + + switch (cdi.Kind) { + case PdbCustomDebugInfoKind.UsingGroups: + case PdbCustomDebugInfoKind.ForwardMethodInfo: + case PdbCustomDebugInfoKind.ForwardModuleInfo: + case PdbCustomDebugInfoKind.StateMachineTypeName: + case PdbCustomDebugInfoKind.DynamicLocals: + case PdbCustomDebugInfoKind.TupleElementNames: + // These are Windows PDB CDIs + Error("Unsupported custom debug info {0}", cdi.Kind); + break; + + case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: + case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: + case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: + case PdbCustomDebugInfoKind.Unknown: + case PdbCustomDebugInfoKind.TupleElementNames_PortablePdb: + case PdbCustomDebugInfoKind.DefaultNamespace: + case PdbCustomDebugInfoKind.DynamicLocalVariables: + case PdbCustomDebugInfoKind.EmbeddedSource: + case PdbCustomDebugInfoKind.SourceLink: + AddCustomDebugInformationCore(serializerMethodContext, encodedToken, cdi, cdi.Guid); + break; + + case PdbCustomDebugInfoKind.AsyncMethod: + // This is a portable PDB pseudo CDI + AddCustomDebugInformationCore(serializerMethodContext, encodedToken, cdi, CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob); + AddStateMachineMethod(cdi, token, ((PdbAsyncMethodCustomDebugInfo)cdi).KickoffMethod); + break; + + case PdbCustomDebugInfoKind.IteratorMethod: + // This is a portable PDB pseudo CDI + AddStateMachineMethod(cdi, token, ((PdbIteratorMethodCustomDebugInfo)cdi).KickoffMethod); + break; + + default: + Error("Unknown custom debug info {0}", cdi.Kind.ToString()); + break; + } + } + + void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, MethodDef kickoffMethod) { + Debug.Assert(new MDToken(moveNextMethodToken).Table == Table.Method); + Debug.Assert(debugMetaData != null); + var row = new RawStateMachineMethodRow(new MDToken(moveNextMethodToken).Rid, GetRid(kickoffMethod)); + debugMetaData.stateMachineMethodInfos.Add(cdi, row); + } + + void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodContext, uint encodedToken, PdbCustomDebugInfo cdi, Guid cdiGuid) { + Debug.Assert(debugMetaData != null); + + var bwctx = AllocBinaryWriterContext(); + var cdiBlob = PortablePdbCustomDebugInfoWriter.Write(this, serializerMethodContext, this, cdi, bwctx); + Debug.Assert(cdiGuid != Guid.Empty); + Free(ref bwctx); + var row = new RawCustomDebugInformationRow(encodedToken, + debugMetaData.guidHeap.Add(cdiGuid), + debugMetaData.blobHeap.Add(cdiBlob)); + debugMetaData.customDebugInfos.Add(cdi, row); + } + + void InitializeMethodDebugInformation() { + if (debugMetaData == null) + return; + int numMethods = NumberOfMethods; + for (int i = 0; i < numMethods; i++) + debugMetaData.tablesHeap.MethodDebugInformationTable.Create(new RawMethodDebugInformationRow()); + } + + void AddPdbDocuments() { + if (debugMetaData == null) + return; + foreach (var doc in module.PdbState.Documents) + AddPdbDocument(doc); + } + + uint AddPdbDocument(PdbDocument doc) { + Debug.Assert(debugMetaData != null); + if (doc == null) { + Error("PdbDocument is null"); + return 0; + } + uint rid; + if (debugMetaData.pdbDocumentInfos.TryGetRid(doc, out rid)) + return rid; + var row = new RawDocumentRow(GetDocumentNameBlobOffset(doc.Url), + debugMetaData.guidHeap.Add(doc.CheckSumAlgorithmId), + debugMetaData.blobHeap.Add(doc.CheckSum), + debugMetaData.guidHeap.Add(doc.Language)); + rid = debugMetaData.tablesHeap.DocumentTable.Add(row); + debugMetaData.pdbDocumentInfos.Add(doc, rid); + AddCustomDebugInformationList(Table.Document, rid, doc.CustomDebugInfos); + return rid; + } + + uint GetDocumentNameBlobOffset(string name) { + Debug.Assert(debugMetaData != null); + if (name == null) { + Error("Document name is null"); + name = string.Empty; + } + + var bwctx = AllocBinaryWriterContext(); + var outStream = bwctx.OutStream; + var writer = bwctx.Writer; + outStream.SetLength(0); + outStream.Position = 0; + var parts = name.Split(directorySeparatorCharArray); + if (parts.Length == 1) + writer.Write((byte)0); + else + writer.Write(directorySeparatorCharUtf8); + for (int i = 0; i < parts.Length; i++) { + var part = parts[i]; + uint partOffset = debugMetaData.blobHeap.Add(Encoding.UTF8.GetBytes(part)); + writer.WriteCompressedUInt32(partOffset); + } + + var res = debugMetaData.blobHeap.Add(outStream.ToArray()); + Free(ref bwctx); + return res; + } + static readonly byte[] directorySeparatorCharUtf8 = Encoding.UTF8.GetBytes(Path.DirectorySeparatorChar.ToString()); + static readonly char[] directorySeparatorCharArray = new char[] { Path.DirectorySeparatorChar }; + + uint AddImportScope(PdbImportScope scope) { + Debug.Assert(debugMetaData != null); + if (scope == null) + return 0; + uint rid; + if (debugMetaData.importScopeInfos.TryGetRid(scope, out rid)) { + if (rid == 0) + Error("PdbImportScope has an infinite Parent loop"); + return rid; + } + debugMetaData.importScopeInfos.Add(scope, 0); // Prevent inf recursion + + var bwctx = AllocBinaryWriterContext(); + var outStream = bwctx.OutStream; + var writer = bwctx.Writer; + outStream.SetLength(0); + outStream.Position = 0; + ImportScopeBlobWriter.Write(this, this, writer, debugMetaData.blobHeap, scope.Imports); + var importsData = outStream.ToArray(); + Free(ref bwctx); + + var row = new RawImportScopeRow(AddImportScope(scope.Parent), debugMetaData.blobHeap.Add(importsData)); + rid = debugMetaData.tablesHeap.ImportScopeTable.Add(row); + debugMetaData.importScopeInfos.SetRid(scope, rid); + + AddCustomDebugInformationList(Table.ImportScope, rid, scope.CustomDebugInfos); + return rid; + } + + void AddLocalVariable(PdbLocal local) { + Debug.Assert(debugMetaData != null); + if (local == null) { + Error("PDB local is null"); + return; + } + var row = new RawLocalVariableRow((ushort)local.Attributes, (ushort)local.Index, debugMetaData.stringsHeap.Add(local.Name)); + uint rid = debugMetaData.tablesHeap.LocalVariableTable.Create(row); + debugMetaData.localVariableInfos.Add(local, rid); + AddCustomDebugInformationList(Table.LocalVariable, rid, local.CustomDebugInfos); + } + + void AddLocalConstant(PdbConstant constant) { + Debug.Assert(debugMetaData != null); + if (constant == null) { + Error("PDB constant is null"); + return; + } + + var bwctx = AllocBinaryWriterContext(); + var outStream = bwctx.OutStream; + var writer = bwctx.Writer; + outStream.SetLength(0); + outStream.Position = 0; + LocalConstantSigBlobWriter.Write(this, this, writer, constant.Type, constant.Value); + var signature = outStream.ToArray(); + Free(ref bwctx); + + var row = new RawLocalConstantRow(debugMetaData.stringsHeap.Add(constant.Name), debugMetaData.blobHeap.Add(signature)); + uint rid = debugMetaData.tablesHeap.LocalConstantTable.Create(row); + debugMetaData.localConstantInfos.Add(constant, rid); + AddCustomDebugInformationList(Table.LocalConstant, rid, constant.CustomDebugInfos); + } + + /// + /// Writes the portable PDB to . + /// + /// Output stream + /// Entry point token + /// PDB ID, exactly 20 bytes + internal void WritePortablePdb(Stream output, uint entryPointToken, byte[] pdbId) { + if (debugMetaData == null) + throw new InvalidOperationException(); + if (pdbId.Length != 20) + throw new InvalidOperationException(); + var pdbHeap = debugMetaData.PdbHeap; + pdbHeap.EntryPoint = entryPointToken; + for (int i = 0; i < pdbId.Length; i++) + pdbHeap.PdbId[i] = pdbId[i]; + + ulong systemTablesMask; + tablesHeap.GetSystemTableRows(out systemTablesMask, pdbHeap.TypeSystemTableRows); + debugMetaData.tablesHeap.SetSystemTableRows(pdbHeap.TypeSystemTableRows); + if (!debugMetaData.methodDebugInformationInfosUsed) + debugMetaData.tablesHeap.MethodDebugInformationTable.Reset(); + pdbHeap.ReferencedTypeSystemTables = systemTablesMask; + var writer = new BinaryWriter(output); + debugMetaData.SetOffset(0, 0); + debugMetaData.GetFileLength(); + debugMetaData.VerifyWriteTo(writer); + } + /// uint ISignatureWriterHelper.ToEncodedToken(ITypeDefOrRef typeDefOrRef) { return AddTypeDefOrRef(typeDefOrRef); @@ -2707,6 +3411,7 @@ public void SetOffset(FileOffset offset, RVA rva) { blobHeap.SetReadOnly(); guidHeap.SetReadOnly(); tablesHeap.SetReadOnly(); + pdbHeap.SetReadOnly(); tablesHeap.BigStrings = stringsHeap.IsBig; tablesHeap.BigBlob = blobHeap.IsBig; tablesHeap.BigGuid = guidHeap.IsBig; @@ -2728,37 +3433,53 @@ public void SetOffset(FileOffset offset, RVA rva) { } length = rva - this.rva; - UpdateMethodRvas(); - UpdateFieldRvas(); + if (!isStandaloneDebugMetadata) { + UpdateMethodRvas(); + UpdateFieldRvas(); + } } IList GetHeaps() { var heaps = new List(); - if (options.OtherHeaps != null) - heaps.AddRange(options.OtherHeaps); - - // The #! heap must be added before the other heaps or the CLR can - // sometimes flag an error. Eg., it can check whether a pointer is valid. - // It does this by comparing the pointer to the last valid address for - // the particular heap. If this pointer really is in the #! heap and the - // #! heap is at an address > than the other heap, then the CLR will think - // it's an invalid pointer. - if (hotHeap != null) // Don't check whether it's empty - heaps.Add(hotHeap); - - heaps.Add(tablesHeap); - if (!stringsHeap.IsEmpty || AlwaysCreateStringsHeap) - heaps.Add(stringsHeap); - if (!usHeap.IsEmpty || AlwaysCreateUSHeap) - heaps.Add(usHeap); - if (!guidHeap.IsEmpty || AlwaysCreateGuidHeap) - heaps.Add(guidHeap); - if (!blobHeap.IsEmpty || AlwaysCreateBlobHeap) - heaps.Add(blobHeap); - - if (options.OtherHeapsEnd != null) - heaps.AddRange(options.OtherHeapsEnd); + if (isStandaloneDebugMetadata) { + heaps.Add(pdbHeap); + heaps.Add(tablesHeap); + if (!stringsHeap.IsEmpty) + heaps.Add(stringsHeap); + if (!usHeap.IsEmpty) + heaps.Add(usHeap); + if (!guidHeap.IsEmpty) + heaps.Add(guidHeap); + if (!blobHeap.IsEmpty) + heaps.Add(blobHeap); + } + else { + if (options.OtherHeaps != null) + heaps.AddRange(options.OtherHeaps); + + // The #! heap must be added before the other heaps or the CLR can + // sometimes flag an error. Eg., it can check whether a pointer is valid. + // It does this by comparing the pointer to the last valid address for + // the particular heap. If this pointer really is in the #! heap and the + // #! heap is at an address > than the other heap, then the CLR will think + // it's an invalid pointer. + if (hotHeap != null) // Don't check whether it's empty + heaps.Add(hotHeap); + + heaps.Add(tablesHeap); + if (!stringsHeap.IsEmpty || AlwaysCreateStringsHeap) + heaps.Add(stringsHeap); + if (!usHeap.IsEmpty || AlwaysCreateUSHeap) + heaps.Add(usHeap); + if (!guidHeap.IsEmpty || AlwaysCreateGuidHeap) + heaps.Add(guidHeap); + if (!blobHeap.IsEmpty || AlwaysCreateBlobHeap) + heaps.Add(blobHeap); + + if (options.OtherHeapsEnd != null) + heaps.AddRange(options.OtherHeapsEnd); + } return heaps; } @@ -2803,5 +3524,31 @@ protected static List Sort(IEnumerable pds) { }); return sorted; } + + BinaryWriterContext AllocBinaryWriterContext() { + if (binaryWriterContexts.Count == 0) + return new BinaryWriterContext(); + var res = binaryWriterContexts[binaryWriterContexts.Count - 1]; + binaryWriterContexts.RemoveAt(binaryWriterContexts.Count - 1); + return res; + } + + void Free(ref BinaryWriterContext ctx) { + binaryWriterContexts.Add(ctx); + ctx = null; + } + + SerializerMethodContext AllocSerializerMethodContext() { + if (serializerMethodContexts.Count == 0) + return new SerializerMethodContext(this); + var res = serializerMethodContexts[serializerMethodContexts.Count - 1]; + serializerMethodContexts.RemoveAt(serializerMethodContexts.Count - 1); + return res; + } + + void Free(ref SerializerMethodContext ctx) { + serializerMethodContexts.Add(ctx); + ctx = null; + } } } diff --git a/src/DotNet/Writer/MetaDataHeader.cs b/src/DotNet/Writer/MetaDataHeader.cs index 22a51c6a4..6c7c0ee7a 100644 --- a/src/DotNet/Writer/MetaDataHeader.cs +++ b/src/DotNet/Writer/MetaDataHeader.cs @@ -57,6 +57,22 @@ public sealed class MetaDataHeaderOptions { /// Reserved and should be 0 /// public byte? Reserved2; + + /// + /// Creates portable PDB v1.0 options + /// + /// + public static MetaDataHeaderOptions CreatePortablePdbV1_0() { + return new MetaDataHeaderOptions() { + Signature = DEFAULT_SIGNATURE, + MajorVersion = 1, + MinorVersion = 1, + Reserved1 = 0, + VersionString = MDHeaderRuntimeVersion.PORTABLE_PDB_V1_0, + StorageFlags = 0, + Reserved2 = 0, + }; + } } /// diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 02fe004a6..b5deb2794 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -227,7 +227,7 @@ void AddChunksToSections() { textSection.Add(methodBodies, DEFAULT_METHODBODIES_ALIGNMENT); textSection.Add(netResources, DEFAULT_NETRESOURCES_ALIGNMENT); textSection.Add(metaData, DEFAULT_METADATA_ALIGNMENT); - textSection.Add(debugDirectory, DEFAULT_DEBUGDIRECTORY_ALIGNMENT); + textSection.Add(debugDirectory, DebugDirectory.DEFAULT_DEBUGDIRECTORY_ALIGNMENT); textSection.Add(importDirectory, DEFAULT_IMPORTDIRECTORY_ALIGNMENT); textSection.Add(startupStub, DEFAULT_STARTUPSTUB_ALIGNMENT); if (rsrcSection != null) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 7d4df92b7..36082b7ff 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -10,6 +10,8 @@ using dnlib.DotNet.MD; using System.Diagnostics; using dnlib.DotNet.Pdb.WindowsPdb; +using System.Text; +using System.IO.Compression; namespace dnlib.DotNet.Writer { /// @@ -187,11 +189,9 @@ public bool IsExeFile { public Stream PdbStream { get; set; } /// - /// If or aren't enough, this can be used - /// to create a new instance. must be - /// true or this property is ignored. + /// GUID used by some PDB writers, eg. portable PDB writer. It's initialized to a random GUID. /// - public CreatePdbSymbolWriterDelegate CreatePdbSymbolWriter { get; set; } + public Guid PdbGuid { get; set; } /// /// Default constructor @@ -199,6 +199,7 @@ public bool IsExeFile { protected ModuleWriterOptionsBase() { ShareMethodBodies = true; ModuleKind = ModuleKind.Windows; + PdbGuid = Guid.NewGuid(); } /// @@ -216,6 +217,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) /// Module writer listener protected ModuleWriterOptionsBase(ModuleDef module, IModuleWriterListener listener) { this.listener = listener; + PdbGuid = Guid.NewGuid(); ShareMethodBodies = true; MetaDataOptions.MetaDataHeaderOptions.VersionString = module.RuntimeVersion; ModuleKind = module.Kind; @@ -326,13 +328,6 @@ public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey } } - /// - /// Creates a new instance - /// - /// Module writer - /// A new instance - public delegate ISymbolWriter2 CreatePdbSymbolWriterDelegate(ModuleWriterBase writer); - /// /// Module writer base class /// @@ -351,8 +346,6 @@ public abstract class ModuleWriterBase : IMetaDataListener, ILogger { protected const uint DEFAULT_STRONGNAMESIG_ALIGNMENT = 16; /// Default COR20 header alignment protected const uint DEFAULT_COR20HEADER_ALIGNMENT = 4; - /// Default debug directory alignment - protected const uint DEFAULT_DEBUGDIRECTORY_ALIGNMENT = 4; /// See protected Stream destStream; @@ -471,6 +464,11 @@ public bool IsNativeWriter { get { return this is NativeModuleWriter; } } + /// + /// null if we're not writing a PDB + /// + PdbState pdbState; + /// /// Writes the module to a file /// @@ -505,6 +503,7 @@ static void DeleteFileNoThrow(string fileName) { /// /// Destination stream public void Write(Stream dest) { + pdbState = TheOptions.WritePdb && Module.PdbState != null ? Module.PdbState : null; if (TheOptions.DelaySign) { Debug.Assert(TheOptions.StrongNamePublicKey != null, "Options.StrongNamePublicKey must be initialized when delay signing the assembly"); Debug.Assert(TheOptions.StrongNameKey == null, "Options.StrongNameKey must be null when delay signing the assembly"); @@ -563,7 +562,12 @@ protected void CreateMetaDataChunks(ModuleDef module) { methodBodies = new MethodBodyChunks(TheOptions.ShareMethodBodies); netResources = new NetResources(DEFAULT_NETRESOURCES_ALIGNMENT); - metaData = MetaData.Create(module, constants, methodBodies, netResources, TheOptions.MetaDataOptions); + DebugMetaDataKind debugKind; + if (pdbState != null && (pdbState.PdbFileKind == PdbFileKind.PortablePDB || pdbState.PdbFileKind == PdbFileKind.EmbeddedPortablePDB)) + debugKind = DebugMetaDataKind.Standalone; + else + debugKind = DebugMetaDataKind.None; + metaData = MetaData.Create(module, constants, methodBodies, netResources, TheOptions.MetaDataOptions, debugKind); metaData.Logger = TheOptions.MetaDataLogger ?? this; metaData.Listener = this; @@ -630,7 +634,7 @@ protected void StrongNameSign(long snSigOffset) { } bool CanWritePdb() { - return TheOptions.WritePdb && Module.PdbState != null; + return pdbState != null; } /// @@ -651,33 +655,52 @@ protected void WritePdbFile() { if (debugDirectory == null) throw new InvalidOperationException("debugDirectory is null but WritePdb is true"); - var pdbState = Module.PdbState; if (pdbState == null) { Error("TheOptions.WritePdb is true but module has no PdbState"); - debugDirectory.DontWriteAnything = true; return; } - var symWriter = GetSymbolWriter2(); + try { + switch (pdbState.PdbFileKind) { + case PdbFileKind.WindowsPDB: + WriteWindowsPdb(pdbState); + break; + + case PdbFileKind.PortablePDB: + WritePortablePdb(pdbState, false); + break; + + case PdbFileKind.EmbeddedPortablePDB: + WritePortablePdb(pdbState, true); + break; + + default: + Error("Invalid PDB file kind {0}", pdbState.PdbFileKind); + break; + } + } + catch { + DeleteFileNoThrow(createdPdbFileName); + throw; + } + } + + void WriteWindowsPdb(PdbState pdbState) { + var symWriter = GetWindowsPdbSymbolWriter(); if (symWriter == null) { Error("Could not create a PDB symbol writer. A Windows OS might be required."); - debugDirectory.DontWriteAnything = true; return; } - var pdbWriter = new PdbWriter(symWriter, pdbState, metaData); - try { + using (var pdbWriter = new WindowsPdbWriter(symWriter, pdbState, metaData)) { pdbWriter.Logger = TheOptions.Logger; pdbWriter.Write(); - debugDirectory.Data = pdbWriter.GetDebugInfo(out debugDirectory.debugDirData); - debugDirectory.TimeDateStamp = GetTimeDateStamp(); - pdbWriter.Dispose(); - } - catch { - pdbWriter.Dispose(); - DeleteFileNoThrow(createdPdbFileName); - throw; + IMAGE_DEBUG_DIRECTORY idd; + var data = pdbWriter.GetDebugInfo(out idd); + var entry = debugDirectory.Add(new ByteArrayChunk(data)); + entry.DebugDirectory = idd; + entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); } } @@ -689,13 +712,7 @@ uint GetTimeDateStamp() { return (uint)TheOptions.PEHeadersOptions.TimeDateStamp; } - ISymbolWriter2 GetSymbolWriter2() { - if (TheOptions.CreatePdbSymbolWriter != null) { - var writer = TheOptions.CreatePdbSymbolWriter(this); - if (writer != null) - return writer; - } - + ISymbolWriter2 GetWindowsPdbSymbolWriter() { if (TheOptions.PdbStream != null) { return SymbolWriterCreator.Create(TheOptions.PdbStream, TheOptions.PdbFileName ?? @@ -719,8 +736,17 @@ static string GetStreamName(Stream stream) { return fs == null ? null : fs.Name; } + static string GetModuleName(ModuleDef module) { + var name = module.Name ?? string.Empty; + if (string.IsNullOrEmpty(name)) + return null; + if (name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || name.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || name.EndsWith(".netmodule", StringComparison.OrdinalIgnoreCase)) + return name; + return name + ".pdb"; + } + string GetDefaultPdbFileName() { - var destFileName = GetStreamName(destStream); + var destFileName = GetStreamName(destStream) ?? GetModuleName(Module); if (string.IsNullOrEmpty(destFileName)) { Error("TheOptions.WritePdb is true but it's not possible to guess the default PDB file name. Set PdbFileName to the name of the PDB file."); return null; @@ -729,6 +755,110 @@ string GetDefaultPdbFileName() { return Path.ChangeExtension(destFileName, "pdb"); } + void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { + bool ownsStream = false; + Stream pdbStream = null; + try { + MemoryStream embeddedMemoryStream = null; + if (isEmbeddedPortablePdb) { + pdbStream = embeddedMemoryStream = new MemoryStream(); + ownsStream = true; + } + else + pdbStream = GetStandalonePortablePdbStream(out ownsStream); + + var pdbFilename = TheOptions.PdbFileName ?? GetStreamName(pdbStream) ?? GetDefaultPdbFileName(); + if (isEmbeddedPortablePdb) + pdbFilename = Path.GetFileName(pdbFilename); + + uint entryPointToken; + if (pdbState.UserEntryPoint == null) + entryPointToken = 0; + else + entryPointToken = new MDToken(Table.Method, metaData.GetRid(pdbState.UserEntryPoint)).Raw; + + var pdbId = new byte[20]; + var pdbIdWriter = new BinaryWriter(new MemoryStream(pdbId)); + var pdbGuid = TheOptions.PdbGuid; + pdbIdWriter.Write(pdbGuid.ToByteArray()); + pdbIdWriter.Write(GetTimeDateStamp()); + Debug.Assert(pdbIdWriter.BaseStream.Position == pdbId.Length); + + metaData.WritePortablePdb(pdbStream, entryPointToken, pdbId); + + const uint age = 1; + var cvEntry = debugDirectory.Add(new ByteArrayChunk(GetCodeViewData(pdbGuid, age, pdbFilename))); + cvEntry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); + cvEntry.DebugDirectory.MajorVersion = PortablePdbConstants.EmbeddedPortablePdb_FormatVersion; + cvEntry.DebugDirectory.MinorVersion = PortablePdbConstants.PortableCodeViewVersionMagic; + cvEntry.DebugDirectory.Type = ImageDebugType.CodeView; + + if (isEmbeddedPortablePdb) { + Debug.Assert(embeddedMemoryStream != null); + var embedEntry = debugDirectory.Add(new ByteArrayChunk(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream))); + embedEntry.DebugDirectory.TimeDateStamp = 0; + embedEntry.DebugDirectory.MajorVersion = PortablePdbConstants.EmbeddedPortablePdb_FormatVersion; + embedEntry.DebugDirectory.MinorVersion = PortablePdbConstants.EmbeddedPortablePdb_EmbeddedVersion; + embedEntry.DebugDirectory.Type = ImageDebugType.EmbeddedPortablePdb; + } + } + finally { + if (ownsStream && pdbStream != null) + pdbStream.Dispose(); + } + } + + static byte[] CreateEmbeddedPortablePdbBlob(MemoryStream portablePdbStream) { + var compressedData = Compress(portablePdbStream); + var data = new byte[4 + 4 + compressedData.Length]; + var stream = new MemoryStream(data); + var writer = new BinaryWriter(stream); + writer.Write(0x4244504D);//"MPDB" + writer.Write((uint)portablePdbStream.Length); + writer.Write(compressedData); + Debug.Assert(stream.Position == data.Length); + return data; + } + + static byte[] Compress(MemoryStream sourceStream) { + sourceStream.Position = 0; + var destStream = new MemoryStream(); + using (var deflate = new DeflateStream(destStream, CompressionMode.Compress)) { + var source = sourceStream.ToArray(); + deflate.Write(source, 0, source.Length); + } + return destStream.ToArray(); + } + + static byte[] GetCodeViewData(Guid guid, uint age, string filename) { + var stream = new MemoryStream(); + var writer = new BinaryWriter(stream); + writer.Write(0x53445352); + writer.Write(guid.ToByteArray()); + writer.Write(age); + writer.Write(Encoding.UTF8.GetBytes(filename)); + writer.Write((byte)0); + return stream.ToArray(); + } + + Stream GetStandalonePortablePdbStream(out bool ownsStream) { + if (TheOptions.PdbStream != null) { + ownsStream = false; + return TheOptions.PdbStream; + } + + if (!string.IsNullOrEmpty(TheOptions.PdbFileName)) + createdPdbFileName = TheOptions.PdbFileName; + else + createdPdbFileName = GetDefaultPdbFileName(); + if (createdPdbFileName == null) { + ownsStream = false; + return null; + } + ownsStream = true; + return File.Create(createdPdbFileName); + } + /// void IMetaDataListener.OnMetaDataEvent(MetaData metaData, MetaDataEvent evt) { switch (evt) { diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 5d0897183..76b74debd 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -253,7 +253,7 @@ void AddChunksToSections() { textSection.Add(methodBodies, DEFAULT_METHODBODIES_ALIGNMENT); textSection.Add(netResources, DEFAULT_NETRESOURCES_ALIGNMENT); textSection.Add(metaData, DEFAULT_METADATA_ALIGNMENT); - textSection.Add(debugDirectory, DEFAULT_DEBUGDIRECTORY_ALIGNMENT); + textSection.Add(debugDirectory, DebugDirectory.DEFAULT_DEBUGDIRECTORY_ALIGNMENT); if (rsrcSection != null) rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); } @@ -341,6 +341,9 @@ uint GetLastFileSectionOffset() { } long WriteFile() { + uint entryPointToken; + bool entryPointIsManagedOrNoEntryPoint = GetEntryPoint(out entryPointToken); + Listener.OnWriterEvent(this, ModuleWriterEvent.BeginWritePdb); WritePdbFile(); Listener.OnWriterEvent(this, ModuleWriterEvent.EndWritePdb); @@ -367,7 +370,7 @@ long WriteFile() { var writer = new BinaryWriter(destStream); WriteChunks(writer, chunks, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment); long imageLength = writer.BaseStream.Position - destStreamBaseOffset; - UpdateHeaderFields(writer); + UpdateHeaderFields(writer, entryPointIsManagedOrNoEntryPoint, entryPointToken); Listener.OnWriterEvent(this, ModuleWriterEvent.EndWriteChunks); Listener.OnWriterEvent(this, ModuleWriterEvent.BeginStrongNameSign); @@ -411,7 +414,7 @@ Characteristics GetCharacteristics() { /// Updates the PE header and COR20 header fields that need updating. All sections are /// also updated, and the new ones are added. /// - void UpdateHeaderFields(BinaryWriter writer) { + void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPoint, uint entryPointToken) { long fileHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.FileHeader.StartOffset; long optionalHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.StartOffset; long sectionsOffset = destStreamBaseOffset + (long)peImage.ImageSectionHeaders[0].StartOffset; @@ -512,7 +515,7 @@ void UpdateHeaderFields(BinaryWriter writer) { // Write a new debug directory writer.BaseStream.Position = dataDirOffset + 6 * 8; - writer.WriteDataDirectory(debugDirectory, DebugDirectory.HEADER_SIZE); + writer.WriteDataDirectory(debugDirectory); // Write a new Metadata data directory writer.BaseStream.Position = dataDirOffset + 14 * 8; @@ -534,9 +537,8 @@ void UpdateHeaderFields(BinaryWriter writer) { WriteUInt16(writer, Options.Cor20HeaderOptions.MajorRuntimeVersion); WriteUInt16(writer, Options.Cor20HeaderOptions.MinorRuntimeVersion); writer.WriteDataDirectory(metaData); - uint entryPoint; - writer.Write((uint)GetComImageFlags(GetEntryPoint(out entryPoint))); - writer.Write(Options.Cor20HeaderOptions.EntryPoint ?? entryPoint); + writer.Write((uint)GetComImageFlags(entryPointIsManagedOrNoEntryPoint)); + writer.Write(entryPointToken); writer.WriteDataDirectory(netResources); writer.WriteDataDirectory(strongNameSignature); WriteDataDirectory(writer, module.MetaData.ImageCor20Header.CodeManagerTable); @@ -699,6 +701,12 @@ uint GetMethodToken(IMethod method) { /// true if it's a managed entry point or there's no entry point, /// false if it's a native entry point bool GetEntryPoint(out uint ep) { + var tok = Options.Cor20HeaderOptions.EntryPoint; + if (tok != null) { + ep = tok.Value; + return ep == 0 || ((Options.Cor20HeaderOptions.Flags ?? 0) & ComImageFlags.NativeEntryPoint) == 0; + } + var epMethod = module.ManagedEntryPoint as MethodDef; if (epMethod != null) { ep = new MDToken(Table.Method, metaData.GetRid(epMethod)).Raw; diff --git a/src/DotNet/Writer/NormalMetaData.cs b/src/DotNet/Writer/NormalMetaData.cs index 59023a2cc..c0033051f 100644 --- a/src/DotNet/Writer/NormalMetaData.cs +++ b/src/DotNet/Writer/NormalMetaData.cs @@ -24,16 +24,8 @@ protected override int NumberOfMethods { get { return methodDefInfos.Count; } } - /// - /// Constructor - /// - /// Module - /// Constants list - /// Method bodies list - /// .NET resources list - /// Options - public NormalMetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options) - : base(module, constants, methodBodies, netResources, options) { + public NormalMetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options, DebugMetaDataKind debugKind, bool isStandaloneDebugMetadata) + : base(module, constants, methodBodies, netResources, options, debugKind, isStandaloneDebugMetadata) { } /// @@ -260,6 +252,7 @@ protected override uint AddTypeRef(TypeRef tr) { rid = tablesHeap.TypeRefTable.Add(row); typeRefInfos.SetRid(tr, rid); AddCustomAttributes(Table.TypeRef, rid, tr); + AddCustomDebugInformationList(Table.TypeRef, rid, tr); return rid; } @@ -280,6 +273,7 @@ protected override uint AddTypeSpec(TypeSpec ts) { rid = tablesHeap.TypeSpecTable.Add(row); typeSpecInfos.SetRid(ts, rid); AddCustomAttributes(Table.TypeSpec, rid, ts); + AddCustomDebugInformationList(Table.TypeSpec, rid, ts); return rid; } @@ -298,6 +292,7 @@ protected override uint AddMemberRef(MemberRef mr) { rid = tablesHeap.MemberRefTable.Add(row); memberRefInfos.Add(mr, rid); AddCustomAttributes(Table.MemberRef, rid, mr); + AddCustomDebugInformationList(Table.MemberRef, rid, mr); return rid; } @@ -314,6 +309,7 @@ protected override uint AddStandAloneSig(StandAloneSig sas) { rid = tablesHeap.StandAloneSigTable.Add(row); standAloneSigInfos.Add(sas, rid); AddCustomAttributes(Table.StandAloneSig, rid, sas); + AddCustomDebugInformationList(Table.StandAloneSig, rid, sas); return rid; } @@ -331,6 +327,7 @@ protected override uint AddMethodSpec(MethodSpec ms) { rid = tablesHeap.MethodSpecTable.Add(row); methodSpecInfos.Add(ms, rid); AddCustomAttributes(Table.MethodSpec, rid, ms); + AddCustomDebugInformationList(Table.MethodSpec, rid, ms); return rid; } } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 5a58f16e3..4c5d8f5c7 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -428,7 +428,7 @@ public void WriteTo(BinaryWriter writer) { writer.WriteDataDirectory(null); // Exception table writer.WriteDataDirectory(null); // Certificate table writer.WriteDataDirectory(RelocDirectory); - writer.WriteDataDirectory(DebugDirectory, DebugDirectory.HEADER_SIZE); + writer.WriteDataDirectory(DebugDirectory); writer.WriteDataDirectory(null); // Architecture-specific data writer.WriteDataDirectory(null); // Global pointer register RVA writer.WriteDataDirectory(null); // Thread local storage diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs new file mode 100644 index 000000000..6be6fbcd3 --- /dev/null +++ b/src/DotNet/Writer/PdbHeap.cs @@ -0,0 +1,98 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; + +namespace dnlib.DotNet.Writer { + /// + /// #Pdb heap + /// + public sealed class PdbHeap : HeapBase { + /// + public override string Name { + get { return "#Pdb"; } + } + + /// + /// Gets the PDB ID. This is always 20 bytes in size. + /// + public byte[] PdbId { + get { return pdbId; } + } + readonly byte[] pdbId; + + /// + /// Gets/sets the entry point token + /// + public uint EntryPoint { + get { return entryPoint; } + set { entryPoint = value; } + } + uint entryPoint; + + /// + /// Gets/sets the referenced type system tables + /// + public ulong ReferencedTypeSystemTables { + get { + if (!referencedTypeSystemTablesInitd) + throw new InvalidOperationException("ReferencedTypeSystemTables hasn't been initialized yet"); + return referencedTypeSystemTables; + } + set { + if (isReadOnly) + throw new InvalidOperationException("Size has already been calculated, can't write a new value"); + referencedTypeSystemTables = value; + referencedTypeSystemTablesInitd = true; + + typeSystemTablesCount = 0; + ulong l = value; + while (l != 0) { + if (((int)l & 1) != 0) + typeSystemTablesCount++; + l >>= 1; + } + } + } + ulong referencedTypeSystemTables; + bool referencedTypeSystemTablesInitd; + int typeSystemTablesCount; + + /// + /// Gets the type system table rows. This table has 64 elements. + /// + public uint[] TypeSystemTableRows { + get { return typeSystemTableRows; } + } + readonly uint[] typeSystemTableRows; + + /// + /// Constructor + /// + public PdbHeap() { + pdbId = new byte[20]; + typeSystemTableRows = new uint[64]; + } + + /// + public override uint GetRawLength() { + if (!referencedTypeSystemTablesInitd) + throw new InvalidOperationException("ReferencedTypeSystemTables hasn't been initialized yet"); + return (uint)(pdbId.Length + 4 + 8 + 4 * typeSystemTablesCount); + } + + /// + protected override void WriteToImpl(BinaryWriter writer) { + if (!referencedTypeSystemTablesInitd) + throw new InvalidOperationException("ReferencedTypeSystemTables hasn't been initialized yet"); + writer.Write(pdbId); + writer.Write(entryPoint); + writer.Write(referencedTypeSystemTables); + ulong t = referencedTypeSystemTables; + for (int i = 0; i < typeSystemTableRows.Length; i++, t >>= 1) { + if (((int)t & 1) != 0) + writer.Write(typeSystemTableRows[i]); + } + } + } +} diff --git a/src/DotNet/Writer/PortablePdbConstants.cs b/src/DotNet/Writer/PortablePdbConstants.cs new file mode 100644 index 000000000..7d9043343 --- /dev/null +++ b/src/DotNet/Writer/PortablePdbConstants.cs @@ -0,0 +1,21 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Writer { + static class PortablePdbConstants { + // See System.Reflection.Metadata.PortablePdbVersions + + // Portable PDB version (v1.0) + // Format version is stored in DebugDirectory.MajorVersion + // SRM: DefaultFormatVersion, MinFormatVersion + public const ushort EmbeddedPortablePdb_FormatVersion = 0x0100; + + // Embedded Portable PDB Blob verison (v1.0) + // Embedded version is stored in DebugDirectory.MinorVersion + // SRM: MinEmbeddedVersion, DefaultEmbeddedVersion, MinUnsupportedEmbeddedVersion + public const ushort EmbeddedPortablePdb_EmbeddedVersion = 0x0100; + + // Stored in DebugDirectory.MinorVersion and indicates that it's a portable PDB file + // and not a Windows PDB file + public const ushort PortableCodeViewVersionMagic = 0x504D; + } +} diff --git a/src/DotNet/Writer/PreserveTokensMetaData.cs b/src/DotNet/Writer/PreserveTokensMetaData.cs index 2cda111dd..f04a835da 100644 --- a/src/DotNet/Writer/PreserveTokensMetaData.cs +++ b/src/DotNet/Writer/PreserveTokensMetaData.cs @@ -207,16 +207,8 @@ protected override int NumberOfMethods { get { return methodDefInfos.Count; } } - /// - /// Constructor - /// - /// Module - /// Constants list - /// Method bodies list - /// .NET resources list - /// Options - public PreserveTokensMetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options) - : base(module, constants, methodBodies, netResources, options) { + public PreserveTokensMetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options, DebugMetaDataKind debugKind, bool isStandaloneDebugMetadata) + : base(module, constants, methodBodies, netResources, options, debugKind, isStandaloneDebugMetadata) { mod = module as ModuleDefMD; if (mod == null) throw new ModuleWriterException("Not a ModuleDefMD"); @@ -1072,6 +1064,7 @@ protected override uint AddTypeRef(TypeRef tr) { rid = isOld ? tr.Rid : tablesHeap.TypeRefTable.Add(row); typeRefInfos.SetRid(tr, rid); AddCustomAttributes(Table.TypeRef, rid, tr); + AddCustomDebugInformationList(Table.TypeRef, rid, tr); return rid; } @@ -1100,6 +1093,7 @@ uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { rid = isOld ? ts.Rid : tablesHeap.TypeSpecTable.Add(row); typeSpecInfos.SetRid(ts, rid); AddCustomAttributes(Table.TypeSpec, rid, ts); + AddCustomDebugInformationList(Table.TypeSpec, rid, ts); return rid; } @@ -1126,6 +1120,7 @@ uint AddMemberRef(MemberRef mr, bool forceIsOld) { rid = isOld ? mr.Rid : tablesHeap.MemberRefTable.Add(row); memberRefInfos.Add(mr, rid); AddCustomAttributes(Table.MemberRef, rid, mr); + AddCustomDebugInformationList(Table.MemberRef, rid, mr); return rid; } @@ -1150,6 +1145,7 @@ uint AddStandAloneSig(StandAloneSig sas, bool forceIsOld) { rid = isOld ? sas.Rid : tablesHeap.StandAloneSigTable.Add(row); standAloneSigInfos.Add(sas, rid); AddCustomAttributes(Table.StandAloneSig, rid, sas); + AddCustomDebugInformationList(Table.StandAloneSig, rid, sas); return rid; } @@ -1246,6 +1242,7 @@ uint AddMethodSpec(MethodSpec ms, bool forceIsOld) { rid = isOld ? ms.Rid : tablesHeap.MethodSpecTable.Add(row); methodSpecInfos.Add(ms, rid); AddCustomAttributes(Table.MethodSpec, rid, ms); + AddCustomDebugInformationList(Table.MethodSpec, rid, ms); return rid; } diff --git a/src/DotNet/Writer/SerializerMethodContext.cs b/src/DotNet/Writer/SerializerMethodContext.cs new file mode 100644 index 000000000..a9dd30232 --- /dev/null +++ b/src/DotNet/Writer/SerializerMethodContext.cs @@ -0,0 +1,68 @@ +// dnlib: See LICENSE.txt for more info + +using System.Collections.Generic; +using System.Diagnostics; +using dnlib.DotNet.Emit; + +namespace dnlib.DotNet.Writer { + sealed class SerializerMethodContext { + readonly Dictionary toOffset; + readonly IWriterError helper; + MethodDef method; + CilBody body; + uint bodySize; + bool dictInitd; + + public bool HasBody { + get { return body != null; } + } + + public SerializerMethodContext(IWriterError helper) { + toOffset = new Dictionary(); + this.helper = helper; + } + + internal void SetBody(MethodDef method) { + if (this.method != method) { + toOffset.Clear(); + this.method = method; + this.body = method == null ? null : method.Body; + dictInitd = false; + } + } + + public uint GetOffset(Instruction instr) { + if (!dictInitd) { + Debug.Assert(body != null); + if (body == null) + return 0; + InitializeDict(); + } + if (instr == null) + return bodySize; + uint offset; + if (toOffset.TryGetValue(instr, out offset)) + return offset; + helper.Error("Couldn't find an instruction, maybe it was removed. It's still being referenced by some code or by the PDB"); + return bodySize; + } + + public bool IsSameMethod(MethodDef method) { + return this.method == method; + } + + void InitializeDict() { + Debug.Assert(body != null); + Debug.Assert(toOffset.Count == 0); + uint offset = 0; + var instrs = body.Instructions; + for(int i = 0; i < instrs.Count; i++) { + var instr = instrs[i]; + toOffset[instr] = offset; + offset += (uint)instr.GetSize(); + } + bodySize = offset; + dictInitd = true; + } + } +} diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 35379ddea..126df84a3 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -4,6 +4,8 @@ using dnlib.IO; using dnlib.PE; using dnlib.DotNet.MD; +using System; +using System.Collections.Generic; namespace dnlib.DotNet.Writer { /// @@ -44,6 +46,21 @@ public sealed class TablesHeapOptions { /// s. /// public bool? HasDeletedRows; + + /// + /// Creates portable PDB v1.0 options + /// + /// + public static TablesHeapOptions CreatePortablePdbV1_0() { + return new TablesHeapOptions { + Reserved1 = 0, + MajorVersion = 2, + MinorVersion = 0, + UseENC = null, + ExtraData = null, + HasDeletedRows = null, + }; + } } /// @@ -117,6 +134,14 @@ public RVA RVA { public readonly MDTable GenericParamTable = new MDTable(Table.GenericParam, RawRowEqualityComparer.Instance); public readonly MDTable MethodSpecTable = new MDTable(Table.MethodSpec, RawRowEqualityComparer.Instance); public readonly MDTable GenericParamConstraintTable = new MDTable(Table.GenericParamConstraint, RawRowEqualityComparer.Instance); + public readonly MDTable DocumentTable = new MDTable(Table.Document, RawRowEqualityComparer.Instance); + public readonly MDTable MethodDebugInformationTable = new MDTable(Table.MethodDebugInformation, RawRowEqualityComparer.Instance); + public readonly MDTable LocalScopeTable = new MDTable(Table.LocalScope, RawRowEqualityComparer.Instance); + public readonly MDTable LocalVariableTable = new MDTable(Table.LocalVariable, RawRowEqualityComparer.Instance); + public readonly MDTable LocalConstantTable = new MDTable(Table.LocalConstant, RawRowEqualityComparer.Instance); + public readonly MDTable ImportScopeTable = new MDTable(Table.ImportScope, RawRowEqualityComparer.Instance); + public readonly MDTable StateMachineMethodTable = new MDTable(Table.StateMachineMethod, RawRowEqualityComparer.Instance); + public readonly MDTable CustomDebugInformationTable = new MDTable(Table.CustomDebugInformation, RawRowEqualityComparer.Instance); #pragma warning restore /// @@ -259,9 +284,41 @@ public TablesHeap(TablesHeapOptions options) { GenericParamTable, MethodSpecTable, GenericParamConstraintTable, + new MDTable((Table)0x2D, RawDummyRow.Comparer), + new MDTable((Table)0x2E, RawDummyRow.Comparer), + new MDTable((Table)0x2F, RawDummyRow.Comparer), + DocumentTable, + MethodDebugInformationTable, + LocalScopeTable, + LocalVariableTable, + LocalConstantTable, + ImportScopeTable, + StateMachineMethodTable, + CustomDebugInformationTable, }; } + sealed class RawDummyRow : IRawRow { + public static readonly IEqualityComparer Comparer = new RawDummyRowEqualityComparer(); + sealed class RawDummyRowEqualityComparer : IEqualityComparer { + public bool Equals(RawDummyRow x, RawDummyRow y) { + throw new NotSupportedException(); + } + + public int GetHashCode(RawDummyRow obj) { + throw new NotSupportedException(); + } + } + + public uint Read(int index) { + throw new NotSupportedException(); + } + + public void Write(int index, uint value) { + throw new NotSupportedException(); + } + } + /// public void SetReadOnly() { foreach (var mdt in Tables) @@ -305,7 +362,7 @@ public void CalculateLength() { var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion); var rowCounts = GetRowCounts(); - dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, rowCounts, rowCounts); + dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, systemTables ?? rowCounts, rowCounts); for (int i = 0; i < Tables.Length; i++) Tables[i].TableInfo = tableInfos[i]; @@ -326,6 +383,32 @@ uint[] GetRowCounts() { return sizes; } + internal void GetSystemTableRows(out ulong mask, uint[] tables) { + if (tables.Length != 0x40) + throw new InvalidOperationException(); + var tablesMask = GetValidMask(); + ulong bit = 1; + mask = 0; + for (int i = 0; i < 0x40; i++, bit <<= 1) { + var table = (Table)i; + if (DotNetTableSizes.IsSystemTable(table)) { + if ((tablesMask & bit) != 0) { + tables[i] = (uint)Tables[i].Rows; + mask |= bit; + } + else + tables[i] = 0; + } + else + tables[i] = 0; + } + } + + internal void SetSystemTableRows(uint[] systemTables) { + this.systemTables = (uint[])systemTables.Clone(); + } + uint[] systemTables; + /// public void WriteTo(BinaryWriter writer) { writer.Write(options.Reserved1 ?? 0); @@ -387,6 +470,14 @@ public void WriteTo(BinaryWriter writer) { writer.Write(GenericParamTable); writer.Write(MethodSpecTable); writer.Write(GenericParamConstraintTable); + writer.Write(DocumentTable); + writer.Write(MethodDebugInformationTable); + writer.Write(LocalScopeTable); + writer.Write(LocalVariableTable); + writer.Write(LocalConstantTable); + writer.Write(ImportScopeTable); + writer.Write(StateMachineMethodTable); + writer.Write(CustomDebugInformationTable); writer.WriteZeros((int)(Utils.AlignUp(length, HeapBase.ALIGNMENT) - length)); } diff --git a/src/PE/IPEImage.cs b/src/PE/IPEImage.cs index 873ed7124..74dcbbc23 100644 --- a/src/PE/IPEImage.cs +++ b/src/PE/IPEImage.cs @@ -61,6 +61,11 @@ public interface IPEImage : IRvaFileOffsetConverter, IDisposable { /// IList ImageSectionHeaders { get; } + /// + /// Returns the debug directories + /// + IList ImageDebugDirectories { get; } + /// /// Gets/sets the Win32 resources. This is null if there are no Win32 resources. /// diff --git a/src/PE/ImageDebugDirectory.cs b/src/PE/ImageDebugDirectory.cs new file mode 100644 index 000000000..4a8eda053 --- /dev/null +++ b/src/PE/ImageDebugDirectory.cs @@ -0,0 +1,97 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Diagnostics; +using dnlib.IO; + +namespace dnlib.PE { + /// + /// A IMAGE_DEBUG_DIRECTORY + /// + [DebuggerDisplay("{type}: TS:{timeDateStamp,h} V:{majorVersion,d}.{minorVersion,d} SZ:{sizeOfData} RVA:{addressOfRawData,h} FO:{pointerToRawData,h}")] + public sealed class ImageDebugDirectory : FileSection { + readonly uint characteristics; + readonly uint timeDateStamp; + readonly ushort majorVersion; + readonly ushort minorVersion; + readonly ImageDebugType type; + readonly uint sizeOfData; + readonly uint addressOfRawData; + readonly uint pointerToRawData; + + /// + /// Gets the characteristics (reserved) + /// + public uint Characteristics { + get { return characteristics; } + } + + /// + /// Gets the timestamp + /// + public uint TimeDateStamp { + get { return timeDateStamp; } + } + + /// + /// Gets the major version + /// + public ushort MajorVersion { + get { return majorVersion; } + } + + /// + /// Gets the minor version + /// + public ushort MinorVersion { + get { return minorVersion; } + } + + /// + /// Gets the type + /// + public ImageDebugType Type { + get { return type; } + } + + /// + /// Gets the size of data + /// + public uint SizeOfData { + get { return sizeOfData; } + } + + /// + /// RVA of the data + /// + public RVA AddressOfRawData { + get { return (RVA)addressOfRawData; } + } + + /// + /// File offset of the data + /// + public FileOffset PointerToRawData { + get { return (FileOffset)pointerToRawData; } + } + + /// + /// Constructor + /// + /// PE file reader pointing to the start of this section + /// Verify section + /// Thrown if verification fails + public ImageDebugDirectory(IImageStream reader, bool verify) { + SetStartOffset(reader); + characteristics = reader.ReadUInt32(); + timeDateStamp = reader.ReadUInt32(); + majorVersion = reader.ReadUInt16(); + minorVersion = reader.ReadUInt16(); + type = (ImageDebugType)reader.ReadUInt32(); + sizeOfData = reader.ReadUInt32(); + addressOfRawData = reader.ReadUInt32(); + pointerToRawData = reader.ReadUInt32(); + SetEndoffset(reader); + } + } +} diff --git a/src/PE/ImageDebugType.cs b/src/PE/ImageDebugType.cs new file mode 100644 index 000000000..0e2e82b45 --- /dev/null +++ b/src/PE/ImageDebugType.cs @@ -0,0 +1,42 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.PE { + /// + /// Image debug type, see IMAGE_DEBUG_TYPE_* in winnt.n + /// + public enum ImageDebugType : uint { +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + Unknown = 0, + Coff = 1, + + /// + /// Contains PDB info + /// + CodeView = 2, + + FPO = 3, + Misc = 4, + Exception = 5, + Fixup = 6, + OmapToSrc = 7, + OmapFromSrc = 8, + Borland = 9, + Reserved10 = 10, + CLSID = 11, + VcFeature = 12, + POGO = 13, + ILTCG = 14, + MPX = 15, + + /// + /// It's a deterministic (reproducible) PE file + /// + Repro = 16, + + /// + /// Embedded portable PDB data + /// + EmbeddedPortablePdb = 17, +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member + } +} diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index 495c6b4bf..78478e6d8 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -2,9 +2,10 @@ using System; using System.Collections.Generic; +using System.IO; +using dnlib.IO; using dnlib.Utils; using dnlib.W32Resources; -using dnlib.IO; using dnlib.Threading; namespace dnlib.PE { @@ -98,6 +99,16 @@ public IList ImageSectionHeaders { get { return peInfo.ImageSectionHeaders; } } + /// + public IList ImageDebugDirectories { + get { + if (imageDebugDirectories == null) + imageDebugDirectories = ReadImageDebugDirectories(); + return imageDebugDirectories; + } + } + ImageDebugDirectory[] imageDebugDirectories; + /// public Win32Resources Win32Resources { get { return win32Resources.Value; } @@ -380,5 +391,33 @@ public bool IsMemoryMappedIO { return creator == null ? false : creator.IsMemoryMappedIO; } } + + ImageDebugDirectory[] ReadImageDebugDirectories() { + try { + if (6 >= ImageNTHeaders.OptionalHeader.DataDirectories.Length) + return emptyImageDebugDirectories; + var dataDir = ImageNTHeaders.OptionalHeader.DataDirectories[6]; + if (dataDir.VirtualAddress == 0) + return emptyImageDebugDirectories; + using (var reader = imageStream.Clone()) { + if (dataDir.Size > reader.Length) + return emptyImageDebugDirectories; + int count = (int)(dataDir.Size / 0x1C); + if (count == 0) + return emptyImageDebugDirectories; + reader.Position = (long)ToFileOffset(dataDir.VirtualAddress); + if (reader.Position + dataDir.Size > reader.Length) + return emptyImageDebugDirectories; + var res = new ImageDebugDirectory[count]; + for (int i = 0; i < res.Length; i++) + res[i] = new ImageDebugDirectory(reader, true); + return res; + } + } + catch (IOException) { + } + return emptyImageDebugDirectories; + } + static readonly ImageDebugDirectory[] emptyImageDebugDirectories = new ImageDebugDirectory[0]; } } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 82c7ef700..8984e4a18 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -192,11 +192,16 @@ + + + + + @@ -215,9 +220,9 @@ - + @@ -337,11 +342,14 @@ + + + @@ -370,6 +378,8 @@ + + From 3c3b972c5512151a2568dc9d91a734e906e91a07 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 8 Nov 2017 19:08:33 +0100 Subject: [PATCH 064/511] Update README --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 87fe89edc..68e670243 100644 --- a/README.md +++ b/README.md @@ -116,9 +116,7 @@ default, it will create a PDB file with the same name as the output assembly but with a `.pdb` extension. You can override this by writing the PDB file name to `PdbFileName` or writing your own stream to `PdbStream`. If `PdbStream` is initialized, `PdbFileName` should also be initialized because -the name of the PDB file will be written to the PE file. Another more -advanced property is `CreatePdbSymbolWriter` which returns a `ISymbolWriter2` -instance that dnlib will use. +the name of the PDB file will be written to the PE file. ```csharp var mod = ModuleDefMD.Load(@"C:\myfile.dll"); @@ -129,10 +127,7 @@ instance that dnlib will use. mod.Write(@"C:\out.dll", wopts); ``` -There exist two different types of PDB readers, one is using the Microsoft -COM PDB API available in diasymreader.dll (for Windows only), and the other -one, which is now the default implementation, is a managed PDB reader. The PDB -writer currently only uses the COM PDB API so will only work on Windows. +dnlib supports Windows PDBs, portable PDBs and embedded portable PDBs. Strong name sign an assembly ---------------------------- From ce9dbf12eb7a623a71e7fdda1f8891e3b60dbadf Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 8 Nov 2017 19:09:34 +0100 Subject: [PATCH 065/511] Set new version --- LICENSE.txt | 2 +- src/Properties/AssemblyInfo.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 1d6e3873d..2fa2492de 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,7 +1,7 @@ dnlib: .NET assembly library https://github.com/0xd4d/dnlib -Copyright (C) 2012-2015 de4dot@gmail.com +Copyright (C) 2012-2017 de4dot@gmail.com Contributors ------------ diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index 37a5a2cdb..7d4e3c146 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -12,9 +12,9 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("dnlib")] -[assembly: AssemblyCopyright("Copyright (C) 2012-2015 de4dot@gmail.com")] +[assembly: AssemblyCopyright("Copyright (C) 2012-2017 de4dot@gmail.com")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] -[assembly: AssemblyVersion("1.6.0.0")] -[assembly: AssemblyFileVersion("1.6.0.0")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] From 1fc6dc63d4d8a203d79544a49d6862d83ad20048 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 11 Nov 2017 12:46:19 +0100 Subject: [PATCH 066/511] Updates --- src/DotNet/Pdb/CustomDebugInfoGuids.cs | 2 +- src/DotNet/Pdb/Portable/DocumentNameReader.cs | 32 +++++++++++-------- .../Portable/LocalConstantSigBlobReader.cs | 2 +- .../Pdb/Portable/SymbolReaderCreator.cs | 2 ++ src/DotNet/Pdb/Symbols/SymbolVariable.cs | 1 - src/DotNet/Writer/DebugDirectory.cs | 22 +++++++++---- src/DotNet/Writer/MetaData.cs | 4 +++ src/DotNet/Writer/ModuleWriterBase.cs | 12 +++---- src/DotNet/Writer/PortablePdbConstants.cs | 4 +-- 9 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/DotNet/Pdb/CustomDebugInfoGuids.cs b/src/DotNet/Pdb/CustomDebugInfoGuids.cs index bfa2e3c79..d56cb9641 100644 --- a/src/DotNet/Pdb/CustomDebugInfoGuids.cs +++ b/src/DotNet/Pdb/CustomDebugInfoGuids.cs @@ -10,7 +10,7 @@ public static class CustomDebugInfoGuids { #pragma warning disable 1591 // Missing XML comment for publicly visible type or member // Roslyn: PortableCustomDebugInfoKinds.cs public static readonly Guid AsyncMethodSteppingInformationBlob = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8"); - public static readonly Guid DefaultNamespace = new Guid("58b2eab6-209f-4e4e-a22c-b2d0f910c782"); + public static readonly Guid DefaultNamespace = new Guid("58B2EAB6-209F-4E4E-A22C-B2D0F910C782"); public static readonly Guid DynamicLocalVariables = new Guid("83C563C4-B4F3-47D5-B824-BA5441477EA8"); public static readonly Guid EmbeddedSource = new Guid("0E8A571B-6926-466E-B4AD-8AB04611F5FE"); public static readonly Guid EncLambdaAndClosureMap = new Guid("A643004C-0240-496F-A783-30D64F4979DE"); diff --git a/src/DotNet/Pdb/Portable/DocumentNameReader.cs b/src/DotNet/Pdb/Portable/DocumentNameReader.cs index ec55edc74..bad77acad 100644 --- a/src/DotNet/Pdb/Portable/DocumentNameReader.cs +++ b/src/DotNet/Pdb/Portable/DocumentNameReader.cs @@ -12,7 +12,8 @@ struct DocumentNameReader { readonly BlobStream blobStream; readonly StringBuilder sb; - char prevSepChar; + char[] prevSepChars; + int prevSepCharsLength; byte[] prevSepCharBytes; int prevSepCharBytesCount; @@ -21,7 +22,8 @@ public DocumentNameReader(BlobStream blobStream) { this.blobStream = blobStream; sb = new StringBuilder(); - prevSepChar = '\0'; + prevSepChars = new char[2]; + prevSepCharsLength = 0; prevSepCharBytes = new byte[3]; prevSepCharBytesCount = 0; } @@ -29,12 +31,13 @@ public DocumentNameReader(BlobStream blobStream) { public string ReadDocumentName(uint offset) { sb.Length = 0; using (var stream = blobStream.CreateStream(offset)) { - var sepChar = ReadSeparatorChar(stream); + int sepCharsLength; + var sepChars = ReadSeparatorChar(stream, out sepCharsLength); bool needSep = false; while (stream.Position < stream.Length) { if (needSep) - sb.Append(sepChar); - needSep = sepChar != '\0'; + sb.Append(sepChars, 0, sepCharsLength); + needSep = !(sepCharsLength == 1 && sepChars[0] == '\0'); var part = ReadDocumentNamePart(stream.ReadCompressedUInt32()); sb.Append(part); if (sb.Length > MAX_NAME_LENGTH) { @@ -56,7 +59,7 @@ string ReadDocumentNamePart(uint offset) { return name; } - char ReadSeparatorChar(IImageStream stream) { + char[] ReadSeparatorChar(IImageStream stream, out int charLength) { if (prevSepCharBytesCount != 0 && prevSepCharBytesCount <= stream.Length) { var pos = stream.Position; bool ok = true; @@ -66,14 +69,15 @@ char ReadSeparatorChar(IImageStream stream) { break; } } - if (ok) - return prevSepChar; + if (ok) { + charLength = prevSepCharsLength; + return prevSepChars; + } stream.Position = pos; } var decoder = Encoding.UTF8.GetDecoder(); var bytes = new byte[1]; - var chars = new char[2]; prevSepCharBytesCount = 0; for (int i = 0; ; i++) { byte b = stream.ReadByte(); @@ -84,14 +88,14 @@ char ReadSeparatorChar(IImageStream stream) { prevSepCharBytes[i] = b; bytes[0] = b; bool isLastByte = stream.Position + 1 == stream.Length; - int bytesUsed, charsUsed; + int bytesUsed; bool completed; - decoder.Convert(bytes, 0, 1, chars, 0, 2, isLastByte, out bytesUsed, out charsUsed, out completed); - if (charsUsed > 0) + decoder.Convert(bytes, 0, 1, prevSepChars, 0, prevSepChars.Length, isLastByte, out bytesUsed, out prevSepCharsLength, out completed); + if (prevSepCharsLength > 0) break; } - prevSepChar = chars[0]; - return prevSepChar; + charLength = prevSepCharsLength; + return prevSepChars; } } } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index a77c61b71..53925b102 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -287,7 +287,7 @@ string ReadString() { if (reader.Position == reader.Length) return string.Empty; byte b = reader.ReadByte(); - if (b == 0xFF) + if (b == 0xFF && reader.Position == reader.Length) return null; reader.Position--; return Encoding.Unicode.GetString(reader.ReadRemainingBytes()); diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index 7baba660e..46c1ee14e 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -31,6 +31,8 @@ public static SymbolReader TryCreate(IMetaData metaData) { return null; try { var peImage = metaData.PEImage; + if (peImage == null) + return null; var embeddedDir = TryGetEmbeddedDebugDirectory(peImage); if (embeddedDir == null) return null; diff --git a/src/DotNet/Pdb/Symbols/SymbolVariable.cs b/src/DotNet/Pdb/Symbols/SymbolVariable.cs index d99fa6afd..89818ff5a 100644 --- a/src/DotNet/Pdb/Symbols/SymbolVariable.cs +++ b/src/DotNet/Pdb/Symbols/SymbolVariable.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info - namespace dnlib.DotNet.Pdb.Symbols { /// /// A variable diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index c087e0763..4f2b16acb 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -60,6 +60,15 @@ public DebugDirectory() { entries = new List(); } + /// + /// Adds data + /// + /// Data + /// + public DebugDirectoryEntry Add(byte[] data) { + return Add(new ByteArrayChunk(data)); + } + /// /// Adds data /// @@ -98,13 +107,12 @@ public uint GetVirtualSize() { public void WriteTo(BinaryWriter writer) { uint offset = 0; foreach (var entry in entries) { - var debugDirData = entry.DebugDirectory; - writer.Write(debugDirData.Characteristics); - writer.Write(debugDirData.TimeDateStamp); - writer.Write(debugDirData.MajorVersion); - writer.Write(debugDirData.MinorVersion); - writer.Write((uint)debugDirData.Type); - writer.Write(entry.Chunk.GetVirtualSize()); + writer.Write(entry.DebugDirectory.Characteristics); + writer.Write(entry.DebugDirectory.TimeDateStamp); + writer.Write(entry.DebugDirectory.MajorVersion); + writer.Write(entry.DebugDirectory.MinorVersion); + writer.Write((uint)entry.DebugDirectory.Type); + writer.Write(entry.Chunk.GetFileLength()); writer.Write((uint)entry.Chunk.RVA); writer.Write((uint)entry.Chunk.FileOffset); offset += HEADER_SIZE; diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 21255485f..16fa1c182 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -3137,6 +3137,10 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, MethodDef kickoffMethod) { Debug.Assert(new MDToken(moveNextMethodToken).Table == Table.Method); Debug.Assert(debugMetaData != null); + if (kickoffMethod == null) { + Error("KickoffMethod is null"); + return; + } var row = new RawStateMachineMethodRow(new MDToken(moveNextMethodToken).Rid, GetRid(kickoffMethod)); debugMetaData.stateMachineMethodInfos.Add(cdi, row); } diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 36082b7ff..6a0a09e68 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -698,7 +698,7 @@ void WriteWindowsPdb(PdbState pdbState) { IMAGE_DEBUG_DIRECTORY idd; var data = pdbWriter.GetDebugInfo(out idd); - var entry = debugDirectory.Add(new ByteArrayChunk(data)); + var entry = debugDirectory.Add(data); entry.DebugDirectory = idd; entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); } @@ -787,18 +787,18 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { metaData.WritePortablePdb(pdbStream, entryPointToken, pdbId); const uint age = 1; - var cvEntry = debugDirectory.Add(new ByteArrayChunk(GetCodeViewData(pdbGuid, age, pdbFilename))); + var cvEntry = debugDirectory.Add(GetCodeViewData(pdbGuid, age, pdbFilename)); cvEntry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); - cvEntry.DebugDirectory.MajorVersion = PortablePdbConstants.EmbeddedPortablePdb_FormatVersion; + cvEntry.DebugDirectory.MajorVersion = PortablePdbConstants.FormatVersion; cvEntry.DebugDirectory.MinorVersion = PortablePdbConstants.PortableCodeViewVersionMagic; cvEntry.DebugDirectory.Type = ImageDebugType.CodeView; if (isEmbeddedPortablePdb) { Debug.Assert(embeddedMemoryStream != null); - var embedEntry = debugDirectory.Add(new ByteArrayChunk(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream))); + var embedEntry = debugDirectory.Add(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream)); embedEntry.DebugDirectory.TimeDateStamp = 0; - embedEntry.DebugDirectory.MajorVersion = PortablePdbConstants.EmbeddedPortablePdb_FormatVersion; - embedEntry.DebugDirectory.MinorVersion = PortablePdbConstants.EmbeddedPortablePdb_EmbeddedVersion; + embedEntry.DebugDirectory.MajorVersion = PortablePdbConstants.FormatVersion; + embedEntry.DebugDirectory.MinorVersion = PortablePdbConstants.EmbeddedVersion; embedEntry.DebugDirectory.Type = ImageDebugType.EmbeddedPortablePdb; } } diff --git a/src/DotNet/Writer/PortablePdbConstants.cs b/src/DotNet/Writer/PortablePdbConstants.cs index 7d9043343..4866f90a7 100644 --- a/src/DotNet/Writer/PortablePdbConstants.cs +++ b/src/DotNet/Writer/PortablePdbConstants.cs @@ -7,12 +7,12 @@ static class PortablePdbConstants { // Portable PDB version (v1.0) // Format version is stored in DebugDirectory.MajorVersion // SRM: DefaultFormatVersion, MinFormatVersion - public const ushort EmbeddedPortablePdb_FormatVersion = 0x0100; + public const ushort FormatVersion = 0x0100; // Embedded Portable PDB Blob verison (v1.0) // Embedded version is stored in DebugDirectory.MinorVersion // SRM: MinEmbeddedVersion, DefaultEmbeddedVersion, MinUnsupportedEmbeddedVersion - public const ushort EmbeddedPortablePdb_EmbeddedVersion = 0x0100; + public const ushort EmbeddedVersion = 0x0100; // Stored in DebugDirectory.MinorVersion and indicates that it's a portable PDB file // and not a Windows PDB file From 5e9ccafe9846bb2bd29126780eb75358f848ed5c Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 22 Nov 2017 13:56:59 +0100 Subject: [PATCH 067/511] Read CDIs later --- src/DotNet/MethodDef.cs | 16 ++++++---------- src/DotNet/ModuleDefMD.cs | 21 ++++++++++++++------- src/DotNet/Pdb/PdbState.cs | 24 +++++++++++------------- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index f1e033bd4..9c85b814e 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -1277,11 +1277,7 @@ protected override ImplMap GetImplMap_NoLock() { /// protected override MethodBody GetMethodBody_NoLock() { - var list = ThreadSafeListCreator.Create(); - var body = readerModule.ReadMethodBody(this, origRva, origImplAttributes, list, new GenericParamContext(declaringType2, this)); - Debug.Assert(customDebugInfos == null); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - return body; + return readerModule.ReadMethodBody(this, origRva, origImplAttributes, new GenericParamContext(declaringType2, this)); } /// @@ -1293,11 +1289,11 @@ protected override void InitializeCustomAttributes() { /// protected override void InitializeCustomDebugInfos() { - // The property will initialize CDIs - var body = Body; - Debug.Assert(customDebugInfos != null); - if (customDebugInfos == null) - Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); + var list = ThreadSafeListCreator.Create(); + if (Interlocked.CompareExchange(ref customDebugInfos, list, null) == null) { + var body = Body; + readerModule.InitializeCustomDebugInfos(this, body, list); + } } /// diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 406f706c5..04af96a0c 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1855,16 +1855,15 @@ internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid, GenericPa /// Method /// Method RVA /// Method impl attrs - /// Updated with custom debug infos /// Generic parameter context /// A or null if none - internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, IList customDebugInfos, GenericParamContext gpContext) { + internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, GenericParamContext gpContext) { MethodBody mb; var mDec = methodDecrypter; if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out mb)) { var cilBody = mb as CilBody; if (cilBody != null) - return InitializeBodyFromPdb(method, cilBody, customDebugInfos); + return InitializeBodyFromPdb(method, cilBody); return mb; } @@ -1872,7 +1871,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib return null; var codeType = implAttrs & MethodImplAttributes.CodeTypeMask; if (codeType == MethodImplAttributes.IL) - return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext), customDebugInfos); + return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext)); if (codeType == MethodImplAttributes.Native) return new NativeMethodBody(rva); return null; @@ -1883,15 +1882,23 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// /// Owner method /// Method body - /// Updated with custom debug infos /// Returns originak value - CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body, IList customDebugInfos) { + CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body) { var ps = pdbState; if (ps != null) - ps.InitializeMethodBody(this, method, body, customDebugInfos); + ps.InitializeMethodBody(this, method, body); return body; } + internal void InitializeCustomDebugInfos(MethodDefMD method, CilBody body, IList customDebugInfos) { + if (body == null) + return; + + var ps = pdbState; + if (ps != null) + ps.InitializeCustomDebugInfos(method, body, customDebugInfos); + } + /// /// Reads a string from the #US heap /// diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 0324195cf..8b57fc2ca 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -188,28 +188,26 @@ internal Compiler Compiler { get { return compiler; } } - internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, IList customDebugInfos) { + internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { if (reader == null) return; - SymbolMethod method; -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - method = reader.GetMethod(ownerMethod, 1); + var method = reader.GetMethod(ownerMethod, 1); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); - - // Read the custom debug info last so eg. local names have been initialized - method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); - body.PdbMethod = pdbMethod; } -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif + } + + internal void InitializeCustomDebugInfos(MethodDef ownerMethod, CilBody body, IList customDebugInfos) { + if (reader == null) + return; + + var method = reader.GetMethod(ownerMethod, 1); + if (method != null) + method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); } static Compiler CalculateCompiler(ModuleDef module) { From 6a63fff7e8f9044b183d3406ee7b03b21d064de0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 25 Nov 2017 18:23:40 +0100 Subject: [PATCH 068/511] Trim path strings --- src/DotNet/AssemblyResolver.cs | 6 ++++-- src/DotNet/Writer/MetaData.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 70fa48bfa..9cbd81a77 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -90,7 +90,8 @@ static AssemblyResolver() { var paths = Environment.GetEnvironmentVariable("MONO_PATH"); if (paths != null) { - foreach (var path in paths.Split(Path.PathSeparator)) { + foreach (var tmp in paths.Split(Path.PathSeparator)) { + var path = tmp.Trim(); if (path != string.Empty && Directory.Exists(path)) extraMonoPathsList.Add(path); } @@ -133,7 +134,8 @@ static IEnumerable FindMonoPrefixes() { var prefixes = Environment.GetEnvironmentVariable("MONO_GAC_PREFIX"); if (!string.IsNullOrEmpty(prefixes)) { - foreach (var prefix in prefixes.Split(Path.PathSeparator)) { + foreach (var tmp in prefixes.Split(Path.PathSeparator)) { + var prefix = tmp.Trim(); if (prefix != string.Empty) yield return prefix; } diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 16fa1c182..527b4e796 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -2359,7 +2359,7 @@ protected void AddGenericParamConstraints(uint gpRid, IList /// New rid of owner generic param - /// Generic paramter constraint + /// Generic parameter constraint protected void AddGenericParamConstraint(uint gpRid, GenericParamConstraint gpc) { if (gpc == null) { Error("GenericParamConstraint is null"); From 4ec592473551b89faf95db7ecbde5366f6462a7a Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 6 Dec 2017 17:18:52 +0100 Subject: [PATCH 069/511] Fix name --- src/PE/PEInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PE/PEInfo.cs b/src/PE/PEInfo.cs index 9271f79c1..c209f3f27 100644 --- a/src/PE/PEInfo.cs +++ b/src/PE/PEInfo.cs @@ -106,7 +106,7 @@ public FileOffset ToFileOffset(RVA rva) { return (FileOffset)rva; } - static ulong alignUp(ulong val, uint alignment) { + static ulong AlignUp(ulong val, uint alignment) { return (val + alignment - 1) & ~(ulong)(alignment - 1); } @@ -118,9 +118,9 @@ static ulong alignUp(ulong val, uint alignment) { public long GetImageSize() { var optHdr = ImageNTHeaders.OptionalHeader; uint alignment = optHdr.SectionAlignment; - ulong len = alignUp(optHdr.SizeOfHeaders, alignment); + ulong len = AlignUp(optHdr.SizeOfHeaders, alignment); foreach (var section in imageSectionHeaders) { - ulong len2 = alignUp((ulong)section.VirtualAddress + Math.Max(section.VirtualSize, section.SizeOfRawData), alignment); + ulong len2 = AlignUp((ulong)section.VirtualAddress + Math.Max(section.VirtualSize, section.SizeOfRawData), alignment); if (len2 > len) len = len2; } From f94ce8b43a8ee98f88017f2fc2a52c711ada7526 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 29 Dec 2017 07:18:41 +0100 Subject: [PATCH 070/511] Update corlib detection code --- src/DotNet/ICodedToken.cs | 1 + src/DotNet/ModuleDefMD.cs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index b45da7f0f..ff463fc64 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -183,6 +183,7 @@ public static bool IsCorLib(this IAssembly asm) { asmName.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) || // This name could change but since CoreCLR is used a lot, it's worth supporting asmName.Equals("System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) || + asmName.Equals("netstandard", StringComparison.OrdinalIgnoreCase) || asmName.Equals("corefx", StringComparison.OrdinalIgnoreCase)); } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 04af96a0c..372dc7d12 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -642,6 +642,16 @@ AssemblyRef FindCorLibAssemblyRef() { if (corLibAsmRef != null) return corLibAsmRef; + for (uint i = 1; i <= numAsmRefs; i++) { + var asmRef = ResolveAssemblyRef(i); + if (!UTF8String.ToSystemStringOrEmpty(asmRef.Name).Equals("netstandard", StringComparison.OrdinalIgnoreCase)) + continue; + if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) + corLibAsmRef = asmRef; + } + if (corLibAsmRef != null) + return corLibAsmRef; + for (uint i = 1; i <= numAsmRefs; i++) { var asmRef = ResolveAssemblyRef(i); if (!UTF8String.ToSystemStringOrEmpty(asmRef.Name).Equals("mscorlib", StringComparison.OrdinalIgnoreCase)) From 953fa8c5a30f89f1cd1b221010e64749de15c3d0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 6 Feb 2018 21:35:12 +0100 Subject: [PATCH 071/511] Update copyright years --- LICENSE.txt | 2 +- src/Properties/AssemblyInfo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 2fa2492de..76a568767 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,7 +1,7 @@ dnlib: .NET assembly library https://github.com/0xd4d/dnlib -Copyright (C) 2012-2017 de4dot@gmail.com +Copyright (C) 2012-2018 de4dot@gmail.com Contributors ------------ diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index 7d4e3c146..e191df5c8 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("dnlib")] -[assembly: AssemblyCopyright("Copyright (C) 2012-2017 de4dot@gmail.com")] +[assembly: AssemblyCopyright("Copyright (C) 2012-2018 de4dot@gmail.com")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] From 0ee5d4f4e2d88e60af55b02cee202e9d087f4c66 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 8 Feb 2018 21:42:26 +0100 Subject: [PATCH 072/511] Update XML doc --- src/DotNet/ModuleCreationOptions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 2851f6b20..a827b2347 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -36,7 +36,8 @@ public sealed class ModuleCreationOptions { public object PdbFileOrData { get; set; } /// - /// If true, will load the PDB file from disk if present. The default value is true. + /// If true, will load the PDB file from disk if present, or an embedded portable PDB file + /// stored in the PE file. The default value is true. /// You don't need to initialize or . /// public bool TryToLoadPdbFromDisk { get; set; } From 7a4944d83f313de6aa1577e4dcd8ac986802f99b Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 9 Feb 2018 21:01:58 +0100 Subject: [PATCH 073/511] Add check for new embedded portable PDB data --- src/DotNet/Pdb/Portable/SymbolReaderCreator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index 46c1ee14e..a2616fbcb 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System.Diagnostics; using System.IO; using System.IO.Compression; using dnlib.DotNet.MD; @@ -41,7 +42,11 @@ public static SymbolReader TryCreate(IMetaData metaData) { if (reader.ReadUInt32() != 0x4244504D) return null; uint uncompressedSize = reader.ReadUInt32(); - if (uncompressedSize > int.MaxValue) + // If this fails, see the (hopefully) updated spec: + // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#embedded-portable-pdb-debug-directory-entry-type-17 + bool newVersion = (uncompressedSize & 0x80000000) != 0; + Debug.Assert(!newVersion); + if (newVersion) return null; var decompressedBytes = new byte[uncompressedSize]; using (var deflateStream = new DeflateStream(new MemoryStream(reader.ReadRemainingBytes()), CompressionMode.Decompress)) { From 396fc667fcaa385567158adb6ceea270702718fa Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 12 Feb 2018 18:03:20 +0100 Subject: [PATCH 074/511] Make DotNetTableSizes public --- src/DotNet/MD/DotNetTableSizes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index 60a7fecdb..2845ca8fb 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet.MD { /// /// Initializes .NET table row sizes /// - sealed class DotNetTableSizes { + public sealed class DotNetTableSizes { bool bigStrings; bool bigGuid; bool bigBlob; From c128ad2046540af20416a0921cadca300df1966f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=87=E7=85=8C?= Date: Wed, 14 Feb 2018 14:24:57 +0800 Subject: [PATCH 075/511] Auto switch ComImageFlags.NativeEntryPoint (#154) --- .gitignore | 1 + src/DotNet/ModuleDef.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 85f65d4d2..d1f665933 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.sdf *.opensdf *.suo +/.vs/ /Debug/ /Release/ /Examples/bin/ diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 5bd91295a..8e4853e9b 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -254,6 +254,7 @@ public RVA NativeEntryPoint { #endif nativeEntryPoint = value; managedEntryPoint = null; + Cor20HeaderFlags |= ComImageFlags.NativeEntryPoint; nativeAndManagedEntryPoint_initialized = true; #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } @@ -276,6 +277,7 @@ public IManagedEntryPoint ManagedEntryPoint { #endif nativeEntryPoint = 0; managedEntryPoint = value; + Cor20HeaderFlags &= ~ComImageFlags.NativeEntryPoint; nativeAndManagedEntryPoint_initialized = true; #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } From 4d1ce1015b091012f1094b7409294311442d57e1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Feb 2018 06:58:54 +0100 Subject: [PATCH 076/511] Add more FindPropertyCheckBaseType() overloads --- src/DotNet/TypeDef.cs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 6c527e0c8..a29abece2 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -1649,10 +1649,33 @@ public EventDef FindEventCheckBaseType(UTF8String name) { /// Property name /// Property signature /// The property or null if it wasn't found - public PropertyDef FindPropertyCheckBaseType(UTF8String name, FieldSig sig) { + public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig) { + return FindPropertyCheckBaseType(name, sig, 0, null); + } + + /// + /// Finds a property by checking this type or any of its base types + /// + /// Property name + /// Property signature + /// Property signature comparison options + /// The property or null if it wasn't found + public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, SigComparerOptions options) { + return FindPropertyCheckBaseType(name, sig, options, null); + } + + /// + /// Finds a property by checking this type or any of its base types + /// + /// Property name + /// Property signature + /// Property signature comparison options + /// The module that needs to find the property or null + /// The property or null if it wasn't found + public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; while (td != null) { - var pd = td.FindProperty(name, sig); + var pd = td.FindProperty(name, sig, options, sourceModule); if (pd != null) return pd; td = td.BaseType.ResolveTypeDef(); From 68a715c1d9b27f06ad4b5b26777c376020cc88be Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Feb 2018 06:59:06 +0100 Subject: [PATCH 077/511] Reuse more PE header values by default when writing the file --- src/DotNet/Writer/ModuleWriterBase.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 6a0a09e68..c83b308d8 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -272,6 +272,13 @@ protected ModuleWriterOptionsBase(ModuleDef module, IModuleWriterListener listen PEHeadersOptions.MajorLinkerVersion = ntHeaders.OptionalHeader.MajorLinkerVersion; PEHeadersOptions.MinorLinkerVersion = ntHeaders.OptionalHeader.MinorLinkerVersion; PEHeadersOptions.ImageBase = ntHeaders.OptionalHeader.ImageBase; + PEHeadersOptions.MajorOperatingSystemVersion = ntHeaders.OptionalHeader.MajorOperatingSystemVersion; + PEHeadersOptions.MinorOperatingSystemVersion = ntHeaders.OptionalHeader.MinorOperatingSystemVersion; + PEHeadersOptions.MajorImageVersion = ntHeaders.OptionalHeader.MajorImageVersion; + PEHeadersOptions.MinorImageVersion = ntHeaders.OptionalHeader.MinorImageVersion; + PEHeadersOptions.MajorSubsystemVersion = ntHeaders.OptionalHeader.MajorSubsystemVersion; + PEHeadersOptions.MinorSubsystemVersion = ntHeaders.OptionalHeader.MinorSubsystemVersion; + PEHeadersOptions.Win32VersionValue = ntHeaders.OptionalHeader.Win32VersionValue; AddCheckSum = ntHeaders.OptionalHeader.CheckSum != 0; } @@ -279,7 +286,7 @@ protected ModuleWriterOptionsBase(ModuleDef module, IModuleWriterListener listen PEHeadersOptions.Characteristics &= ~Characteristics._32BitMachine; PEHeadersOptions.Characteristics |= Characteristics.LargeAddressAware; } - else + else if (modDefMD == null) PEHeadersOptions.Characteristics |= Characteristics._32BitMachine; } From 451227c31dffc34cd0b135a754579f544064367f Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Feb 2018 06:59:15 +0100 Subject: [PATCH 078/511] Optimize #Strings stream, fixes #129 --- src/DotNet/Writer/HotHeap.cs | 45 ++- src/DotNet/Writer/HotPool.cs | 2 +- src/DotNet/Writer/HotTable.cs | 23 +- src/DotNet/Writer/MDTableWriter.cs | 462 +++++++++++++++++++++-------- src/DotNet/Writer/MetaData.cs | 5 +- src/DotNet/Writer/StringsHeap.cs | 110 ++++++- src/DotNet/Writer/TablesHeap.cs | 118 ++++---- 7 files changed, 552 insertions(+), 213 deletions(-) diff --git a/src/DotNet/Writer/HotHeap.cs b/src/DotNet/Writer/HotHeap.cs index be4a0f8d9..67c44b366 100644 --- a/src/DotNet/Writer/HotHeap.cs +++ b/src/DotNet/Writer/HotHeap.cs @@ -15,12 +15,13 @@ namespace dnlib.DotNet.Writer { /// It's only used by the CLR when the compressed heap (#~) is present, not when /// the ENC heap (#-) is present. /// - public abstract class HotHeap : HeapBase { + abstract class HotHeap : HeapBase { const uint HOT_HEAP_MAGIC = 0x484F4E44; // "HOND" const int MAX_TABLES = (int)Table.GenericParamConstraint + 1; const uint HOT_HEAP_DIR_SIZE = 4 + MAX_TABLES * 4; const uint HH_ALIGNMENT = 4; + protected readonly MetaData metadata; uint totalLength; readonly HotTable[] headers = new HotTable[MAX_TABLES]; readonly List hotPools = new List(); @@ -35,6 +36,14 @@ public override string Name { get { return "#!"; } } + /// + /// Constructor + /// + /// Metadata owner + protected HotHeap(MetaData metadata) { + this.metadata = metadata; + } + /// /// Creates a instance /// @@ -50,19 +59,21 @@ public override string Name { /// /// Creates a hot heap instance /// + /// Metadata owner /// Target module - public static HotHeap Create(ModuleDef module) { - return Create(GetHotHeapVersion(module)); + public static HotHeap Create(MetaData metadata, ModuleDef module) { + return Create(metadata, GetHotHeapVersion(module)); } /// /// Creates a hot heap instance /// + /// Metadata owner /// Hot heap version - public static HotHeap Create(HotHeapVersion version) { + public static HotHeap Create(MetaData metadata, HotHeapVersion version) { switch (version) { - case HotHeapVersion.CLR20: return new HotHeap20(); - case HotHeapVersion.CLR40: return new HotHeap40(); + case HotHeapVersion.CLR20: return new HotHeap20(metadata); + case HotHeapVersion.CLR40: return new HotHeap40(metadata); default: throw new ArgumentException("Invalid version"); } } @@ -204,15 +215,22 @@ static void WriteAlign(BinaryWriter writer, ref uint offs) { /// /// CLR 2.0 (.NET 2.0 - 3.5) hot heap (#!) /// - public sealed class HotHeap20 : HotHeap { + sealed class HotHeap20 : HotHeap { /// public override HotHeapVersion HotHeapVersion { get { return HotHeapVersion.CLR20; } } + /// + /// Constructor + /// + /// Metadata owner + public HotHeap20(MetaData metadata) : base(metadata) { + } + /// public override HotTable CreateHotTable(IMDTable mdTable) { - return new HotTable20(mdTable); + return new HotTable20(metadata, mdTable); } /// @@ -224,15 +242,22 @@ public override HotPool CreateHotPool(HeapType heapType) { /// /// CLR 4.0 (.NET 4.0 - 4.5) hot heap (#!) /// - public sealed class HotHeap40 : HotHeap { + sealed class HotHeap40 : HotHeap { /// public override HotHeapVersion HotHeapVersion { get { return HotHeapVersion.CLR40; } } + /// + /// Constructor + /// + /// Metadata owner + public HotHeap40(MetaData metadata) : base(metadata) { + } + /// public override HotTable CreateHotTable(IMDTable mdTable) { - return new HotTable40(mdTable); + return new HotTable40(metadata, mdTable); } /// diff --git a/src/DotNet/Writer/HotPool.cs b/src/DotNet/Writer/HotPool.cs index d629c51a9..0b36b7c7e 100644 --- a/src/DotNet/Writer/HotPool.cs +++ b/src/DotNet/Writer/HotPool.cs @@ -11,7 +11,7 @@ namespace dnlib.DotNet.Writer { /// /// Hot pool /// - public abstract class HotPool : IChunk { + abstract class HotPool : IChunk { internal const uint HP_ALIGNMENT = 4; FileOffset offset; RVA rva; diff --git a/src/DotNet/Writer/HotTable.cs b/src/DotNet/Writer/HotTable.cs index 4a5fbe77a..caefea991 100644 --- a/src/DotNet/Writer/HotTable.cs +++ b/src/DotNet/Writer/HotTable.cs @@ -23,6 +23,7 @@ public abstract class HotTable : IChunk { FileOffset offset; RVA rva; + readonly MetaData metadata; internal readonly IMDTable mdTable; readonly HotHeapVersion version; readonly int hotTableHeaderSize; @@ -70,9 +71,11 @@ public Table Table { /// /// Constructor /// + /// Metadata owner /// Hot heap version /// The MD table - internal HotTable(HotHeapVersion version, IMDTable mdTable) { + internal HotTable(MetaData metadata, HotHeapVersion version, IMDTable mdTable) { + this.metadata = metadata; this.mdTable = mdTable; this.version = version; @@ -172,7 +175,7 @@ public void CreateFullData() { data = new byte[FullTableSize]; var writer = new BinaryWriter(new MemoryStream(data)); - writer.Write(mdTable); + writer.Write(metadata, mdTable); if (writer.BaseStream.Position != data.Length) throw new InvalidOperationException("Didn't write all MD table data"); } @@ -195,7 +198,7 @@ public void CreatePartialData() { foreach (var rid in rids) { memStream.Position = 0; var row = mdTable.Get(rid); - writer.Write(mdTable, row); + writer.Write(metadata, mdTable, row); partialData[rid] = memStream.ToArray(); } } @@ -335,13 +338,14 @@ internal void WriteSecondLevelTable(BinaryWriter writer) { /// /// CLR 2.0 (.NET 2.0 - 3.5) hot table /// - public sealed class HotTable20 : HotTable { + sealed class HotTable20 : HotTable { /// /// Constructor /// + /// Metadata owner /// The MD table - public HotTable20(IMDTable mdTable) - : base(HotHeapVersion.CLR20, mdTable) { + public HotTable20(MetaData metadata, IMDTable mdTable) + : base(metadata, HotHeapVersion.CLR20, mdTable) { } /// @@ -400,15 +404,16 @@ internal override void PartialWriteTo(BinaryWriter writer) { /// /// CLR 4.0 (.NET 4.0 - 4.5) partial hot table /// - public sealed class HotTable40 : HotTable { + sealed class HotTable40 : HotTable { uint indexesOffset; /// /// Constructor /// + /// Metadata owner /// The MD table - public HotTable40(IMDTable mdTable) - : base(HotHeapVersion.CLR40, mdTable) { + public HotTable40(MetaData metadata, IMDTable mdTable) + : base(metadata, HotHeapVersion.CLR40, mdTable) { } /// diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index 755e7434c..fd1755309 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System.Diagnostics; using System.IO; using dnlib.DotNet.MD; @@ -12,9 +13,10 @@ public static class MDTableWriter { /// Writes a raw row /// /// Writer + /// Metadata /// Table /// Row - public static void Write(this BinaryWriter writer, IMDTable table, IRawRow row) { + public static void Write(this BinaryWriter writer, MetaData metadata, IMDTable table, IRawRow row) { if (table.Table == Table.Constant) { var cols = table.TableInfo.Columns; var row2 = (RawConstantRow)row; @@ -25,8 +27,13 @@ public static void Write(this BinaryWriter writer, IMDTable table, IRawRow row) } else { var cols = table.TableInfo.Columns; - foreach (var col in cols) - col.Write(writer, row.Read(col.Index)); + var stringsHeap = metadata.StringsHeap; + foreach (var col in cols) { + if (col.ColumnSize == ColumnSize.Strings) + col.Write(writer, stringsHeap.GetOffset(row.Read(col.Index))); + else + col.Write(writer, row.Read(col.Index)); + } } } @@ -34,60 +41,75 @@ public static void Write(this BinaryWriter writer, IMDTable table, IRawRow row) /// Writes a metadata table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, IMDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, IMDTable table) { switch (table.Table) { - case Table.Module: writer.Write((MDTable)table); break; - case Table.TypeRef: writer.Write((MDTable)table); break; - case Table.TypeDef: writer.Write((MDTable)table); break; - case Table.FieldPtr: writer.Write((MDTable)table); break; - case Table.Field: writer.Write((MDTable)table); break; - case Table.MethodPtr: writer.Write((MDTable)table); break; - case Table.Method: writer.Write((MDTable)table); break; - case Table.ParamPtr: writer.Write((MDTable)table); break; - case Table.Param: writer.Write((MDTable)table); break; - case Table.InterfaceImpl: writer.Write((MDTable)table); break; - case Table.MemberRef: writer.Write((MDTable)table); break; - case Table.Constant: writer.Write((MDTable)table); break; - case Table.CustomAttribute: writer.Write((MDTable)table); break; - case Table.FieldMarshal: writer.Write((MDTable)table); break; - case Table.DeclSecurity: writer.Write((MDTable)table); break; - case Table.ClassLayout: writer.Write((MDTable)table); break; - case Table.FieldLayout: writer.Write((MDTable)table); break; - case Table.StandAloneSig: writer.Write((MDTable)table); break; - case Table.EventMap: writer.Write((MDTable)table); break; - case Table.EventPtr: writer.Write((MDTable)table); break; - case Table.Event: writer.Write((MDTable)table); break; - case Table.PropertyMap: writer.Write((MDTable)table); break; - case Table.PropertyPtr: writer.Write((MDTable)table); break; - case Table.Property: writer.Write((MDTable)table); break; - case Table.MethodSemantics: writer.Write((MDTable)table); break; - case Table.MethodImpl: writer.Write((MDTable)table); break; - case Table.ModuleRef: writer.Write((MDTable)table); break; - case Table.TypeSpec: writer.Write((MDTable)table); break; - case Table.ImplMap: writer.Write((MDTable)table); break; - case Table.FieldRVA: writer.Write((MDTable)table); break; - case Table.ENCLog: writer.Write((MDTable)table); break; - case Table.ENCMap: writer.Write((MDTable)table); break; - case Table.Assembly: writer.Write((MDTable)table); break; - case Table.AssemblyProcessor: writer.Write((MDTable)table); break; - case Table.AssemblyOS: writer.Write((MDTable)table); break; - case Table.AssemblyRef: writer.Write((MDTable)table); break; - case Table.AssemblyRefProcessor: writer.Write((MDTable)table); break; - case Table.AssemblyRefOS: writer.Write((MDTable)table); break; - case Table.File: writer.Write((MDTable)table); break; - case Table.ExportedType: writer.Write((MDTable)table); break; - case Table.ManifestResource:writer.Write((MDTable)table); break; - case Table.NestedClass: writer.Write((MDTable)table); break; - case Table.GenericParam: writer.Write((MDTable)table); break; - case Table.MethodSpec: writer.Write((MDTable)table); break; - case Table.GenericParamConstraint: writer.Write((MDTable)table); break; + case Table.Module: writer.Write(metadata, (MDTable)table); break; + case Table.TypeRef: writer.Write(metadata, (MDTable)table); break; + case Table.TypeDef: writer.Write(metadata, (MDTable)table); break; + case Table.FieldPtr: writer.Write(metadata, (MDTable)table); break; + case Table.Field: writer.Write(metadata, (MDTable)table); break; + case Table.MethodPtr: writer.Write(metadata, (MDTable)table); break; + case Table.Method: writer.Write(metadata, (MDTable)table); break; + case Table.ParamPtr: writer.Write(metadata, (MDTable)table); break; + case Table.Param: writer.Write(metadata, (MDTable)table); break; + case Table.InterfaceImpl: writer.Write(metadata, (MDTable)table); break; + case Table.MemberRef: writer.Write(metadata, (MDTable)table); break; + case Table.Constant: writer.Write(metadata, (MDTable)table); break; + case Table.CustomAttribute: writer.Write(metadata, (MDTable)table); break; + case Table.FieldMarshal: writer.Write(metadata, (MDTable)table); break; + case Table.DeclSecurity: writer.Write(metadata, (MDTable)table); break; + case Table.ClassLayout: writer.Write(metadata, (MDTable)table); break; + case Table.FieldLayout: writer.Write(metadata, (MDTable)table); break; + case Table.StandAloneSig: writer.Write(metadata, (MDTable)table); break; + case Table.EventMap: writer.Write(metadata, (MDTable)table); break; + case Table.EventPtr: writer.Write(metadata, (MDTable)table); break; + case Table.Event: writer.Write(metadata, (MDTable)table); break; + case Table.PropertyMap: writer.Write(metadata, (MDTable)table); break; + case Table.PropertyPtr: writer.Write(metadata, (MDTable)table); break; + case Table.Property: writer.Write(metadata, (MDTable)table); break; + case Table.MethodSemantics: writer.Write(metadata, (MDTable)table); break; + case Table.MethodImpl: writer.Write(metadata, (MDTable)table); break; + case Table.ModuleRef: writer.Write(metadata, (MDTable)table); break; + case Table.TypeSpec: writer.Write(metadata, (MDTable)table); break; + case Table.ImplMap: writer.Write(metadata, (MDTable)table); break; + case Table.FieldRVA: writer.Write(metadata, (MDTable)table); break; + case Table.ENCLog: writer.Write(metadata, (MDTable)table); break; + case Table.ENCMap: writer.Write(metadata, (MDTable)table); break; + case Table.Assembly: writer.Write(metadata, (MDTable)table); break; + case Table.AssemblyProcessor: writer.Write(metadata, (MDTable)table); break; + case Table.AssemblyOS: writer.Write(metadata, (MDTable)table); break; + case Table.AssemblyRef: writer.Write(metadata, (MDTable)table); break; + case Table.AssemblyRefProcessor: writer.Write(metadata, (MDTable)table); break; + case Table.AssemblyRefOS: writer.Write(metadata, (MDTable)table); break; + case Table.File: writer.Write(metadata, (MDTable)table); break; + case Table.ExportedType: writer.Write(metadata, (MDTable)table); break; + case Table.ManifestResource:writer.Write(metadata, (MDTable)table); break; + case Table.NestedClass: writer.Write(metadata, (MDTable)table); break; + case Table.GenericParam: writer.Write(metadata, (MDTable)table); break; + case Table.MethodSpec: writer.Write(metadata, (MDTable)table); break; + case Table.GenericParamConstraint: writer.Write(metadata, (MDTable)table); break; + case Table.Document: writer.Write(metadata, (MDTable)table); break; + case Table.MethodDebugInformation: writer.Write(metadata, (MDTable)table); break; + case Table.LocalScope: writer.Write(metadata, (MDTable)table); break; + case Table.LocalVariable: writer.Write(metadata, (MDTable)table); break; + case Table.LocalConstant: writer.Write(metadata, (MDTable)table); break; + case Table.ImportScope: writer.Write(metadata, (MDTable)table); break; + case Table.StateMachineMethod: writer.Write(metadata, (MDTable)table); break; + case Table.CustomDebugInformation: writer.Write(metadata, (MDTable)table); break; default: + Debug.Fail(string.Format("Unknown table: {0}, add a new method overload", table.Table)); var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table.GetRawRows()) { - foreach (var col in cols) - col.Write(writer, row.Read(col.Index)); + foreach (var col in cols) { + if (col.ColumnSize == ColumnSize.Strings) + col.Write(writer, stringsHeap.GetOffset(row.Read(col.Index))); + else + col.Write(writer, row.Read(col.Index)); + } } break; } @@ -97,12 +119,14 @@ public static void Write(this BinaryWriter writer, IMDTable table) { /// Writes a Module table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Generation); - cols[1].Write(writer, row.Name); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); cols[2].Write(writer, row.Mvid); cols[3].Write(writer, row.EncId); cols[4].Write(writer, row.EncBaseId); @@ -113,13 +137,15 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a TypeRef table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { cols[0].Write(writer, row.ResolutionScope); - cols[1].Write(writer, row.Name); - cols[2].Write(writer, row.Namespace); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); + cols[2].Write(writer, stringsHeap.GetOffset(row.Namespace)); } } @@ -127,13 +153,15 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a TypeDef table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Flags); - cols[1].Write(writer, row.Name); - cols[2].Write(writer, row.Namespace); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); + cols[2].Write(writer, stringsHeap.GetOffset(row.Namespace)); cols[3].Write(writer, row.Extends); cols[4].Write(writer, row.FieldList); cols[5].Write(writer, row.MethodList); @@ -144,8 +172,9 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a FieldPtr table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Field); @@ -155,12 +184,14 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a Field table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Flags); - cols[1].Write(writer, row.Name); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); cols[2].Write(writer, row.Signature); } } @@ -169,8 +200,9 @@ public static void Write(this BinaryWriter writer, MDTable table) { /// Writes a MethodPtr table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Method); @@ -180,14 +212,16 @@ public static void Write(this BinaryWriter writer, MDTable tabl /// Writes a Method table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.RVA); writer.Write(row.ImplFlags); writer.Write(row.Flags); - cols[3].Write(writer, row.Name); + cols[3].Write(writer, stringsHeap.GetOffset(row.Name)); cols[4].Write(writer, row.Signature); cols[5].Write(writer, row.ParamList); } @@ -197,8 +231,9 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a ParamPtr table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Param); @@ -208,13 +243,15 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a Param table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Flags); writer.Write(row.Sequence); - cols[2].Write(writer, row.Name); + cols[2].Write(writer, stringsHeap.GetOffset(row.Name)); } } @@ -222,8 +259,9 @@ public static void Write(this BinaryWriter writer, MDTable table) { /// Writes a InterfaceImpl table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Class); @@ -235,12 +273,14 @@ public static void Write(this BinaryWriter writer, MDTable /// Writes a MemberRef table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { cols[0].Write(writer, row.Class); - cols[1].Write(writer, row.Name); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); cols[2].Write(writer, row.Signature); } } @@ -249,8 +289,9 @@ public static void Write(this BinaryWriter writer, MDTable tabl /// Writes a Constant table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.Type); @@ -264,8 +305,9 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a CustomAttribute table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Parent); @@ -278,8 +320,9 @@ public static void Write(this BinaryWriter writer, MDTableFieldMarshal table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Parent); @@ -291,8 +334,9 @@ public static void Write(this BinaryWriter writer, MDTable t /// Writes a DeclSecurity table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.Action); @@ -305,8 +349,9 @@ public static void Write(this BinaryWriter writer, MDTable t /// Writes a ClassLayout table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.PackingSize); @@ -319,8 +364,9 @@ public static void Write(this BinaryWriter writer, MDTable ta /// Writes a FieldLayout table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.OffSet); @@ -332,8 +378,9 @@ public static void Write(this BinaryWriter writer, MDTable ta /// Writes a StandAloneSig table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Signature); @@ -343,8 +390,9 @@ public static void Write(this BinaryWriter writer, MDTable /// Writes a EventMap table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Parent); @@ -356,8 +404,9 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a EventPtr table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Event); @@ -367,12 +416,14 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a Event table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.EventFlags); - cols[1].Write(writer, row.Name); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); cols[2].Write(writer, row.EventType); } } @@ -381,8 +432,9 @@ public static void Write(this BinaryWriter writer, MDTable table) { /// Writes a PropertyMap table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Parent); @@ -394,8 +446,9 @@ public static void Write(this BinaryWriter writer, MDTable ta /// Writes a PropertyPtr table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Property); @@ -405,12 +458,14 @@ public static void Write(this BinaryWriter writer, MDTable ta /// Writes a Property table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.PropFlags); - cols[1].Write(writer, row.Name); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); cols[2].Write(writer, row.Type); } } @@ -419,8 +474,9 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a MethodSemantics table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.Semantic); @@ -433,8 +489,9 @@ public static void Write(this BinaryWriter writer, MDTableMethodImpl table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Class); @@ -447,19 +504,22 @@ public static void Write(this BinaryWriter writer, MDTable tab /// Writes a ModuleRef table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) - cols[0].Write(writer, row.Name); + cols[0].Write(writer, stringsHeap.GetOffset(row.Name)); } /// /// Writes a TypeSpec table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) cols[0].Write(writer, row.Signature); @@ -469,13 +529,15 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a ImplMap table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.MappingFlags); cols[1].Write(writer, row.MemberForwarded); - cols[2].Write(writer, row.ImportName); + cols[2].Write(writer, stringsHeap.GetOffset(row.ImportName)); cols[3].Write(writer, row.ImportScope); } } @@ -484,8 +546,9 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a FieldRVA table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.RVA); @@ -497,8 +560,9 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a ENCLog table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { foreach (var row in table) { writer.Write(row.Token); writer.Write(row.FuncCode); @@ -509,8 +573,9 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a ENCMap table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { foreach (var row in table) writer.Write(row.Token); } @@ -519,9 +584,11 @@ public static void Write(this BinaryWriter writer, MDTable table) /// Writes a Assembly table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.HashAlgId); writer.Write(row.MajorVersion); @@ -530,8 +597,8 @@ public static void Write(this BinaryWriter writer, MDTable table writer.Write(row.RevisionNumber); writer.Write(row.Flags); cols[6].Write(writer, row.PublicKey); - cols[7].Write(writer, row.Name); - cols[8].Write(writer, row.Locale); + cols[7].Write(writer, stringsHeap.GetOffset(row.Name)); + cols[8].Write(writer, stringsHeap.GetOffset(row.Locale)); } } @@ -539,8 +606,9 @@ public static void Write(this BinaryWriter writer, MDTable table /// Writes a AssemblyProcessor table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { foreach (var row in table) writer.Write(row.Processor); } @@ -549,8 +617,9 @@ public static void Write(this BinaryWriter writer, MDTableAssemblyOS table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { foreach (var row in table) { writer.Write(row.OSPlatformId); writer.Write(row.OSMajorVersion); @@ -562,9 +631,11 @@ public static void Write(this BinaryWriter writer, MDTable tab /// Writes a AssemblyRef table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.MajorVersion); writer.Write(row.MinorVersion); @@ -572,8 +643,8 @@ public static void Write(this BinaryWriter writer, MDTable ta writer.Write(row.RevisionNumber); writer.Write(row.Flags); cols[5].Write(writer, row.PublicKeyOrToken); - cols[6].Write(writer, row.Name); - cols[7].Write(writer, row.Locale); + cols[6].Write(writer, stringsHeap.GetOffset(row.Name)); + cols[7].Write(writer, stringsHeap.GetOffset(row.Locale)); cols[8].Write(writer, row.HashValue); } } @@ -582,8 +653,9 @@ public static void Write(this BinaryWriter writer, MDTable ta /// Writes a AssemblyRefProcessor table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.Processor); @@ -595,8 +667,9 @@ public static void Write(this BinaryWriter writer, MDTableAssemblyRefOS table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { writer.Write(row.OSPlatformId); @@ -610,12 +683,14 @@ public static void Write(this BinaryWriter writer, MDTable /// Writes a File table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Flags); - cols[1].Write(writer, row.Name); + cols[1].Write(writer, stringsHeap.GetOffset(row.Name)); cols[2].Write(writer, row.HashValue); } } @@ -624,14 +699,16 @@ public static void Write(this BinaryWriter writer, MDTable table) { /// Writes a ExportedType table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Flags); writer.Write(row.TypeDefId); - cols[2].Write(writer, row.TypeName); - cols[3].Write(writer, row.TypeNamespace); + cols[2].Write(writer, stringsHeap.GetOffset(row.TypeName)); + cols[3].Write(writer, stringsHeap.GetOffset(row.TypeNamespace)); cols[4].Write(writer, row.Implementation); } } @@ -640,13 +717,15 @@ public static void Write(this BinaryWriter writer, MDTable t /// Writes a ManifestResource table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; foreach (var row in table) { writer.Write(row.Offset); writer.Write(row.Flags); - cols[2].Write(writer, row.Name); + cols[2].Write(writer, stringsHeap.GetOffset(row.Name)); cols[3].Write(writer, row.Implementation); } } @@ -655,8 +734,9 @@ public static void Write(this BinaryWriter writer, MDTableNestedClass table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.NestedClass); @@ -668,17 +748,27 @@ public static void Write(this BinaryWriter writer, MDTable ta /// Writes a GenericParam table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; - bool useKindColumn = cols.Count >= 5; - foreach (var row in table) { - writer.Write(row.Number); - writer.Write(row.Flags); - cols[2].Write(writer, row.Owner); - cols[3].Write(writer, row.Name); - if (useKindColumn) + var stringsHeap = metadata.StringsHeap; + if (cols.Count >= 5) { + foreach (var row in table) { + writer.Write(row.Number); + writer.Write(row.Flags); + cols[2].Write(writer, row.Owner); + cols[3].Write(writer, stringsHeap.GetOffset(row.Name)); cols[4].Write(writer, row.Kind); + } + } + else { + foreach (var row in table) { + writer.Write(row.Number); + writer.Write(row.Flags); + cols[2].Write(writer, row.Owner); + cols[3].Write(writer, stringsHeap.GetOffset(row.Name)); + } } } @@ -686,8 +776,9 @@ public static void Write(this BinaryWriter writer, MDTable t /// Writes a MethodSpec table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Method); @@ -699,13 +790,136 @@ public static void Write(this BinaryWriter writer, MDTable tab /// Writes a GenericParamConstraint table /// /// Writer + /// Metadata /// Table - public static void Write(this BinaryWriter writer, MDTable table) { + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { var cols = table.TableInfo.Columns; foreach (var row in table) { cols[0].Write(writer, row.Owner); cols[1].Write(writer, row.Constraint); } } + + /// + /// Writes a Document table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + foreach (var row in table) { + cols[0].Write(writer, row.Name); + cols[1].Write(writer, row.HashAlgorithm); + cols[2].Write(writer, row.Hash); + cols[3].Write(writer, row.Language); + } + } + + /// + /// Writes a MethodDebugInformation table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + foreach (var row in table) { + cols[0].Write(writer, row.Document); + cols[1].Write(writer, row.SequencePoints); + } + } + + /// + /// Writes a LocalScope table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + foreach (var row in table) { + cols[0].Write(writer, row.Method); + cols[1].Write(writer, row.ImportScope); + cols[2].Write(writer, row.VariableList); + cols[3].Write(writer, row.ConstantList); + cols[4].Write(writer, row.StartOffset); + cols[5].Write(writer, row.Length); + } + } + + /// + /// Writes a LocalVariable table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; + foreach (var row in table) { + cols[0].Write(writer, row.Attributes); + cols[1].Write(writer, row.Index); + cols[2].Write(writer, stringsHeap.GetOffset(row.Name)); + } + } + + /// + /// Writes a LocalConstant table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; + foreach (var row in table) { + cols[0].Write(writer, stringsHeap.GetOffset(row.Name)); + cols[1].Write(writer, row.Signature); + } + } + + /// + /// Writes a ImportScope table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + foreach (var row in table) { + cols[0].Write(writer, row.Parent); + cols[1].Write(writer, row.Imports); + } + } + + /// + /// Writes a StateMachineMethod table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + foreach (var row in table) { + cols[0].Write(writer, row.MoveNextMethod); + cols[1].Write(writer, row.KickoffMethod); + } + } + + /// + /// Writes a CustomDebugInformation table + /// + /// Writer + /// Metadata + /// Table + public static void Write(this BinaryWriter writer, MetaData metadata, MDTable table) { + var cols = table.TableInfo.Columns; + foreach (var row in table) { + cols[0].Write(writer, row.Parent); + cols[1].Write(writer, row.Kind); + cols[2].Write(writer, row.Value); + } + } } } diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 527b4e796..abd6e999e 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -392,7 +392,7 @@ public MetaDataHeader MetaDataHeader { /// /// Gets/sets the hot heap (#!) /// - public HotHeap HotHeap { + HotHeap HotHeap { get { return hotHeap; } set { hotHeap = value; } } @@ -763,7 +763,7 @@ internal MetaData(ModuleDef module, UniqueChunkList constants, M this.netResources = netResources; this.options = options ?? new MetaDataOptions(); this.metaDataHeader = new MetaDataHeader(isStandaloneDebugMetadata ? this.options.DebugMetaDataHeaderOptions : this.options.MetaDataHeaderOptions); - this.tablesHeap = new TablesHeap(isStandaloneDebugMetadata ? this.options.DebugTablesHeapOptions : this.options.TablesHeapOptions); + this.tablesHeap = new TablesHeap(this, isStandaloneDebugMetadata ? this.options.DebugTablesHeapOptions : this.options.TablesHeapOptions); this.stringsHeap = new StringsHeap(); this.usHeap = new USHeap(); this.guidHeap = new GuidHeap(); @@ -3411,6 +3411,7 @@ public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; + stringsHeap.AddOptimizedStrings(); stringsHeap.SetReadOnly(); blobHeap.SetReadOnly(); guidHeap.SetReadOnly(); diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index cf19b93b1..b3090428c 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -5,6 +5,7 @@ using System.IO; using dnlib.IO; using dnlib.DotNet.MD; +using System.Diagnostics; namespace dnlib.DotNet.Writer { /// @@ -16,6 +17,25 @@ public sealed class StringsHeap : HeapBase, IOffsetHeap { uint nextOffset = 1; byte[] originalData; Dictionary userRawData; + readonly Dictionary toStringsOffsetInfo = new Dictionary(UTF8StringEqualityComparer.Instance); + readonly Dictionary offsetIdToInfo = new Dictionary(); + readonly List stringsOffsetInfos = new List(); + const uint STRINGS_ID_FLAG = 0x80000000; + uint stringsId = STRINGS_ID_FLAG | 0; + + sealed class StringsOffsetInfo { + public StringsOffsetInfo(UTF8String value, uint stringsId) { + Value = value; + StringsId = stringsId; + Debug.Assert((stringsId & STRINGS_ID_FLAG) != 0); + } + public readonly UTF8String Value; + public readonly uint StringsId; + public uint StringsOffset; + public override string ToString() { + return string.Format("{0:X8} {1:X4} {2}", StringsId, StringsOffset, Value.String); + } + } /// public override string Name { @@ -62,22 +82,101 @@ void Populate(IImageStream reader) { } } + internal void AddOptimizedStrings() { + if (isReadOnly) + throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); + + stringsOffsetInfos.Sort(Comparison_StringsOffsetInfoSorter); + + StringsOffsetInfo prevInfo = null; + foreach (var info in stringsOffsetInfos) { + if (prevInfo != null && EndsWith(prevInfo.Value, info.Value)) + info.StringsOffset = prevInfo.StringsOffset + (uint)(prevInfo.Value.Data.Length - info.Value.Data.Length); + else + info.StringsOffset = AddToCache(info.Value); + prevInfo = info; + } + } + + static bool EndsWith(UTF8String s, UTF8String value) { + var d = s.Data; + var vd = value.Data; + int i = d.Length - vd.Length; + if (i < 0) + return false; + for (int vi = 0; vi < vd.Length; vi++) { + if (d[i] != vd[vi]) + return false; + i++; + } + return true; + } + + static readonly Comparison Comparison_StringsOffsetInfoSorter = StringsOffsetInfoSorter; + static int StringsOffsetInfoSorter(StringsOffsetInfo a, StringsOffsetInfo b) { + var da = a.Value.Data; + var db = b.Value.Data; + int ai = da.Length - 1; + int bi = db.Length - 1; + int len = Math.Min(da.Length, db.Length); + while (len > 0) { + int c = da[ai] - db[bi]; + if (c != 0) + return c; + ai--; + bi--; + len--; + } + return db.Length - da.Length; + } + /// - /// Adds a string to the #Strings heap + /// Adds a string to the #Strings heap. The returned value is not necessarily an offset in + /// the #Strings heap. Call to get the offset. /// /// The string - /// The offset of the string in the #Strings heap + /// The offset id. This is not a #Strings offset. Call to get the #Strings offset public uint Add(UTF8String s) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); if (UTF8String.IsNullOrEmpty(s)) return 0; + StringsOffsetInfo info; + if (toStringsOffsetInfo.TryGetValue(s, out info)) + return info.StringsId; uint offset; if (cachedDict.TryGetValue(s, out offset)) return offset; - return AddToCache(s); + if (Array.IndexOf(s.Data, (byte)0) >= 0) + throw new ArgumentException("Strings in the #Strings heap can't contain NUL bytes"); + info = new StringsOffsetInfo(s, stringsId++); + Debug.Assert(!toStringsOffsetInfo.ContainsKey(s)); + Debug.Assert(!offsetIdToInfo.ContainsKey(info.StringsId)); + toStringsOffsetInfo[s] = info; + offsetIdToInfo[info.StringsId] = info; + stringsOffsetInfos.Add(info); + return info.StringsId; + } + + /// + /// Gets the offset of a string in the #Strings heap. This method can only be called after + /// all strings have been added. + /// + /// Offset id returned by + /// + public uint GetOffset(uint offsetId) { + if (!isReadOnly) + throw new ModuleWriterException("This method can only be called after all strings have been added and this heap is read-only"); + if ((offsetId & STRINGS_ID_FLAG) == 0) + return offsetId; + StringsOffsetInfo info; + if (offsetIdToInfo.TryGetValue(offsetId, out info)) { + Debug.Assert(info.StringsOffset != 0); + return info.StringsOffset; + } + throw new ArgumentOutOfRangeException("offsetId"); } /// @@ -90,13 +189,12 @@ public uint Create(UTF8String s) { throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); if (UTF8String.IsNullOrEmpty(s)) s = UTF8String.Empty; + if (Array.IndexOf(s.Data, (byte)0) >= 0) + throw new ArgumentException("Strings in the #Strings heap can't contain NUL bytes"); return AddToCache(s); } uint AddToCache(UTF8String s) { - if (Array.IndexOf(s.Data, (byte)0) >= 0) - throw new ArgumentException("Strings in the #Strings heap can't contain 00h bytes"); - uint offset; cached.Add(s); cachedDict[s] = offset = nextOffset; diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 126df84a3..089e6ef3d 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -74,6 +74,7 @@ public sealed class TablesHeap : IHeap { bool bigGuid; bool bigBlob; bool hasDeletedRows; + readonly MetaData metadata; readonly TablesHeapOptions options; FileOffset offset; RVA rva; @@ -224,18 +225,13 @@ public bool BigBlob { set { bigBlob = value; } } - /// - /// Default constructor - /// - public TablesHeap() - : this(null) { - } - /// /// Constructor /// + /// Metadata owner /// Options - public TablesHeap(TablesHeapOptions options) { + public TablesHeap(MetaData metadata, TablesHeapOptions options) { + this.metadata = metadata; this.options = options ?? new TablesHeapOptions(); this.hasDeletedRows = this.options.HasDeletedRows ?? false; this.Tables = new IMDTable[] { @@ -425,59 +421,59 @@ public void WriteTo(BinaryWriter writer) { if (options.ExtraData.HasValue) writer.Write(options.ExtraData.Value); - writer.Write(ModuleTable); - writer.Write(TypeRefTable); - writer.Write(TypeDefTable); - writer.Write(FieldPtrTable); - writer.Write(FieldTable); - writer.Write(MethodPtrTable); - writer.Write(MethodTable); - writer.Write(ParamPtrTable); - writer.Write(ParamTable); - writer.Write(InterfaceImplTable); - writer.Write(MemberRefTable); - writer.Write(ConstantTable); - writer.Write(CustomAttributeTable); - writer.Write(FieldMarshalTable); - writer.Write(DeclSecurityTable); - writer.Write(ClassLayoutTable); - writer.Write(FieldLayoutTable); - writer.Write(StandAloneSigTable); - writer.Write(EventMapTable); - writer.Write(EventPtrTable); - writer.Write(EventTable); - writer.Write(PropertyMapTable); - writer.Write(PropertyPtrTable); - writer.Write(PropertyTable); - writer.Write(MethodSemanticsTable); - writer.Write(MethodImplTable); - writer.Write(ModuleRefTable); - writer.Write(TypeSpecTable); - writer.Write(ImplMapTable); - writer.Write(FieldRVATable); - writer.Write(ENCLogTable); - writer.Write(ENCMapTable); - writer.Write(AssemblyTable); - writer.Write(AssemblyProcessorTable); - writer.Write(AssemblyOSTable); - writer.Write(AssemblyRefTable); - writer.Write(AssemblyRefProcessorTable); - writer.Write(AssemblyRefOSTable); - writer.Write(FileTable); - writer.Write(ExportedTypeTable); - writer.Write(ManifestResourceTable); - writer.Write(NestedClassTable); - writer.Write(GenericParamTable); - writer.Write(MethodSpecTable); - writer.Write(GenericParamConstraintTable); - writer.Write(DocumentTable); - writer.Write(MethodDebugInformationTable); - writer.Write(LocalScopeTable); - writer.Write(LocalVariableTable); - writer.Write(LocalConstantTable); - writer.Write(ImportScopeTable); - writer.Write(StateMachineMethodTable); - writer.Write(CustomDebugInformationTable); + writer.Write(metadata, ModuleTable); + writer.Write(metadata, TypeRefTable); + writer.Write(metadata, TypeDefTable); + writer.Write(metadata, FieldPtrTable); + writer.Write(metadata, FieldTable); + writer.Write(metadata, MethodPtrTable); + writer.Write(metadata, MethodTable); + writer.Write(metadata, ParamPtrTable); + writer.Write(metadata, ParamTable); + writer.Write(metadata, InterfaceImplTable); + writer.Write(metadata, MemberRefTable); + writer.Write(metadata, ConstantTable); + writer.Write(metadata, CustomAttributeTable); + writer.Write(metadata, FieldMarshalTable); + writer.Write(metadata, DeclSecurityTable); + writer.Write(metadata, ClassLayoutTable); + writer.Write(metadata, FieldLayoutTable); + writer.Write(metadata, StandAloneSigTable); + writer.Write(metadata, EventMapTable); + writer.Write(metadata, EventPtrTable); + writer.Write(metadata, EventTable); + writer.Write(metadata, PropertyMapTable); + writer.Write(metadata, PropertyPtrTable); + writer.Write(metadata, PropertyTable); + writer.Write(metadata, MethodSemanticsTable); + writer.Write(metadata, MethodImplTable); + writer.Write(metadata, ModuleRefTable); + writer.Write(metadata, TypeSpecTable); + writer.Write(metadata, ImplMapTable); + writer.Write(metadata, FieldRVATable); + writer.Write(metadata, ENCLogTable); + writer.Write(metadata, ENCMapTable); + writer.Write(metadata, AssemblyTable); + writer.Write(metadata, AssemblyProcessorTable); + writer.Write(metadata, AssemblyOSTable); + writer.Write(metadata, AssemblyRefTable); + writer.Write(metadata, AssemblyRefProcessorTable); + writer.Write(metadata, AssemblyRefOSTable); + writer.Write(metadata, FileTable); + writer.Write(metadata, ExportedTypeTable); + writer.Write(metadata, ManifestResourceTable); + writer.Write(metadata, NestedClassTable); + writer.Write(metadata, GenericParamTable); + writer.Write(metadata, MethodSpecTable); + writer.Write(metadata, GenericParamConstraintTable); + writer.Write(metadata, DocumentTable); + writer.Write(metadata, MethodDebugInformationTable); + writer.Write(metadata, LocalScopeTable); + writer.Write(metadata, LocalVariableTable); + writer.Write(metadata, LocalConstantTable); + writer.Write(metadata, ImportScopeTable); + writer.Write(metadata, StateMachineMethodTable); + writer.Write(metadata, CustomDebugInformationTable); writer.WriteZeros((int)(Utils.AlignUp(length, HeapBase.ALIGNMENT) - length)); } From 121f6797df6ddcefe974475c01b24ce0428ecb40 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Feb 2018 07:13:34 +0100 Subject: [PATCH 079/511] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 68e670243..751fb5a8b 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ mixed mode assemblies, doesn't read .NET assemblies the same way the [CLR](http: and many other missing features de4dot needed, dnlib was a necessity. The API is similar because it made porting de4dot to dnlib a lot easier. -For another application using dnlib, see [ConfuserEx](https://github.com/yck1509/ConfuserEx/) -(a .NET obfuscator). It uses many of the more advanced features of dnlib. Have -a look at its writer code which gets executed during the assembly writing -process. +For other applications using dnlib, see [dnSpy](https://github.com/0xd4d/dnSpy) and +[ConfuserEx](https://github.com/yck1509/ConfuserEx/) (a .NET obfuscator). They use +many of the more advanced features of dnlib. Have a look at ConfuserEx' writer code +which gets executed during the assembly writing process. Want to say thanks? Click the star at the top of the page. From b572737e4bca0a2479f0435248d3cdbe7196c6df Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Feb 2018 07:54:05 +0100 Subject: [PATCH 080/511] Fix ImportScopeBlobWriter --- .../Pdb/Portable/ImportScopeBlobWriter.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index 7264957cc..4b1bad56d 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -54,7 +54,7 @@ void Write(BinaryWriter writer, IList imports) { case PdbImportDefinitionKind.ImportType: // ::= ImportType - writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbImportType)import).TargetType).Rid); + writer.WriteCompressedUInt32(GetTypeDefOrRefEncodedToken(((PdbImportType)import).TargetType)); break; case PdbImportDefinitionKind.ImportXmlNamespace: @@ -90,7 +90,7 @@ void Write(BinaryWriter writer, IList imports) { case PdbImportDefinitionKind.AliasType: // ::= AliasType writer.WriteCompressedUInt32(WriteUTF8(((PdbAliasType)import).Alias)); - writer.WriteCompressedUInt32(systemMetaData.GetToken(((PdbAliasType)import).TargetType).Rid); + writer.WriteCompressedUInt32(GetTypeDefOrRefEncodedToken(((PdbAliasType)import).TargetType)); break; default: @@ -99,5 +99,18 @@ void Write(BinaryWriter writer, IList imports) { } } } + + uint GetTypeDefOrRefEncodedToken(ITypeDefOrRef tdr) { + if (tdr == null) { + helper.Error("ITypeDefOrRef is null"); + return 0; + } + var token = systemMetaData.GetToken(tdr); + uint codedToken; + if (MD.CodedToken.TypeDefOrRef.Encode(token, out codedToken)) + return codedToken; + helper.Error(string.Format("Could not encode token 0x{0:X8}", token.Raw)); + return 0; + } } } From 08772d73d21d913c5402dbd08b9c668e55f3450c Mon Sep 17 00:00:00 2001 From: SlowLogicBoy Date: Wed, 21 Feb 2018 09:24:29 +0200 Subject: [PATCH 081/511] Port to netstandard2.0 (#155) * Port to netstandard2.0 * netfx build fix * netfx build fix * Revert .sln and Example projects * revert some changes in gitignore * Change Output path to match with framework. * revert git ignore * Review changes * Review changes --- src/DotNet/Emit/MethodTableToTypeConverter.cs | 20 ++++++++++++++---- src/DotNet/ModuleDefMD.cs | 13 +++++++++++- src/dnlib.netstandard.csproj | 21 +++++++++++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/dnlib.netstandard.csproj diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index a805e4961..b909005f9 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -30,7 +30,11 @@ static class MethodTableToTypeConverter { static MethodTableToTypeConverter() { if (ptrFieldInfo == null) { +#if NETSTANDARD2_0 + var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); +#else var asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); +#endif moduleBuilder = asmb.DefineDynamicModule("DynMod"); } } @@ -81,8 +85,12 @@ static Type GetTypeNET45(TypeBuilder tb, MethodBuilder mb, IntPtr address) { int maxStack = 8; byte[] locals = GetLocalSignature(address); setMethodBodyMethodInfo.Invoke(mb, new object[5] { code, maxStack, locals, null, null }); - - var createdMethod = tb.CreateType().GetMethod(METHOD_NAME, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); +#if NETSTANDARD2_0 + var type = tb.CreateTypeInfo(); +#else + var type = tb.CreateType(); +#endif + var createdMethod = type.GetMethod(METHOD_NAME, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); return createdMethod.GetMethodBody().LocalVariables[0].LocalType; } @@ -100,8 +108,12 @@ static Type GetTypeNET40(TypeBuilder tb, MethodBuilder mb, IntPtr address) { sigDoneFieldInfo.SetValue(sigHelper, true); currSigFieldInfo.SetValue(sigHelper, locals.Length); signatureFieldInfo.SetValue(sigHelper, locals); - - var createdMethod = tb.CreateType().GetMethod(METHOD_NAME, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); +#if NETSTANDARD2_0 + var type = tb.CreateTypeInfo(); +#else + var type = tb.CreateType(); +#endif + var createdMethod = type.GetMethod(METHOD_NAME, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); return createdMethod.GetMethodBody().LocalVariables[0].LocalType; } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 372dc7d12..bce3866e1 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -235,6 +235,17 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext conte return Load(mod, new ModuleCreationOptions(context), imageLayout); } + static IntPtr GetModuleHandle(System.Reflection.Module mod) { +#if NETSTANDARD2_0 + var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new [] { typeof(System.Reflection.Module) }); + if(GetHINSTANCE == null) + throw new NotSupportedException("Module loading is not supported on current platform"); + return (IntPtr)GetHINSTANCE.Invoke(null, new [] { mod }); +#else + return Marshal.GetHINSTANCE(mod); +#endif + } + /// /// Creates a instance from a reflection module /// @@ -243,7 +254,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext conte /// Image layout of the module in memory /// A new instance public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptions options, ImageLayout imageLayout) { - IntPtr addr = Marshal.GetHINSTANCE(mod); + IntPtr addr = GetModuleHandle(mod); if (addr == new IntPtr(-1)) throw new InvalidOperationException(string.Format("Module {0} has no HINSTANCE", mod)); return Load(addr, options, imageLayout); diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj new file mode 100644 index 000000000..f7bf9c71e --- /dev/null +++ b/src/dnlib.netstandard.csproj @@ -0,0 +1,21 @@ + + + netstandard2.0 + dnlib + dnlib + true + true + ..\dnlib.snk + ..\$(Configuration)\bin + $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml + false + + + + + + + + + + \ No newline at end of file From 2c00f09c4e2b36fe56fb3d759b66d345c8ab0a1b Mon Sep 17 00:00:00 2001 From: SlowLogicBoy Date: Wed, 21 Feb 2018 19:13:35 +0200 Subject: [PATCH 082/511] Assembly Signing is not supported. (#158) * Assembly Signing is not supported. Assembly signing is only supported on Windows with msbuild. * fix formatting * Update signing stuff --- src/dnlib.netstandard.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index f7bf9c71e..2252f5b79 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 dnlib @@ -6,6 +6,7 @@ true true ..\dnlib.snk + true ..\$(Configuration)\bin $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml false @@ -18,4 +19,4 @@ - \ No newline at end of file + From ce72fb29893805254f74410f53235fab8ce77585 Mon Sep 17 00:00:00 2001 From: SlowLogicBoy Date: Wed, 21 Feb 2018 20:00:43 +0200 Subject: [PATCH 083/511] Fix for #159 (#160) * Fix for #159 fixes #159 * change exception. --- src/DotNet/ModuleDefMD.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index bce3866e1..527317197 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -240,7 +240,12 @@ static IntPtr GetModuleHandle(System.Reflection.Module mod) { var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new [] { typeof(System.Reflection.Module) }); if(GetHINSTANCE == null) throw new NotSupportedException("Module loading is not supported on current platform"); - return (IntPtr)GetHINSTANCE.Invoke(null, new [] { mod }); + + var addr = (IntPtr)GetHINSTANCE.Invoke(null, new [] { mod }); + if(addr == new IntPtr(0) || addr == new IntPtr(-1)) + throw new ArgumentException("It is not possible to get address of module"); + + return addr; #else return Marshal.GetHINSTANCE(mod); #endif From 5cc410faca13e175cf2b65ae94096c31f05f4d53 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 06:27:49 +0100 Subject: [PATCH 084/511] Add netstandard sln, fix formatting --- dnlib.netstandard.sln | 25 +++++++++++++++++++++++++ src/DotNet/ModuleDefMD.cs | 16 ++++++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 dnlib.netstandard.sln diff --git a/dnlib.netstandard.sln b/dnlib.netstandard.sln new file mode 100644 index 000000000..b9316a5c2 --- /dev/null +++ b/dnlib.netstandard.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib.netstandard", "src\dnlib.netstandard.csproj", "{80695BC3-65CA-403E-B161-57D4F6EC5CC3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DA3B4267-5AB5-4A1D-A0D5-CF49A2882567} + EndGlobalSection +EndGlobal diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 527317197..5951395cf 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -237,18 +237,18 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext conte static IntPtr GetModuleHandle(System.Reflection.Module mod) { #if NETSTANDARD2_0 - var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new [] { typeof(System.Reflection.Module) }); - if(GetHINSTANCE == null) - throw new NotSupportedException("Module loading is not supported on current platform"); + var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new[] { typeof(System.Reflection.Module) }); + if (GetHINSTANCE == null) + throw new NotSupportedException("System.Reflection.Module loading is not supported on current platform"); - var addr = (IntPtr)GetHINSTANCE.Invoke(null, new [] { mod }); - if(addr == new IntPtr(0) || addr == new IntPtr(-1)) + var addr = (IntPtr)GetHINSTANCE.Invoke(null, new[] { mod }); +#else + var addr = Marshal.GetHINSTANCE(mod); +#endif + if (addr == IntPtr.Zero || addr == new IntPtr(-1)) throw new ArgumentException("It is not possible to get address of module"); return addr; -#else - return Marshal.GetHINSTANCE(mod); -#endif } /// From c47737b70112572966aec873fee925a39b88b1dd Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 06:27:57 +0100 Subject: [PATCH 085/511] Use a stable metadata table sorter, fixes #156 --- src/DotNet/Writer/MetaData.cs | 47 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index abd6e999e..4e7e49f60 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -155,6 +155,12 @@ public enum MetaDataFlags : uint { /// Always create the #Blob heap even if it's empty /// AlwaysCreateBlobHeap = 0x80000, + + /// + /// Sort the InterfaceImpl table the same way Roslyn sorts it. Roslyn doesn't sort it + /// according to the ECMA spec, see https://github.com/dotnet/roslyn/issues/3905 + /// + RoslynSortInterfaceImpl = 0x100000, } /// @@ -470,14 +476,24 @@ public void Add(T data, TRow row) { toRid[data] = (uint)toRid.Count + 1; } - public void Sort(Comparison.Info> comparison) { - infos.Sort(comparison); + public void Sort(Comparison comparison) { + infos.Sort(CreateComparison(comparison)); toRid.Clear(); for (int i = 0; i < infos.Count; i++) toRid[infos[i].data] = (uint)i + 1; isSorted = true; } + Comparison CreateComparison(Comparison comparison) { + return (a, b) => { + int c = comparison(a, b); + if (c != 0) + return c; + // Make sure it's a stable sort + return toRid[a.data].CompareTo(toRid[b.data]); + }; + } + public uint Rid(T data) { return toRid[data]; } @@ -745,6 +761,19 @@ public bool AlwaysCreateBlobHeap { } } + /// + /// Gets/sets the bit + /// + public bool RoslynSortInterfaceImpl { + get { return (options.Flags & MetaDataFlags.RoslynSortInterfaceImpl) != 0; } + set { + if (value) + options.Flags |= MetaDataFlags.RoslynSortInterfaceImpl; + else + options.Flags &= ~MetaDataFlags.RoslynSortInterfaceImpl; + } + } + /// /// If true, use the original Field RVAs. If it has no RVA, assume it's a new /// field value and create a new Field RVA. @@ -1620,11 +1649,15 @@ void SortTables() { return a.row.Owner.CompareTo(b.row.Owner); return a.row.Number.CompareTo(b.row.Number); }); - interfaceImplInfos.Sort((a, b) => { - if (a.row.Class != b.row.Class) - return a.row.Class.CompareTo(b.row.Class); - return a.row.Interface.CompareTo(b.row.Interface); - }); + if (RoslynSortInterfaceImpl) + interfaceImplInfos.Sort((a, b) => a.row.Class.CompareTo(b.row.Class)); + else { + interfaceImplInfos.Sort((a, b) => { + if (a.row.Class != b.row.Class) + return a.row.Class.CompareTo(b.row.Class); + return a.row.Interface.CompareTo(b.row.Interface); + }); + } tablesHeap.ClassLayoutTable.IsSorted = true; tablesHeap.ConstantTable.IsSorted = true; From 71a98d4ef44df97921c46f6d9324f57784648611 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 06:28:10 +0100 Subject: [PATCH 086/511] Use reference comparison --- src/DotNet/SigComparer.cs | 96 +++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 6f3547187..fcc1215a5 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -3427,7 +3427,7 @@ public bool Equals(TypeDef a, Type b) { // null always means the global type. if (a == null) return false; - if (b == null) + if ((object)b == null) return a.IsGlobalModuleType; if (!recursionCounter.Increment()) return false; @@ -3456,7 +3456,7 @@ bool EnclosingTypeEquals(TypeDef a, Type b) { // b == null doesn't mean that b is the global type if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; return Equals(a, b); } @@ -3482,7 +3482,7 @@ public bool Equals(TypeRef a, Type b) { // null always means the global type. if (a == null) return false; - if (b == null) + if ((object)b == null) return false; // Must use a ModuleRef to reference the global type, so always fail if (!recursionCounter.Increment()) return false; @@ -3546,7 +3546,7 @@ public bool Equals(TypeSpec a, Type b) { // null always means the global type. if (a == null) return false; - if (b == null) + if ((object)b == null) return false; // Must use a ModuleRef to reference the global type, so always fail return Equals(a.TypeSig, b); } @@ -3583,7 +3583,7 @@ bool Equals(ITypeDefOrRef a, Type b, bool treatAsGenericInst) { /// /// The type static bool IsFnPtrElementType(Type a) { - if (a == null || !a.HasElementType) + if ((object)a == null || !a.HasElementType) return false; var et = a.GetElementType(); if (et == null || et.HasElementType) @@ -3609,7 +3609,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { // null always means the global type. if (a == null) return false; - if (b == null) + if ((object)b == null) return false; // Must use a ModuleRef to reference the global type, so always fail if (!recursionCounter.Increment()) return false; @@ -3697,13 +3697,13 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { case ElementType.Var: result = b.IsGenericParameter && b.GenericParameterPosition == (a as GenericSig).Number && - b.DeclaringMethod == null; + (object)b.DeclaringMethod == null; break; case ElementType.MVar: result = b.IsGenericParameter && b.GenericParameterPosition == (a as GenericSig).Number && - b.DeclaringMethod != null; + (object)b.DeclaringMethod != null; break; case ElementType.GenericInst: @@ -3769,7 +3769,7 @@ public bool Equals(ExportedType a, Type b) { // null always means the global type. if (a == null) return false; - if (b == null) + if ((object)b == null) return false; // Must use a ModuleRef to reference the global type, so always fail if (!recursionCounter.Increment()) return false; @@ -3824,7 +3824,7 @@ public int GetHashCode(Type a, bool treatAsGenericInst) { // ************************************************************************** // IMPORTANT: This hash code must match the TypeSig/TypeDef/TypeRef hash code // ************************************************************************** - if (a == null) // Could be global type + if ((object)a == null) // Could be global type return GetHashCode_TypeDef(a); if (!recursionCounter.Increment()) return 0; @@ -3972,7 +3972,7 @@ public int GetHashCode_TypeDef(Type a) { // A global method/field's declaring type is null. This is the reason we must // return GetHashCodeGlobalType() here. - if (a == null) + if ((object)a == null) return GetHashCodeGlobalType(); int hash; hash = GetHashCode_TypeName(a.Name); @@ -4022,7 +4022,7 @@ bool Equals(IList a, IList b) { bool Equals(ModuleDef a, Module b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -4044,7 +4044,7 @@ bool Equals(ModuleDef a, Module b) { bool Equals(FileDef a, Module b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; // Use b.Name since it's the filename we want to compare, not b.ScopeName @@ -4058,9 +4058,9 @@ bool Equals(FileDef a, Module b) { /// Module #2 /// true if same, false otherwise bool Equals(IModule a, Module b) { - if (a == b) + if ((object)a == b) return true; - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -4076,9 +4076,9 @@ bool Equals(IModule a, Module b) { /// Assembly #2 /// true if same, false otherwise bool Equals(IAssembly a, Assembly b) { - if (a == b) + if ((object)a == b) return true; - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -4106,9 +4106,9 @@ bool DeclaringTypeEquals(IMethod a, MethodBase b) { if (!CompareMethodFieldDeclaringType) return true; - if (a == b) + if ((object)a == b) return true; - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4137,7 +4137,7 @@ bool DeclaringTypeEquals(MethodDef a, MethodBase b) { return true; if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; return Equals(a.DeclaringType, b.DeclaringType); } @@ -4148,7 +4148,7 @@ bool DeclaringTypeEquals(MemberRef a, MethodBase b) { return true; if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; return Equals(a.Class, b.DeclaringType, b.Module); } @@ -4159,7 +4159,7 @@ bool DeclaringTypeEquals(MethodSpec a, MethodBase b) { return true; if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; return DeclaringTypeEquals(a.Method, b); } @@ -4181,9 +4181,9 @@ public bool Equals(MethodBase a, IMethod b) { /// Method #2 /// true if same, false otherwise public bool Equals(IMethod a, MethodBase b) { - if (a == b) + if ((object)a == b) return true; - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4225,7 +4225,7 @@ public bool Equals(MethodBase a, MethodDef b) { public bool Equals(MethodDef a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4271,7 +4271,7 @@ public bool Equals(MethodBase a, MethodSig b) { public bool Equals(MethodSig a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4304,7 +4304,7 @@ public bool Equals(MethodBase a, MemberRef b) { public bool Equals(MemberRef a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4383,13 +4383,13 @@ bool Equals(IMemberRefParent a, Type b, Module bModule) { result = Equals((IType)ita, b); else if ((moda = a as ModuleRef) != null) { ModuleDef omoda = moda.Module; - result = b == null && // b == null => it's the global type + result = (object)b == null && // b == null => it's the global type Equals(moda, bModule) && Equals(omoda == null ? null : omoda.Assembly, bModule.Assembly); } else if ((ma = a as MethodDef) != null) result = Equals(ma.DeclaringType, b); - else if (b == null && (td = a as TypeDef) != null) + else if ((object)b == null && (td = a as TypeDef) != null) result = td.IsGlobalModuleType; else result = false; @@ -4417,7 +4417,7 @@ public bool Equals(MethodBase a, MethodSpec b) { public bool Equals(MethodSpec a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4446,7 +4446,7 @@ public bool Equals(MethodSpec a, MethodBase b) { /// The MethodBase /// The hash code public int GetHashCode(MethodBase a) { - if (a == null) + if ((object)a == null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4464,7 +4464,7 @@ public int GetHashCode(MethodBase a) { } int GetHashCode_MethodSig(MethodBase a) { - if (a == null) + if ((object)a == null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4506,7 +4506,7 @@ int GetHashCode(IList a, Type declaringType) { int GetHashCode_ReturnType(MethodBase a) { var mi = a as MethodInfo; - if (mi != null) + if ((object)mi != null) return GetHashCode(mi.ReturnParameter, a.DeclaringType); return GetHashCode(typeof(void)); } @@ -4581,14 +4581,14 @@ static int GetHashCode_CallingConvention(CallingConventions a, bool isGeneric) { bool ReturnTypeEquals(TypeSig a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; bool result; var mi = b as MethodInfo; - if (mi != null) + if ((object)mi != null) result = Equals(a, mi.ReturnParameter, b.DeclaringType); else if (b is ConstructorInfo) result = IsSystemVoid(a); @@ -4644,7 +4644,7 @@ bool Equals(IList a, IList b, Type declaringType) { bool Equals(TypeSig a, ParameterInfo b, Type declaringType) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4733,9 +4733,9 @@ public bool Equals(FieldInfo a, IField b) { /// Field #2 /// true if same, false otherwise public bool Equals(IField a, FieldInfo b) { - if (a == b) + if ((object)a == b) return true; - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4774,7 +4774,7 @@ public bool Equals(FieldInfo a, FieldDef b) { public bool Equals(FieldDef a, FieldInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4790,7 +4790,7 @@ public bool Equals(FieldDef a, FieldInfo b) { bool Equals(FieldSig a, FieldInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4822,7 +4822,7 @@ public bool Equals(FieldInfo a, MemberRef b) { public bool Equals(MemberRef a, FieldInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4854,7 +4854,7 @@ public int GetHashCode(FieldInfo a) { // ************************************************************ // IMPORTANT: This hash code must match the MemberRef hash code // ************************************************************ - if (a == null) + if ((object)a == null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4869,7 +4869,7 @@ public int GetHashCode(FieldInfo a) { } int GetHashCode_FieldSig(FieldInfo a) { - if (a == null) + if ((object)a == null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4890,7 +4890,7 @@ int GetHashCode_FieldSig(FieldInfo a) { public bool Equals(PropertyDef a, PropertyInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4906,7 +4906,7 @@ public bool Equals(PropertyDef a, PropertyInfo b) { bool Equals(PropertySig a, PropertyInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4928,7 +4928,7 @@ public int GetHashCode(PropertyInfo a) { // ************************************************************** // IMPORTANT: This hash code must match the PropertyDef hash code // ************************************************************** - if (a == null) + if ((object)a == null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4951,7 +4951,7 @@ public int GetHashCode(PropertyInfo a) { public bool Equals(EventDef a, EventInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a == null || (object)b == null) return false; if (!recursionCounter.Increment()) return false; @@ -4973,7 +4973,7 @@ public int GetHashCode(EventInfo a) { // *********************************************************** // IMPORTANT: This hash code must match the EventDef hash code // *********************************************************** - if (a == null) + if ((object)a == null) return 0; if (!recursionCounter.Increment()) return 0; From 3769fecbd8b1740a4c6791632378c291ba0d63bb Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 06:28:22 +0100 Subject: [PATCH 087/511] Fix PDB string constant checks, only needed if it's a Windows PDB --- src/DotNet/Pdb/PdbState.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 8b57fc2ca..0321bf362 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -332,11 +332,15 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody case ElementType.ValueType: break; case ElementType.String: - // "" is stored as null, and null is stored as (int)0 - if (constant.Value is int && (int)constant.Value == 0) - constant.Value = null; - else if (constant.Value == null) - constant.Value = string.Empty; + if (PdbFileKind == PdbFileKind.WindowsPDB) { + // "" is stored as null, and null is stored as (int)0 + if (constant.Value is int && (int)constant.Value == 0) + constant.Value = null; + else if (constant.Value == null) + constant.Value = string.Empty; + } + else + Debug.Assert(PdbFileKind == PdbFileKind.PortablePDB || PdbFileKind == PdbFileKind.EmbeddedPortablePDB); break; case ElementType.Object: case ElementType.Class: From a24883e70f740a0d5226f79c5c454fb210b14c17 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 06:28:32 +0100 Subject: [PATCH 088/511] Don't write empty scopes, fixes #157 --- src/DotNet/Writer/MetaData.cs | 52 +++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 4e7e49f60..6ecf63372 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -1825,20 +1825,23 @@ void WriteMethodBodies() { if (cilBody != null) { var pdbMethod = cilBody.PdbMethod; if (pdbMethod != null) { - serializerMethodContext.SetBody(method); - scopeStack.Add(pdbMethod.Scope); - while (scopeStack.Count > 0) { - var scope = scopeStack[scopeStack.Count - 1]; - scopeStack.RemoveAt(scopeStack.Count - 1); - scopeStack.AddRange(scope.Scopes); - uint scopeStart = serializerMethodContext.GetOffset(scope.Start); - uint scopeEnd = serializerMethodContext.GetOffset(scope.End); - methodScopeDebugInfos.Add(new MethodScopeDebugInfo() { - MethodRid = rid, - Scope = scope, - ScopeStart = scopeStart, - ScopeLength = scopeEnd - scopeStart, - }); + // We don't need to write empty scopes + if (!IsEmptyRootScope(cilBody, pdbMethod.Scope)) { + serializerMethodContext.SetBody(method); + scopeStack.Add(pdbMethod.Scope); + while (scopeStack.Count > 0) { + var scope = scopeStack[scopeStack.Count - 1]; + scopeStack.RemoveAt(scopeStack.Count - 1); + scopeStack.AddRange(scope.Scopes); + uint scopeStart = serializerMethodContext.GetOffset(scope.Start); + uint scopeEnd = serializerMethodContext.GetOffset(scope.End); + methodScopeDebugInfos.Add(new MethodScopeDebugInfo() { + MethodRid = rid, + Scope = scope, + ScopeStart = scopeStart, + ScopeLength = scopeEnd - scopeStart, + }); + } } } } @@ -1884,6 +1887,27 @@ void WriteMethodBodies() { Listener.OnMetaDataEvent(this, MetaDataEvent.WriteMethodBodies0 + notifyNum++); } + static bool IsEmptyRootScope(CilBody cilBody, PdbScope scope) { + if (scope.Variables.Count != 0) + return false; + if (scope.Constants.Count != 0) + return false; + if (scope.Namespaces.Count != 0) + return false; + if (scope.ImportScope != null) + return false; + if (scope.Scopes.Count != 0) + return false; + if (scope.CustomDebugInfos.Count != 0) + return false; + if (scope.End != null) + return false; + if (cilBody.Instructions.Count != 0 && cilBody.Instructions[0] != scope.Start) + return false; + + return true; + } + /// /// Checks whether a list is empty or whether it contains only nulls /// From 389438b5bd545c4a2d387f5c7b6f367890882ec6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 06:28:41 +0100 Subject: [PATCH 089/511] Set new version --- src/Properties/AssemblyInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index e191df5c8..e85ff4917 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -16,5 +16,5 @@ [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] -[assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.0")] +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] From af4aaeac823ae53b790c92c033e764fdde90dfdd Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Feb 2018 18:58:31 +0100 Subject: [PATCH 090/511] Throw if #US heap is too big --- src/DotNet/Writer/USHeap.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index b4fe3334e..de200a5bc 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -103,6 +103,8 @@ uint AddToCache(string s) { cached.Add(s); cachedDict[s] = offset = nextOffset; nextOffset += (uint)GetRawDataSize(s); + if (offset > 0x00FFFFFF) + throw new ModuleWriterException("#US heap is too big"); return offset; } From 92a4dc0406a20b38b4f1df8376b856bb971811ba Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 25 Feb 2018 14:24:04 +0100 Subject: [PATCH 091/511] Add Constant.Padding column --- src/DotNet/MD/DotNetTableSizes.cs | 7 ++++--- src/DotNet/MD/MetaData.cs | 2 +- src/DotNet/MD/RawTableRows.cs | 10 ++++++---- src/DotNet/MD/TablesStream_Read.cs | 8 ++++---- src/DotNet/Writer/MDTableWriter.cs | 28 +++++++++------------------- 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index 2845ca8fb..d3877fd88 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -36,7 +36,7 @@ public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IListTable /// Row public static void Write(this BinaryWriter writer, MetaData metadata, IMDTable table, IRawRow row) { - if (table.Table == Table.Constant) { - var cols = table.TableInfo.Columns; - var row2 = (RawConstantRow)row; - writer.Write(row2.Type); - writer.Write(row2.Padding); - cols[1].Write(writer, row2.Parent); - cols[2].Write(writer, row2.Value); - } - else { - var cols = table.TableInfo.Columns; - var stringsHeap = metadata.StringsHeap; - foreach (var col in cols) { - if (col.ColumnSize == ColumnSize.Strings) - col.Write(writer, stringsHeap.GetOffset(row.Read(col.Index))); - else - col.Write(writer, row.Read(col.Index)); - } + var cols = table.TableInfo.Columns; + var stringsHeap = metadata.StringsHeap; + foreach (var col in cols) { + if (col.ColumnSize == ColumnSize.Strings) + col.Write(writer, stringsHeap.GetOffset(row.Read(col.Index))); + else + col.Write(writer, row.Read(col.Index)); } } @@ -296,8 +286,8 @@ public static void Write(this BinaryWriter writer, MetaData metadata, MDTable Date: Thu, 1 Mar 2018 19:36:28 +0100 Subject: [PATCH 092/511] Make sure the rid fits in 24 bits --- src/DotNet/ModuleDef.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 8e4853e9b..6924d630f 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1004,9 +1004,10 @@ public T ForceUpdateRowId(T tableRow) where T : IMDTokenProvider { } uint GetNextFreeRid(Table table) { + var lastUsedRids = this.lastUsedRids; if ((uint)table >= lastUsedRids.Length) return 0; - return (uint)Interlocked.Increment(ref lastUsedRids[(int)table]); + return (uint)Interlocked.Increment(ref lastUsedRids[(int)table]) & 0x00FFFFFF; } /// From 72555acc1d8842ac3805c86a93cbb2a14080f10b Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 4 Mar 2018 16:11:51 +0100 Subject: [PATCH 093/511] Support managed exported functions, fixes #87 --- README.md | 14 + src/DotNet/CpuArch.cs | 394 ++++++++++++++ src/DotNet/MethodDef.cs | 11 + src/DotNet/MethodExportInfo.cs | 115 ++++ src/DotNet/MethodExportInfoProvider.cs | 163 ++++++ src/DotNet/ModuleDefMD.cs | 11 + src/DotNet/Writer/ChunkListBase.cs | 20 +- src/DotNet/Writer/IChunk.cs | 2 + src/DotNet/Writer/ImageCor20Header.cs | 4 +- src/DotNet/Writer/ImportAddressTable.cs | 27 +- src/DotNet/Writer/ImportDirectory.cs | 27 +- src/DotNet/Writer/ManagedExportsWriter.cs | 607 ++++++++++++++++++++++ src/DotNet/Writer/MetaData.cs | 14 +- src/DotNet/Writer/ModuleWriter.cs | 85 +-- src/DotNet/Writer/ModuleWriterBase.cs | 28 +- src/DotNet/Writer/NativeModuleWriter.cs | 6 +- src/DotNet/Writer/PEHeaders.cs | 37 +- src/DotNet/Writer/RelocDirectory.cs | 100 +++- src/DotNet/Writer/StartupStub.cs | 57 +- src/dnlib.csproj | 4 + 20 files changed, 1638 insertions(+), 88 deletions(-) create mode 100644 src/DotNet/CpuArch.cs create mode 100644 src/DotNet/MethodExportInfo.cs create mode 100644 src/DotNet/MethodExportInfoProvider.cs create mode 100644 src/DotNet/Writer/ManagedExportsWriter.cs diff --git a/README.md b/README.md index 751fb5a8b..84277625a 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,20 @@ Enhanced strong name signing with key migration: mod.Write(@"C:\out\file.dll", opts); ``` +Exporting managed methods (DllExport) +------------------------------------- + +dnlib supports exporting managed methods so the managed DLL file can be loaded by native code and then executed. .NET Framework supports this feature, but there's no guarantee that other CLRs (eg. .NET Core or Mono/Unity) support this feature. + +The `MethodDef` class has an `ExportInfo` property. If it gets initialized, the method gets exported when saving the module. At most 65536 (2^16) methods can be exported. This is a PE file limitation, not a dnlib limitation. + +The method's calling convention should also be changed to eg. stdcall, or cdecl, see `MethodDef.MethodSig.CallingConvention`. Exported methods should not be generic. + +Requirements: + +- The assembly platform must be x86, x64, IA-64 or ARM (ARM64 isn't supported at the moment). AnyCPU assemblies are not supported. This is as simple as changing (if needed) `ModuleWriterOptions.PEHeadersOptions.Machine` when saving the file. x86 files should set `32-bit required` flag and clear `32-bit preferred` flag in the COR20 header. +- It must be a DLL file (see `ModuleWriterOptions.PEHeadersOptions.Characteristics`). The file will fail to load at runtime if it's an EXE file. + Type classes ------------ diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs new file mode 100644 index 000000000..1c07a27a0 --- /dev/null +++ b/src/DotNet/CpuArch.cs @@ -0,0 +1,394 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using dnlib.DotNet.Writer; +using dnlib.IO; +using dnlib.PE; + +namespace dnlib.DotNet { + enum StubType { + Export, + EntryPoint, + } + + abstract class CpuArch { + static readonly Dictionary toCpuArch = new Dictionary { + // To support a new CPU arch, the easiest way is to check coreclr/src/ilasm/writer.cpp or + // coreclr/src/dlls/mscorpe/stubs.h, eg. ExportStubAMD64Template, ExportStubX86Template, + // ExportStubARMTemplate, ExportStubIA64Template, or use ilasm to generate a file with + // exports and check the stub + { Machine.I386, new X86CpuArch() }, + { Machine.AMD64, new X64CpuArch() }, + { Machine.IA64, new ItaniumCpuArch() }, + { Machine.ARMNT, new ArmCpuArch() }, + //TODO: Support ARM64 + // { Machine.ARM64, new Arm64CpuArch() }, + }; + + /// + /// Gets the required alignment for the stubs, must be a power of 2 + /// + /// Stub type + /// + public abstract uint GetStubAlignment(StubType stubType); + + /// + /// Gets the size of a stub, it doesn't have to be a multiple of + /// + /// Stub type + /// + public abstract uint GetStubSize(StubType stubType); + + /// + /// Gets the offset of the code (entry point) relative to the start of the stub + /// + /// Stub type + /// + public abstract uint GetStubCodeOffset(StubType stubType); + + public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { + return toCpuArch.TryGetValue(machine, out cpuArch); + } + + /// + /// Gets the RVA of the func field that the stub jumps to + /// + /// Reader, positioned at the stub func + /// PE image + /// Updated with RVA of func field + /// + public bool TryGetExportedRvaFromStub(IBinaryReader reader, IPEImage peImage, out uint funcRva) { + bool b = TryGetExportedRvaFromStubCore(reader, peImage, out funcRva); + Debug.Assert(b); + return b; + } + + protected abstract bool TryGetExportedRvaFromStubCore(IBinaryReader reader, IPEImage peImage, out uint funcRva); + + /// + /// Writes stub relocs, if needed + /// + /// Stub type + /// Reloc directory + /// The chunk where this stub will be written to + /// Offset of this stub in + public abstract void WriteStubRelocs(StubType stubType, RelocDirectory relocDirectory, IChunk chunk, uint stubOffset); + + /// + /// Writes the stub that jumps to the managed function + /// + /// Stub type + /// Writer + /// Image base + /// RVA of this stub + /// RVA of a pointer-sized field that contains the absolute address of the managed function + public abstract void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva); + } + + sealed class X86CpuArch : CpuArch { + public override uint GetStubAlignment(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 4; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubSize(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 2/*padding*/ + 6; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubCodeOffset(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 2/*padding*/; + default: + throw new ArgumentOutOfRangeException(); + } + } + + protected override bool TryGetExportedRvaFromStubCore(IBinaryReader reader, IPEImage peImage, out uint funcRva) { + funcRva = 0; + + // FF25xxxxxxxx jmp DWORD PTR [xxxxxxxx] + if (reader.ReadUInt16() != 0x25FF) + return false; + funcRva = reader.ReadUInt32() - (uint)peImage.ImageNTHeaders.OptionalHeader.ImageBase; + return true; + } + + public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDirectory, IChunk chunk, uint stubOffset) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + relocDirectory.Add(chunk, stubOffset + 4); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + writer.Write((ushort)0);// padding + writer.Write((ushort)0x25FF); + writer.Write((uint)imageBase + managedFuncRva); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + } + } + + sealed class X64CpuArch : CpuArch { + public override uint GetStubAlignment(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 4; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubSize(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 2/*padding*/ + 12; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubCodeOffset(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 2/*padding*/; + default: + throw new ArgumentOutOfRangeException(); + } + } + + protected override bool TryGetExportedRvaFromStubCore(IBinaryReader reader, IPEImage peImage, out uint funcRva) { + funcRva = 0; + + // 48A1xxxxxxxxxxxxxxxx movabs rax,[xxxxxxxxxxxxxxxx] + // FFE0 jmp rax + if (reader.ReadUInt16() != 0xA148) + return false; + ulong absAddr = reader.ReadUInt64(); + if (reader.ReadUInt16() != 0xE0FF) + return false; + ulong rva = absAddr - peImage.ImageNTHeaders.OptionalHeader.ImageBase; + if (rva > uint.MaxValue) + return false; + funcRva = (uint)rva; + return true; + } + + public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDirectory, IChunk chunk, uint stubOffset) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + relocDirectory.Add(chunk, stubOffset + 4); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + writer.Write((ushort)0);// padding + writer.Write((ushort)0xA148); + writer.Write(imageBase + managedFuncRva); + writer.Write((ushort)0xE0FF); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + sealed class ItaniumCpuArch : CpuArch { + public override uint GetStubAlignment(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 16; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubSize(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 0x30; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubCodeOffset(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 0x20; + default: + throw new ArgumentOutOfRangeException(); + } + } + + protected override bool TryGetExportedRvaFromStubCore(IBinaryReader reader, IPEImage peImage, out uint funcRva) { + funcRva = 0; + + // From ExportStubIA64Template in coreclr/src/ilasm/writer.cpp + // + // ld8 r9 = [gp] ;; + // ld8 r10 = [r9],8 + // nop.i ;; + // ld8 gp = [r9] + // mov b6 = r10 + // br.cond.sptk.few b6 + // + // 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, + // 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, + // 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, + // 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00, + // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of the template + // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //address of VTFixup slot + ulong addrTemplate = reader.ReadUInt64(); + ulong absAddr = reader.ReadUInt64(); + reader.Position = (long)peImage.ToFileOffset((RVA)(addrTemplate - peImage.ImageNTHeaders.OptionalHeader.ImageBase)); + if (reader.ReadUInt64() != 0x40A010180200480BUL) + return false; + if (reader.ReadUInt64() != 0x0004000000283024UL) + return false; + if (reader.ReadUInt64() != 0x5060101812000810UL) + return false; + if (reader.ReadUInt64() != 0x0080006000038004UL) + return false; + + ulong rva = absAddr - peImage.ImageNTHeaders.OptionalHeader.ImageBase; + if (rva > uint.MaxValue) + return false; + funcRva = (uint)rva; + return true; + } + + public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDirectory, IChunk chunk, uint stubOffset) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + relocDirectory.Add(chunk, stubOffset + 0x20); + relocDirectory.Add(chunk, stubOffset + 0x28); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + writer.Write(0x40A010180200480BUL); + writer.Write(0x0004000000283024UL); + writer.Write(0x5060101812000810UL); + writer.Write(0x0080006000038004UL); + writer.Write(imageBase + stubRva); + writer.Write(imageBase + managedFuncRva); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + sealed class ArmCpuArch : CpuArch { + public override uint GetStubAlignment(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 4; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubSize(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 8; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override uint GetStubCodeOffset(StubType stubType) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + return 0; + default: + throw new ArgumentOutOfRangeException(); + } + } + + protected override bool TryGetExportedRvaFromStubCore(IBinaryReader reader, IPEImage peImage, out uint funcRva) { + funcRva = 0; + + // DFF800F0 ldr.w pc,[pc] + // xxxxxxxx + if (reader.ReadUInt32() != 0xF000F8DF) + return false; + funcRva = reader.ReadUInt32() - (uint)peImage.ImageNTHeaders.OptionalHeader.ImageBase; + return true; + } + + public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDirectory, IChunk chunk, uint stubOffset) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + relocDirectory.Add(chunk, stubOffset + 4); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + switch (stubType) { + case StubType.Export: + case StubType.EntryPoint: + writer.Write(0xF000F8DF); + writer.Write((uint)imageBase + managedFuncRva); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } +} diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 9c85b814e..ba8d5ca6f 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -357,6 +357,16 @@ protected virtual void InitializeOverrides() { Interlocked.CompareExchange(ref overrides, ThreadSafeListCreator.Create(), null); } + /// + /// Gets the export info or null if the method isn't exported to unmanaged code. + /// + public MethodExportInfo ExportInfo { + get { return exportInfo; } + set { exportInfo = value; } + } + /// + protected MethodExportInfo exportInfo; + /// public bool HasCustomAttributes { get { return CustomAttributes.Count > 0; } @@ -1336,6 +1346,7 @@ public MethodDefMD(ModuleDefMD readerModule, uint rid) { this.declaringType2 = readerModule.GetOwnerType(this); this.signature = readerModule.ReadSignature(signature, new GenericParamContext(declaringType2, this)); this.parameterList = new ParameterList(this, declaringType2); + this.exportInfo = readerModule.GetExportInfo(rid); } internal MethodDefMD InitializeAll() { diff --git a/src/DotNet/MethodExportInfo.cs b/src/DotNet/MethodExportInfo.cs new file mode 100644 index 000000000..e7d7bd406 --- /dev/null +++ b/src/DotNet/MethodExportInfo.cs @@ -0,0 +1,115 @@ +// dnlib: See LICENSE.txt for more info + +using System.Diagnostics; + +namespace dnlib.DotNet { + /// + /// Contains the name and ordinal of a method that gets exported to unmanaged code. + /// + [DebuggerDisplay("{Ordinal} {Name} {Options}")] + public sealed class MethodExportInfo { + MethodExportInfoOptions options; + ushort? ordinal; + string name; + + const MethodExportInfoOptions DefaultOptions = MethodExportInfoOptions.FromUnmanaged; + + /// + /// Gets the ordinal or null + /// + public ushort? Ordinal { + get { return ordinal; } + set { ordinal = value; } + } + + /// + /// Gets the name. If it's null, and is also null, the name of the method + /// () is used as the exported name. + /// + public string Name { + get { return name; } + set { name = value; } + } + + /// + /// Gets the options + /// + public MethodExportInfoOptions Options { + get { return options; } + set { options = value; } + } + + /// + /// Constructor + /// + public MethodExportInfo() { + options = DefaultOptions; + } + + /// + /// Constructor + /// + /// Name or null to export by ordinal + public MethodExportInfo(string name) { + options = DefaultOptions; + this.name = name; + } + + /// + /// Constructor + /// + /// Ordinal + public MethodExportInfo(ushort ordinal) { + options = DefaultOptions; + this.ordinal = ordinal; + } + + /// + /// Constructor + /// + /// Name or null to export by ordinal + /// Ordinal or null to export by name + public MethodExportInfo(string name, ushort? ordinal) { + options = DefaultOptions; + this.name = name; + this.ordinal = ordinal; + } + + /// + /// Constructor + /// + /// Name or null to export by ordinal + /// Ordinal or null to export by name + /// Options + public MethodExportInfo(string name, ushort? ordinal, MethodExportInfoOptions options) { + this.options = options; + this.name = name; + this.ordinal = ordinal; + } + } + + /// + /// Exported method options + /// + public enum MethodExportInfoOptions { + /// + /// No bit is set + /// + None = 0, + + /// + /// Transition from unmanaged code + /// + FromUnmanaged = 0x00000001, + + /// + /// Also retain app domain + /// + FromUnmanagedRetainAppDomain = 0x00000002, + + /// + /// Call most derived method + /// + CallMostDerived = 0x00000004, + } +} diff --git a/src/DotNet/MethodExportInfoProvider.cs b/src/DotNet/MethodExportInfoProvider.cs new file mode 100644 index 000000000..9fd9477a3 --- /dev/null +++ b/src/DotNet/MethodExportInfoProvider.cs @@ -0,0 +1,163 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Collections.Generic; +using System.IO; +using dnlib.PE; +using dnlib.IO; +using System.Diagnostics; +using System.Text; + +namespace dnlib.DotNet { + sealed class MethodExportInfoProvider { + readonly Dictionary toInfo; + + public MethodExportInfoProvider(ModuleDefMD module) { + toInfo = new Dictionary(); + try { + Initialize(module); + } + catch (OutOfMemoryException) { + } + catch (IOException) { + } + } + + void Initialize(ModuleDefMD module) { + var vtblHdr = module.MetaData.ImageCor20Header.VTableFixups; + if (vtblHdr.VirtualAddress == 0 || vtblHdr.Size == 0) + return; + + var peImage = module.MetaData.PEImage; + var exportHdr = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[0]; + if (exportHdr.VirtualAddress == 0 || exportHdr.Size < 0x28) + return; + + CpuArch cpuArch; + if (!CpuArch.TryGetCpuArch(peImage.ImageNTHeaders.FileHeader.Machine, out cpuArch)) { + Debug.Fail(string.Format("Exported methods: Unsupported machine: {0}", peImage.ImageNTHeaders.FileHeader.Machine)); + return; + } + + using (var reader = peImage.CreateFullStream()) { + var offsetToInfo = GetOffsetToExportInfoDictionary(reader, peImage, exportHdr, cpuArch); + reader.Position = (long)peImage.ToFileOffset(vtblHdr.VirtualAddress); + long endPos = reader.Position + vtblHdr.Size; + while (reader.Position + 8 <= endPos && reader.CanRead(8)) { + var tableRva = (RVA)reader.ReadUInt32(); + int numSlots = reader.ReadUInt16(); + var flags = (VTableFlags)reader.ReadUInt16(); + bool is64bit = (flags & VTableFlags._64Bit) != 0; + var exportOptions = ToMethodExportInfoOptions(flags); + + var pos = reader.Position; + reader.Position = (long)peImage.ToFileOffset(tableRva); + int slotSize = is64bit ? 8 : 4; + while (numSlots-- > 0 && reader.CanRead(slotSize)) { + var tokenPos = reader.Position; + MethodExportInfo exportInfo; + uint token = reader.ReadUInt32(); + bool b = offsetToInfo.TryGetValue(tokenPos, out exportInfo); + Debug.Assert(token == 0 || b); + if (b) { + exportInfo = new MethodExportInfo(exportInfo.Name, exportInfo.Ordinal, exportOptions); + toInfo[token] = exportInfo; + } + if (slotSize == 8) + reader.ReadUInt32(); + } + reader.Position = pos; + } + } + } + + static MethodExportInfoOptions ToMethodExportInfoOptions(VTableFlags flags) { + var res = MethodExportInfoOptions.None; + if ((flags & VTableFlags.FromUnmanaged) != 0) + res |= MethodExportInfoOptions.FromUnmanaged; + if ((flags & VTableFlags.FromUnmanagedRetainAppDomain) != 0) + res |= MethodExportInfoOptions.FromUnmanagedRetainAppDomain; + if ((flags & VTableFlags.CallMostDerived) != 0) + res |= MethodExportInfoOptions.CallMostDerived; + return res; + } + + static Dictionary GetOffsetToExportInfoDictionary(IImageStream reader, IPEImage peImage, ImageDataDirectory exportHdr, CpuArch cpuArch) { + reader.Position = (long)peImage.ToFileOffset(exportHdr.VirtualAddress); + // Skip Characteristics(4), TimeDateStamp(4), MajorVersion(2), MinorVersion(2), Name(4) + reader.Position += 16; + uint ordinalBase = reader.ReadUInt32(); + int numFuncs = reader.ReadInt32(); + int numNames = reader.ReadInt32(); + long offsetOfFuncs = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); + long offsetOfNames = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); + long offsetOfNameIndexes = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); + + var names = ReadNames(reader, peImage, numNames, offsetOfNames, offsetOfNameIndexes); + reader.Position = offsetOfFuncs; + var allInfos = new MethodExportInfo[numFuncs]; + var dict = new Dictionary(numFuncs); + for (int i = 0; i < allInfos.Length; i++) { + var currOffset = reader.Position; + var nextOffset = reader.Position + 4; + uint funcRva; + reader.Position = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); + bool rvaValid = cpuArch.TryGetExportedRvaFromStub(reader, peImage, out funcRva); + long funcOffset = rvaValid ? (long)peImage.ToFileOffset((RVA)funcRva) : 0; + var exportInfo = new MethodExportInfo((ushort)(ordinalBase + (uint)i)); + if (funcOffset != 0) + dict[funcOffset] = exportInfo; + allInfos[i] = exportInfo; + reader.Position = nextOffset; + } + + foreach (var info in names) { + int index = info.Index; + if ((uint)index >= (uint)numFuncs) + continue; + allInfos[index].Ordinal = null; + allInfos[index].Name = info.Name; + } + + return dict; + } + + static NameAndIndex[] ReadNames(IImageStream reader, IPEImage peImage, int numNames, long offsetOfNames, long offsetOfNameIndexes) { + var names = new NameAndIndex[numNames]; + + reader.Position = offsetOfNameIndexes; + for (int i = 0; i < names.Length; i++) + names[i].Index = reader.ReadUInt16(); + + var currentOffset = offsetOfNames; + for (int i = 0; i < names.Length; i++, currentOffset += 4) { + reader.Position = currentOffset; + long offsetOfName = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); + names[i].Name = ReadMethodNameASCIIZ(reader, offsetOfName); + } + + return names; + } + + struct NameAndIndex { + public string Name; + public int Index; + } + + // If this method gets updated, also update the writer (ManagedExportsWriter) + static string ReadMethodNameASCIIZ(IImageStream reader, long offset) { + reader.Position = offset; + var stringData = reader.ReadBytesUntilByte(0); + return Encoding.UTF8.GetString(stringData); + } + + public MethodExportInfo GetMethodExportInfo(uint token) { + if (toInfo.Count == 0) + return null; + MethodExportInfo info; + if (toInfo.TryGetValue(token, out info)) + return new MethodExportInfo(info.Name, info.Ordinal, info.Options); + return null; + } + } +} diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 5951395cf..38ee4226e 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1940,6 +1940,17 @@ public string ReadUserString(uint token) { return USStream.ReadNoNull(token & 0x00FFFFFF); } + internal MethodExportInfo GetExportInfo(uint methodRid) { + if (methodExportInfoProvider == null) + InitializeMethodExportInfoProvider(); + return methodExportInfoProvider.GetMethodExportInfo(0x06000000 + methodRid); + } + + void InitializeMethodExportInfoProvider() { + Interlocked.CompareExchange(ref methodExportInfoProvider, new MethodExportInfoProvider(this), null); + } + MethodExportInfoProvider methodExportInfoProvider; + /// /// Writes the mixed-mode module to a file on disk. If the file exists, it will be overwritten. /// diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index 0e7d89867..ff81a54dd 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -89,12 +89,18 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { offset += paddingF; rva += paddingV; elem.chunk.SetOffset(offset, rva); - uint chunkLenF = elem.chunk.GetFileLength(); - uint chunkLenV = elem.chunk.GetVirtualSize(); - offset += chunkLenF; - rva += chunkLenV; - length += paddingF + chunkLenF; - virtualSize += paddingV + chunkLenV; + if (elem.chunk.GetVirtualSize() == 0) { + offset -= paddingF; + rva -= paddingV; + } + else { + uint chunkLenF = elem.chunk.GetFileLength(); + uint chunkLenV = elem.chunk.GetVirtualSize(); + offset += chunkLenF; + rva += chunkLenV; + length += paddingF + chunkLenF; + virtualSize += paddingV + chunkLenV; + } } } @@ -112,6 +118,8 @@ public uint GetVirtualSize() { public void WriteTo(BinaryWriter writer) { FileOffset offset2 = offset; foreach (var elem in chunks) { + if (elem.chunk.GetVirtualSize() == 0) + continue; int paddingF = (int)offset2.AlignUp(elem.alignment) - (int)offset2; writer.WriteZeros(paddingF); elem.chunk.VerifyWriteTo(writer); diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index a9f88a1fe..c4c735497 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -59,6 +59,8 @@ public static partial class Extensions { /// Not all bytes were written public static void VerifyWriteTo(this IChunk chunk, BinaryWriter writer) { long pos = writer.BaseStream.Position; + // Uncomment this to add some debug info, useful when comparing old vs new version + //System.Diagnostics.Debug.WriteLine(string.Format(" RVA 0x{0:X8} OFFS 0x{1:X8} VSIZE 0x{2:X8} {3}", (uint)chunk.RVA, (uint)chunk.FileOffset, chunk.GetVirtualSize(), chunk.GetType().FullName)); chunk.WriteTo(writer); if (writer.BaseStream.Position - pos != chunk.GetFileLength()) throw new IOException("Did not write all bytes"); diff --git a/src/DotNet/Writer/ImageCor20Header.cs b/src/DotNet/Writer/ImageCor20Header.cs index 0610a9b92..f9eb362f5 100644 --- a/src/DotNet/Writer/ImageCor20Header.cs +++ b/src/DotNet/Writer/ImageCor20Header.cs @@ -90,6 +90,8 @@ public sealed class ImageCor20Header : IChunk { /// public StrongNameSignature StrongNameSignature { get; set; } + internal IChunk VtableFixups { get; set; } + /// public FileOffset FileOffset { get { return offset; } @@ -135,7 +137,7 @@ public void WriteTo(BinaryWriter writer) { writer.WriteDataDirectory(NetResources); writer.WriteDataDirectory(StrongNameSignature); writer.WriteDataDirectory(null); // Code manager table - writer.WriteDataDirectory(null); // Vtable fixups + writer.WriteDataDirectory(VtableFixups); writer.WriteDataDirectory(null); // Export address table jumps writer.WriteDataDirectory(null); // Managed native header } diff --git a/src/DotNet/Writer/ImportAddressTable.cs b/src/DotNet/Writer/ImportAddressTable.cs index ab183bf58..3b329795b 100644 --- a/src/DotNet/Writer/ImportAddressTable.cs +++ b/src/DotNet/Writer/ImportAddressTable.cs @@ -9,6 +9,7 @@ namespace dnlib.DotNet.Writer { /// Import address table chunk /// public sealed class ImportAddressTable : IChunk { + readonly bool is64bit; FileOffset offset; RVA rva; @@ -27,6 +28,16 @@ public RVA RVA { get { return rva; } } + internal bool Enable { get; set; } + + /// + /// Constructor + /// + /// true if it's a 64-bit PE file, false if it's a 32-bit PE file + public ImportAddressTable(bool is64bit) { + this.is64bit = is64bit; + } + /// public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; @@ -35,7 +46,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetFileLength() { - return 8; + if (!Enable) + return 0; + return is64bit ? 16U : 8; } /// @@ -45,8 +58,16 @@ public uint GetVirtualSize() { /// public void WriteTo(BinaryWriter writer) { - writer.Write((uint)ImportDirectory.CorXxxMainRVA); - writer.Write(0); + if (!Enable) + return; + if (is64bit) { + writer.Write((ulong)(uint)ImportDirectory.CorXxxMainRVA); + writer.Write(0UL); + } + else { + writer.Write((uint)ImportDirectory.CorXxxMainRVA); + writer.Write(0); + } } } } diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index ffc16dea3..d23e377e5 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -10,6 +10,7 @@ namespace dnlib.DotNet.Writer { /// Import directory chunk /// public sealed class ImportDirectory : IChunk { + readonly bool is64bit; FileOffset offset; RVA rva; bool isExeFile; @@ -56,8 +57,18 @@ public RVA RVA { get { return rva; } } + internal bool Enable { get; set; } + const uint STRINGS_ALIGNMENT = 16; + /// + /// Constructor + /// + /// true if it's a 64-bit PE file, false if it's a 32-bit PE file + public ImportDirectory(bool is64bit) { + this.is64bit = is64bit; + } + /// public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; @@ -65,7 +76,7 @@ public void SetOffset(FileOffset offset, RVA rva) { length = 0x28; importLookupTableRVA = rva + length; - length += 8; + length += is64bit ? 16U : 8; stringsPadding = (int)(rva.AlignUp(STRINGS_ALIGNMENT) - rva); length += (uint)stringsPadding; @@ -78,6 +89,8 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetFileLength() { + if (!Enable) + return 0; return length; } @@ -88,6 +101,8 @@ public uint GetVirtualSize() { /// public void WriteTo(BinaryWriter writer) { + if (!Enable) + return; writer.Write((uint)importLookupTableRVA); writer.Write(0); // DateTimeStamp writer.Write(0); // ForwarderChain @@ -98,8 +113,14 @@ public void WriteTo(BinaryWriter writer) { writer.Write(0); // ImportLookupTable - writer.Write((uint)corXxxMainRVA); - writer.Write(0); + if (is64bit) { + writer.Write((ulong)(uint)corXxxMainRVA); + writer.Write(0UL); + } + else { + writer.Write((uint)corXxxMainRVA); + writer.Write(0); + } writer.WriteZeros(stringsPadding); writer.Write((ushort)0); diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs new file mode 100644 index 000000000..96a69bc8f --- /dev/null +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -0,0 +1,607 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using dnlib.IO; +using dnlib.PE; + +namespace dnlib.DotNet.Writer { + sealed class ManagedExportsWriter { + const uint DEFAULT_VTBL_FIXUPS_ALIGNMENT = 4; + const uint DEFAULT_SDATA_ALIGNMENT = 8; + const StubType stubType = StubType.Export; + readonly string moduleName; + readonly Machine machine; + readonly RelocDirectory relocDirectory; + readonly MetaData metaData; + readonly PEHeaders peHeaders; + readonly LogError logError; + readonly VtableFixupsChunk vtableFixups; + readonly StubsChunk stubsChunk; + readonly SdataChunk sdataChunk; + readonly ExportDir exportDir; + readonly List vtables; + readonly List allMethodInfos; + readonly List sortedNameInfos; + readonly CpuArch cpuArch; + uint exportDirOffset; + + bool Is64Bit { + get { return machine == Machine.IA64 || machine == Machine.AMD64 || machine == Machine.ARM64; } + } + + FileOffset ExportDirOffset { + get { return sdataChunk.FileOffset + exportDirOffset; } + } + + RVA ExportDirRVA { + get { return sdataChunk.RVA + exportDirOffset; } + } + + uint ExportDirSize { + get { return 0x28; } + } + + internal bool HasExports { + get { return vtables.Count != 0; } + } + + sealed class ExportDir : IChunk { + readonly ManagedExportsWriter owner; + + public FileOffset FileOffset { + get { return owner.ExportDirOffset; } + } + + public RVA RVA { + get { return owner.ExportDirRVA; } + } + + public ExportDir(ManagedExportsWriter owner) { + this.owner = owner; + } + + void IChunk.SetOffset(FileOffset offset, RVA rva) { + throw new NotSupportedException(); + } + + public uint GetFileLength() { + return owner.ExportDirSize; + } + + public uint GetVirtualSize() { + return GetFileLength(); + } + + void IChunk.WriteTo(BinaryWriter writer) { + throw new NotSupportedException(); + } + } + + sealed class VtableFixupsChunk : IChunk { + readonly ManagedExportsWriter owner; + FileOffset offset; + RVA rva; + internal uint length; + + public FileOffset FileOffset { + get { return offset; } + } + + public RVA RVA { + get { return rva; } + } + + public VtableFixupsChunk(ManagedExportsWriter owner) { + this.owner = owner; + } + + public void SetOffset(FileOffset offset, RVA rva) { + this.offset = offset; + this.rva = rva; + } + + public uint GetFileLength() { + return length; + } + + public uint GetVirtualSize() { + return GetFileLength(); + } + + public void WriteTo(BinaryWriter writer) { + owner.WriteVtableFixups(writer); + } + } + + sealed class StubsChunk : IChunk { + readonly ManagedExportsWriter owner; + FileOffset offset; + RVA rva; + internal uint length; + + public FileOffset FileOffset { + get { return offset; } + } + + public RVA RVA { + get { return rva; } + } + + public StubsChunk(ManagedExportsWriter owner) { + this.owner = owner; + } + + public void SetOffset(FileOffset offset, RVA rva) { + this.offset = offset; + this.rva = rva; + } + + public uint GetFileLength() { + return length; + } + + public uint GetVirtualSize() { + return GetFileLength(); + } + + public void WriteTo(BinaryWriter writer) { + owner.WriteStubs(writer); + } + } + + sealed class SdataChunk : IChunk { + readonly ManagedExportsWriter owner; + FileOffset offset; + RVA rva; + internal uint length; + + public FileOffset FileOffset { + get { return offset; } + } + + public RVA RVA { + get { return rva; } + } + + public SdataChunk(ManagedExportsWriter owner) { + this.owner = owner; + } + + public void SetOffset(FileOffset offset, RVA rva) { + this.offset = offset; + this.rva = rva; + } + + public uint GetFileLength() { + return length; + } + + public uint GetVirtualSize() { + return GetFileLength(); + } + + public void WriteTo(BinaryWriter writer) { + owner.WriteSdata(writer); + } + } + + internal delegate void LogError(string format, params object[] args); + + public ManagedExportsWriter(string moduleName, Machine machine, RelocDirectory relocDirectory, MetaData metaData, PEHeaders peHeaders, LogError logError) { + this.moduleName = moduleName; + this.machine = machine; + this.relocDirectory = relocDirectory; + this.metaData = metaData; + this.peHeaders = peHeaders; + this.logError = logError; + vtableFixups = new VtableFixupsChunk(this); + stubsChunk = new StubsChunk(this); + sdataChunk = new SdataChunk(this); + exportDir = new ExportDir(this); + vtables = new List(); + allMethodInfos = new List(); + sortedNameInfos = new List(); + // The error is reported later when we know that there's at least one exported method + CpuArch.TryGetCpuArch(machine, out cpuArch); + } + + internal void AddTextChunks(PESection textSection) { + textSection.Add(vtableFixups, DEFAULT_VTBL_FIXUPS_ALIGNMENT); + if (cpuArch != null) + textSection.Add(stubsChunk, cpuArch.GetStubAlignment(stubType)); + } + + internal void AddSdataChunks(PESection sdataSection) { + sdataSection.Add(sdataChunk, DEFAULT_SDATA_ALIGNMENT); + } + + internal void InitializeChunkProperties() { + if (allMethodInfos.Count == 0) + return; + peHeaders.ExportDirectory = exportDir; + peHeaders.ImageCor20Header.VtableFixups = vtableFixups; + } + + internal void AddExportedMethods(List methods, uint timestamp) { + if (methods.Count == 0) + return; + + // Only check for an unsupported machine when we know there's at least one exported method + if (cpuArch == null) { + logError("The module has exported methods but the CPU architecture isn't supported: {0} (0x{1:X4})", machine, (ushort)machine); + return; + } + if (methods.Count > 0x10000) { + logError("Too many methods have been exported. No more than 2^16 methods can be exported. Number of exported methods: {0}", methods.Count); + return; + } + + Initialize(methods, timestamp); + } + + sealed class MethodInfo { + public readonly MethodDef Method; + public readonly uint StubChunkOffset; + public readonly int Index; + public uint ManagedVtblOffset; + public uint NameOffset; + public int NameIndex; + public byte[] NameBytes; + public MethodInfo(MethodDef method, uint stubChunkOffset, int index) { + Method = method; + StubChunkOffset = stubChunkOffset; + Index = index; + } + } + + sealed class VTableInfo { + public uint SdataChunkOffset { get; set; } + public readonly VTableFlags Flags; + public readonly List Methods; + public VTableInfo(VTableFlags flags) { + Flags = flags; + Methods = new List(); + } + } + + void Initialize(List methods, uint timestamp) { + var dict = new Dictionary>(); + var baseFlags = Is64Bit ? VTableFlags._64Bit : VTableFlags._32Bit; + uint stubOffset = 0; + int index = 0; + uint stubAlignment = cpuArch.GetStubAlignment(stubType); + uint stubCodeOffset = cpuArch.GetStubCodeOffset(stubType); + uint stubSize = cpuArch.GetStubSize(stubType); + foreach (var method in methods) { + var exportInfo = method.ExportInfo; + Debug.Assert(exportInfo != null); + if (exportInfo == null) + continue; + + var flags = baseFlags; + if ((exportInfo.Options & MethodExportInfoOptions.FromUnmanaged) != 0) + flags |= VTableFlags.FromUnmanaged; + if ((exportInfo.Options & MethodExportInfoOptions.FromUnmanagedRetainAppDomain) != 0) + flags |= VTableFlags.FromUnmanagedRetainAppDomain; + if ((exportInfo.Options & MethodExportInfoOptions.CallMostDerived) != 0) + flags |= VTableFlags.CallMostDerived; + + List list; + if (!dict.TryGetValue((int)flags, out list)) + dict.Add((int)flags, list = new List()); + if (list.Count == 0 || list[list.Count - 1].Methods.Count >= ushort.MaxValue) + list.Add(new VTableInfo(flags)); + var info = new MethodInfo(method, stubOffset + stubCodeOffset, index); + allMethodInfos.Add(info); + list[list.Count - 1].Methods.Add(info); + stubOffset = (stubOffset + stubSize + stubAlignment - 1) & ~(stubAlignment - 1); + index++; + } + + foreach (var kv in dict) + vtables.AddRange(kv.Value); + + WriteSdataBlob(timestamp); + + vtableFixups.length = (uint)vtables.Count * 8; + stubsChunk.length = stubOffset; + sdataChunk.length = (uint)sdataBytesInfo.Data.Length; + + uint expectedOffset = 0; + foreach (var info in allMethodInfos) { + uint currentOffset = info.StubChunkOffset - stubCodeOffset; + if (expectedOffset != currentOffset) + throw new InvalidOperationException(); + cpuArch.WriteStubRelocs(stubType, relocDirectory, stubsChunk, currentOffset); + expectedOffset = (currentOffset + stubSize + stubAlignment - 1) & ~(stubAlignment - 1); + } + if (expectedOffset != stubOffset) + throw new InvalidOperationException(); + } + + struct NamesBlob { + readonly Dictionary nameOffsets; + readonly List names; + readonly List methodNameOffsets; + uint currentOffset; + int methodNamesCount; + bool methodNamesIsFrozen; + + public int MethodNamesCount { + get { return methodNamesCount; } + } + + public int TotalNamesCount { + get { return names.Count; } + } + + struct NameInfo { + public readonly uint Offset; + public readonly byte[] Bytes; + public NameInfo(uint offset, byte[] bytes) { + Offset = offset; + Bytes = bytes; + } + } + + public NamesBlob(bool dummy) { + nameOffsets = new Dictionary(StringComparer.Ordinal); + names = new List(); + methodNameOffsets = new List(); + currentOffset = 0; + methodNamesCount = 0; + methodNamesIsFrozen = false; + } + + public uint GetMethodNameOffset(string name, out byte[] bytes) { + if (methodNamesIsFrozen) + throw new InvalidOperationException(); + methodNamesCount++; + uint offset = GetOffset(name, out bytes); + methodNameOffsets.Add(offset); + return offset; + } + + public uint GetOtherNameOffset(string name) { + methodNamesIsFrozen = true; + byte[] bytes; + return GetOffset(name, out bytes); + } + + uint GetOffset(string name, out byte[] bytes) { + NameInfo nameInfo; + if (nameOffsets.TryGetValue(name, out nameInfo)) { + bytes = nameInfo.Bytes; + return nameInfo.Offset; + } + bytes = GetNameASCIIZ(name); + names.Add(bytes); + uint offset = currentOffset; + nameOffsets.Add(name, new NameInfo(offset, bytes)); + currentOffset += (uint)bytes.Length; + return offset; + } + + // If this method gets updated, also update the reader (MethodExportInfoProvider) + static byte[] GetNameASCIIZ(string name) { + Debug.Assert(name != null); + int size = Encoding.UTF8.GetByteCount(name); + var bytes = new byte[size + 1]; + Encoding.UTF8.GetBytes(name, 0, name.Length, bytes, 0); + if (bytes[bytes.Length - 1] != 0) + throw new ModuleWriterException(); + return bytes; + } + + public void Write(BinaryWriter writer) { + foreach (var name in names) + writer.Write(name); + } + + public uint[] GetMethodNameOffsets() { + return methodNameOffsets.ToArray(); + } + } + + struct SdataBytesInfo { + public byte[] Data; + public uint namesBlobStreamOffset; + public uint moduleNameOffset; + public uint exportDirmoduleNameStreamOffset; + public uint exportDiraddressOfFunctionsStreamOffset; + public uint addressOfFunctionsStreamOffset; + public uint addressOfNamesStreamOffset; + public uint addressOfNameOrdinalsStreamOffset; + public uint[] MethodNameOffsets; + } + SdataBytesInfo sdataBytesInfo; + + /// + /// Writes the .sdata blob. We could write the data in any order, but we write the data in the same order as ILASM + /// + /// PE timestamp + void WriteSdataBlob(uint timestamp) { + var stream = new MemoryStream(); + var writer = new BinaryWriter(stream); + + // Write all vtables (referenced from the .text section) + Debug.Assert((writer.BaseStream.Position & 7) == 0); + foreach (var vtbl in vtables) { + vtbl.SdataChunkOffset = (uint)writer.BaseStream.Position; + foreach (var info in vtbl.Methods) { + info.ManagedVtblOffset = (uint)writer.BaseStream.Position; + writer.Write(0x06000000 + metaData.GetRid(info.Method)); + if ((vtbl.Flags & VTableFlags._64Bit) != 0) + writer.Write(0U); + } + } + + var namesBlob = new NamesBlob(1 == 2); + int nameIndex = 0; + foreach (var info in allMethodInfos) { + var exportInfo = info.Method.ExportInfo; + var name = exportInfo.Name; + if (name == null) { + if (exportInfo.Ordinal != null) + continue; + name = info.Method.Name; + } + if (string.IsNullOrEmpty(name)) { + logError("Exported method name is null or empty, method: {0} (0x{1:X8})", info.Method, info.Method.MDToken.Raw); + continue; + } + info.NameOffset = namesBlob.GetMethodNameOffset(name, out info.NameBytes); + info.NameIndex = nameIndex++; + sortedNameInfos.Add(info); + } + sdataBytesInfo.MethodNameOffsets = namesBlob.GetMethodNameOffsets(); + sdataBytesInfo.moduleNameOffset = namesBlob.GetOtherNameOffset(moduleName); + + sortedNameInfos.Sort((a, b) => CompareTo(a.NameBytes, b.NameBytes)); + + uint ordinalBase = uint.MaxValue; + foreach (var info in allMethodInfos) { + if (info.Method.ExportInfo.Ordinal != null) + ordinalBase = Math.Min(ordinalBase, info.Method.ExportInfo.Ordinal.Value); + } + if (ordinalBase == uint.MaxValue) + ordinalBase = 0; + + // Write IMAGE_EXPORT_DIRECTORY + Debug.Assert((writer.BaseStream.Position & 3) == 0); + exportDirOffset = (uint)writer.BaseStream.Position; + writer.Write(0U); // Characteristics + writer.Write(timestamp); + writer.Write(0U); // MajorVersion, MinorVersion + sdataBytesInfo.exportDirmoduleNameStreamOffset = (uint)writer.BaseStream.Position; + writer.Write(0U); // Name + writer.Write(ordinalBase); // Base + writer.Write((uint)allMethodInfos.Count); // NumberOfFunctions + writer.Write(sdataBytesInfo.MethodNameOffsets.Length); // NumberOfNames + sdataBytesInfo.exportDiraddressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; + writer.Write(0U); // AddressOfFunctions + writer.Write(0U); // AddressOfNames + writer.Write(0U); // AddressOfNameOrdinals + + sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; + WriteZeroes(writer, allMethodInfos.Count * 4); + sdataBytesInfo.addressOfNamesStreamOffset = (uint)writer.BaseStream.Position; + WriteZeroes(writer, namesBlob.TotalNamesCount * 4); + sdataBytesInfo.addressOfNameOrdinalsStreamOffset = (uint)writer.BaseStream.Position; + WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 2); + sdataBytesInfo.namesBlobStreamOffset = (uint)writer.BaseStream.Position; + namesBlob.Write(writer); + + sdataBytesInfo.Data = stream.ToArray(); + } + + void WriteSdata(BinaryWriter writer) { + if (sdataBytesInfo.Data == null) + return; + PatchSdataBytesBlob(); + writer.Write(sdataBytesInfo.Data); + } + + void PatchSdataBytesBlob() { + uint rva = (uint)sdataChunk.RVA; + uint namesBaseOffset = rva + sdataBytesInfo.namesBlobStreamOffset; + + var writer = new BinaryWriter(new MemoryStream(sdataBytesInfo.Data)); + + writer.BaseStream.Position = sdataBytesInfo.exportDirmoduleNameStreamOffset; + writer.Write(namesBaseOffset + sdataBytesInfo.moduleNameOffset); + + writer.BaseStream.Position = sdataBytesInfo.exportDiraddressOfFunctionsStreamOffset; + writer.Write(rva + sdataBytesInfo.addressOfFunctionsStreamOffset); // AddressOfFunctions + if (sdataBytesInfo.MethodNameOffsets.Length != 0) { + writer.Write(rva + sdataBytesInfo.addressOfNamesStreamOffset); // AddressOfNames + writer.Write(rva + sdataBytesInfo.addressOfNameOrdinalsStreamOffset); // AddressOfNameOrdinals + } + + uint funcBaseRva = (uint)stubsChunk.RVA; + writer.BaseStream.Position = sdataBytesInfo.addressOfFunctionsStreamOffset; + foreach (var info in allMethodInfos) + writer.Write(funcBaseRva + info.StubChunkOffset); + + var nameOffsets = sdataBytesInfo.MethodNameOffsets; + if (nameOffsets.Length != 0) { + writer.BaseStream.Position = sdataBytesInfo.addressOfNamesStreamOffset; + foreach (var info in sortedNameInfos) + writer.Write(namesBaseOffset + nameOffsets[info.NameIndex]); + + writer.BaseStream.Position = sdataBytesInfo.addressOfNameOrdinalsStreamOffset; + Debug.Assert(allMethodInfos.Count <= 0x10000);// Verified elsewhere + foreach (var info in sortedNameInfos) + writer.Write((ushort)info.Index); + } + } + + static void WriteZeroes(BinaryWriter writer, int count) { + while (count >= 8) { + writer.Write(0UL); + count -= 8; + } + for (int i = 0; i < count; i++) + writer.Write((byte)0); + } + + void WriteVtableFixups(BinaryWriter writer) { + if (vtables.Count == 0) + return; + + foreach (var vtbl in vtables) { + Debug.Assert(vtbl.Methods.Count <= ushort.MaxValue); + writer.Write((uint)sdataChunk.RVA + vtbl.SdataChunkOffset); + writer.Write((ushort)vtbl.Methods.Count); + writer.Write((ushort)vtbl.Flags); + } + } + + void WriteStubs(BinaryWriter writer) { + if (vtables.Count == 0) + return; + if (cpuArch == null) + return; + + ulong imageBase = peHeaders.ImageBase; + uint stubsBaseRva = (uint)stubsChunk.RVA; + uint vtblBaseRva = (uint)sdataChunk.RVA; + uint expectedOffset = 0; + uint stubCodeOffset = cpuArch.GetStubCodeOffset(stubType); + uint stubSize = cpuArch.GetStubSize(stubType); + uint stubAlignment = cpuArch.GetStubAlignment(stubType); + int zeroes = (int)((stubSize + stubAlignment - 1 & ~(stubAlignment - 1)) - stubSize); + foreach (var info in allMethodInfos) { + uint currentOffset = info.StubChunkOffset - stubCodeOffset; + if (expectedOffset != currentOffset) + throw new InvalidOperationException(); + var pos = writer.BaseStream.Position; + cpuArch.WriteStub(stubType, writer, imageBase, stubsBaseRva + currentOffset, vtblBaseRva + info.ManagedVtblOffset); + Debug.Assert(pos + stubSize == writer.BaseStream.Position, "The full stub wasn't written"); + if (pos + stubSize != writer.BaseStream.Position) + throw new InvalidOperationException(); + if (zeroes != 0) + WriteZeroes(writer, zeroes); + expectedOffset = (currentOffset + stubSize + stubAlignment - 1) & ~(stubAlignment - 1); + } + if (expectedOffset != stubsChunk.length) + throw new InvalidOperationException(); + } + + static int CompareTo(byte[] a, byte[] b) { + if (a == b) + return 0; + int max = Math.Min(a.Length, b.Length); + for (int i = 0; i < max; i++) { + int c = a[i] - b[i]; + if (c != 0) + return c; + } + return a.Length - b.Length; + } + } +} diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 6ecf63372..5ece4d273 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -343,6 +343,7 @@ public abstract class MetaData : IChunk, ISignatureWriterHelper, ITokenCreator, readonly SortedRows customDebugInfos = new SortedRows(); readonly List binaryWriterContexts = new List(); readonly List serializerMethodContexts = new List(); + readonly List exportedMethods = new List(); /// /// Gets/sets the listener @@ -450,6 +451,13 @@ public PdbHeap PdbHeap { get { return pdbHeap; } } + /// + /// Gets all exported methods + /// + public List ExportedMethods { + get { return exportedMethods; } + } + /// /// The public key that should be used instead of the one in . /// @@ -1468,6 +1476,8 @@ void InitializeTypeDefsAndMemberDefs() { Error("Method is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; } + if (method.ExportInfo != null) + ExportedMethods.Add(method); uint rid = GetRid(method); var row = tablesHeap.MethodTable[rid]; row.ImplFlags = (ushort)method.ImplAttributes; @@ -1606,10 +1616,8 @@ void InitializeVTableFixups() { continue; } foreach (var method in vtable) { - if (method == null) { - Error("VTable method is null"); + if (method == null) continue; - } AddMDTokenProvider(method); } } diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index b5deb2794..078144a6f 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using dnlib.DotNet.MD; +using dnlib.PE; using dnlib.W32Resources; namespace dnlib.DotNet.Writer { @@ -38,9 +39,6 @@ public ModuleWriterOptions(ModuleDef module, IModuleWriterListener listener) /// Writes a .NET PE file. See also /// public sealed class ModuleWriter : ModuleWriterBase { - const uint DEFAULT_IAT_ALIGNMENT = 4; - const uint DEFAULT_IMPORTDIRECTORY_ALIGNMENT = 4; - const uint DEFAULT_STARTUPSTUB_ALIGNMENT = 1; const uint DEFAULT_RELOC_ALIGNMENT = 4; readonly ModuleDef module; @@ -48,6 +46,7 @@ public sealed class ModuleWriter : ModuleWriterBase { List sections; PESection textSection; + PESection sdataSection; PESection rsrcSection; PESection relocSection; @@ -57,6 +56,8 @@ public sealed class ModuleWriter : ModuleWriterBase { ImportDirectory importDirectory; StartupStub startupStub; RelocDirectory relocDirectory; + ManagedExportsWriter managedExportsWriter; + bool needStartupStub; /// public override ModuleDef Module { @@ -91,14 +92,21 @@ public override PESection TextSection { } /// - /// Gets the .rsrc section or null if there's none + /// Gets the .sdata section + /// + internal PESection SdataSection { + get { return sdataSection; } + } + + /// + /// Gets the .rsrc section or null if none /// public override PESection RsrcSection { get { return rsrcSection; } } /// - /// Gets the .reloc section or null if there's none + /// Gets the .reloc section /// public PESection RelocSection { get { return relocSection; } @@ -190,53 +198,65 @@ protected override Win32Resources GetWin32Resources() { void CreateSections() { sections = new List(); sections.Add(textSection = new PESection(".text", 0x60000020)); + sections.Add(sdataSection = new PESection(".sdata", 0xC0000040)); if (GetWin32Resources() != null) sections.Add(rsrcSection = new PESection(".rsrc", 0x40000040)); - if (!Options.Is64Bit) - sections.Add(relocSection = new PESection(".reloc", 0x42000040)); + // Should be last so any data in a previous section can add relocations + sections.Add(relocSection = new PESection(".reloc", 0x42000040)); } void CreateChunks() { peHeaders = new PEHeaders(Options.PEHeadersOptions); - if (!Options.Is64Bit) { - importAddressTable = new ImportAddressTable(); - importDirectory = new ImportDirectory(); - startupStub = new StartupStub(); - relocDirectory = new RelocDirectory(); - } + var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; + bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + relocDirectory = new RelocDirectory(machine); + if (machine == Machine.I386) + needStartupStub = true; + + importAddressTable = new ImportAddressTable(is64bit); + importDirectory = new ImportDirectory(is64bit); + startupStub = new StartupStub(relocDirectory, machine, (format, args) => Error(format, args)); CreateStrongNameSignature(); imageCor20Header = new ImageCor20Header(Options.Cor20HeaderOptions); CreateMetaDataChunks(module); + managedExportsWriter = new ManagedExportsWriter(UTF8String.ToSystemStringOrEmpty(module.Name), machine, relocDirectory, metaData, peHeaders, (format, args) => Error(format, args)); CreateDebugDirectory(); - if (importDirectory != null) - importDirectory.IsExeFile = Options.IsExeFile; - + importDirectory.IsExeFile = Options.IsExeFile; peHeaders.IsExeFile = Options.IsExeFile; } void AddChunksToSections() { - textSection.Add(importAddressTable, DEFAULT_IAT_ALIGNMENT); + var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; + bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + uint pointerAlignment = is64bit ? 8U : 4; + + textSection.Add(importAddressTable, pointerAlignment); textSection.Add(imageCor20Header, DEFAULT_COR20HEADER_ALIGNMENT); textSection.Add(strongNameSignature, DEFAULT_STRONGNAMESIG_ALIGNMENT); + managedExportsWriter.AddTextChunks(textSection); textSection.Add(constants, DEFAULT_CONSTANTS_ALIGNMENT); textSection.Add(methodBodies, DEFAULT_METHODBODIES_ALIGNMENT); textSection.Add(netResources, DEFAULT_NETRESOURCES_ALIGNMENT); textSection.Add(metaData, DEFAULT_METADATA_ALIGNMENT); textSection.Add(debugDirectory, DebugDirectory.DEFAULT_DEBUGDIRECTORY_ALIGNMENT); - textSection.Add(importDirectory, DEFAULT_IMPORTDIRECTORY_ALIGNMENT); - textSection.Add(startupStub, DEFAULT_STARTUPSTUB_ALIGNMENT); - if (rsrcSection != null) + textSection.Add(importDirectory, pointerAlignment); + textSection.Add(startupStub, startupStub.Alignment); + managedExportsWriter.AddSdataChunks(sdataSection); + if (GetWin32Resources() != null) rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); - if (relocSection != null) - relocSection.Add(relocDirectory, DEFAULT_RELOC_ALIGNMENT); + relocSection.Add(relocDirectory, DEFAULT_RELOC_ALIGNMENT); } long WriteFile() { + managedExportsWriter.AddExportedMethods(metaData.ExportedMethods, GetTimeDateStamp()); + if (managedExportsWriter.HasExports) + needStartupStub = true; + Listener.OnWriterEvent(this, ModuleWriterEvent.BeginWritePdb); WritePdbFile(); Listener.OnWriterEvent(this, ModuleWriterEvent.EndWritePdb); @@ -244,6 +264,15 @@ long WriteFile() { Listener.OnWriterEvent(this, ModuleWriterEvent.BeginCalculateRvasAndFileOffsets); var chunks = new List(); chunks.Add(peHeaders); + if (!managedExportsWriter.HasExports) + sections.Remove(sdataSection); + if (!(relocDirectory.NeedsRelocSection || managedExportsWriter.HasExports || needStartupStub)) + sections.Remove(relocSection); + + importAddressTable.Enable = needStartupStub; + importDirectory.Enable = needStartupStub; + startupStub.Enable = needStartupStub; + foreach (var section in sections) chunks.Add(section); peHeaders.PESections = sections; @@ -274,13 +303,10 @@ long WriteFile() { void InitializeChunkProperties() { Options.Cor20HeaderOptions.EntryPoint = GetEntryPoint(); - if (importAddressTable != null) { - importAddressTable.ImportDirectory = importDirectory; - importDirectory.ImportAddressTable = importAddressTable; - startupStub.ImportDirectory = importDirectory; - startupStub.PEHeaders = peHeaders; - relocDirectory.StartupStub = startupStub; - } + importAddressTable.ImportDirectory = importDirectory; + importDirectory.ImportAddressTable = importAddressTable; + startupStub.ImportDirectory = importDirectory; + startupStub.PEHeaders = peHeaders; peHeaders.StartupStub = startupStub; peHeaders.ImageCor20Header = imageCor20Header; peHeaders.ImportAddressTable = importAddressTable; @@ -291,6 +317,7 @@ void InitializeChunkProperties() { imageCor20Header.MetaData = metaData; imageCor20Header.NetResources = netResources; imageCor20Header.StrongNameSignature = strongNameSignature; + managedExportsWriter.InitializeChunkProperties(); } uint GetEntryPoint() { diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index c83b308d8..3c5965d1e 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -607,10 +607,13 @@ protected void CreateMetaDataChunks(ModuleDef module) { protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offset, RVA rva, uint fileAlignment, uint sectionAlignment) { foreach (var chunk in chunks) { chunk.SetOffset(offset, rva); - offset += chunk.GetFileLength(); - rva += chunk.GetVirtualSize(); - offset = offset.AlignUp(fileAlignment); - rva = rva.AlignUp(sectionAlignment); + // If it has zero size, it's not present in the file (eg. a section that wasn't needed) + if (chunk.GetVirtualSize() != 0) { + offset += chunk.GetFileLength(); + rva += chunk.GetVirtualSize(); + offset = offset.AlignUp(fileAlignment); + rva = rva.AlignUp(sectionAlignment); + } } } @@ -624,10 +627,13 @@ protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offse protected void WriteChunks(BinaryWriter writer, List chunks, FileOffset offset, uint fileAlignment) { foreach (var chunk in chunks) { chunk.VerifyWriteTo(writer); - offset += chunk.GetFileLength(); - var newOffset = offset.AlignUp(fileAlignment); - writer.WriteZeros((int)(newOffset - offset)); - offset = newOffset; + // If it has zero size, it's not present in the file (eg. a section that wasn't needed) + if (chunk.GetVirtualSize() != 0) { + offset += chunk.GetFileLength(); + var newOffset = offset.AlignUp(fileAlignment); + writer.WriteZeros((int)(newOffset - offset)); + offset = newOffset; + } } } @@ -711,7 +717,11 @@ void WriteWindowsPdb(PdbState pdbState) { } } - uint GetTimeDateStamp() { + /// + /// Gets the timestamp stored in the PE header + /// + /// + protected uint GetTimeDateStamp() { var td = TheOptions.PEHeadersOptions.TimeDateStamp; if (td.HasValue) return (uint)td; diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 76b74debd..b59a62140 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -688,9 +688,9 @@ uint GetMethodToken(IMethod method) { return new MDToken(Table.MethodSpec, metaData.GetRid(ms)).Raw; if (method == null) - Error("VTable method is null"); - else - Error("Invalid VTable method type: {0}", method.GetType()); + return 0; + + Error("Invalid VTable method type: {0}", method.GetType()); return 0; } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 4c5d8f5c7..21f2e51c4 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using dnlib.IO; using dnlib.PE; @@ -238,6 +239,8 @@ public sealed class PEHeaders : IChunk { /// public DebugDirectory DebugDirectory { get; set; } + internal IChunk ExportDirectory { get; set; } + /// /// Gets the image base /// @@ -318,6 +321,17 @@ public void SetOffset(FileOffset offset, RVA rva) { imageBase = options.ImageBase ?? 0x0000000140000000; } + int SectionsCount { + get { + int count = 0; + foreach (var section in sections) { + if (section.GetVirtualSize() != 0) + count++; + } + return count; + } + } + /// public uint GetFileLength() { return length; @@ -329,8 +343,11 @@ public uint GetVirtualSize() { } IEnumerable GetSectionSizeInfos() { - foreach (var section in PESections) - yield return new SectionSizeInfo(section.GetVirtualSize(), section.Characteristics); + foreach (var section in sections) { + uint virtSize = section.GetVirtualSize(); + if (virtSize != 0) + yield return new SectionSizeInfo(virtSize, section.Characteristics); + } } /// @@ -345,7 +362,8 @@ public void WriteTo(BinaryWriter writer) { // Image file header writer.Write((ushort)GetMachine()); - writer.Write((ushort)sections.Count); + writer.Write((ushort)SectionsCount); + Debug.Assert(SectionsCount == sections.Count, "One or more sections are empty! The PE file could be bigger than it should be. Empty sections should be removed."); writer.Write(options.TimeDateStamp ?? PEHeadersOptions.CreateNewTimeDateStamp()); writer.Write(options.PointerToSymbolTable ?? 0); writer.Write(options.NumberOfSymbols ?? 0); @@ -422,7 +440,7 @@ public void WriteTo(BinaryWriter writer) { writer.Write(options.NumberOfRvaAndSizes ?? 0x00000010); } - writer.WriteDataDirectory(null); // Export table + writer.WriteDataDirectory(ExportDirectory); writer.WriteDataDirectory(ImportDirectory); writer.WriteDataDirectory(Win32Resources); writer.WriteDataDirectory(null); // Exception table @@ -441,8 +459,15 @@ public void WriteTo(BinaryWriter writer) { // Sections uint rva = Utils.AlignUp(sectionSizes.SizeOfHeaders, sectionAlignment); - foreach (var section in sections) - rva += section.WriteHeaderTo(writer, fileAlignment, sectionAlignment, rva); + int emptySections = 0; + foreach (var section in sections) { + if (section.GetVirtualSize() != 0) + rva += section.WriteHeaderTo(writer, fileAlignment, sectionAlignment, rva); + else + emptySections++; + } + if (emptySections != 0) + writer.BaseStream.Position += emptySections * 0x28; } /// diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index ae93a0aaf..2a704a7a4 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -1,6 +1,8 @@ // dnlib: See LICENSE.txt for more info -using System.IO; +using System; +using System.Collections.Generic; +using System.IO; using dnlib.IO; using dnlib.PE; @@ -9,13 +11,22 @@ namespace dnlib.DotNet.Writer { /// Relocations directory /// public sealed class RelocDirectory : IChunk { + readonly Machine machine; + readonly List allRelocRvas = new List(); + readonly List> relocSections = new List>(); + bool isReadOnly; FileOffset offset; RVA rva; + uint totalSize; - /// - /// Gets/sets the - /// - public StartupStub StartupStub { get; set; } + struct RelocInfo { + public readonly IChunk Chunk; + public readonly uint OffsetOrRva; + public RelocInfo(IChunk chunk, uint offset) { + Chunk = chunk; + OffsetOrRva = offset; + } + } /// public FileOffset FileOffset { @@ -27,15 +38,55 @@ public RVA RVA { get { return rva; } } + internal bool NeedsRelocSection { + get { return allRelocRvas.Count != 0; } + } + + /// + /// Constructor + /// + /// Machine + public RelocDirectory(Machine machine) { + this.machine = machine; + } + /// public void SetOffset(FileOffset offset, RVA rva) { + isReadOnly = true; this.offset = offset; this.rva = rva; + + var allRvas = new List(allRelocRvas.Count); + foreach (var info in allRelocRvas) { + uint relocRva; + if (info.Chunk != null) + relocRva = (uint)info.Chunk.RVA + info.OffsetOrRva; + else + relocRva = info.OffsetOrRva; + allRvas.Add(relocRva); + } + allRvas.Sort(); + + uint prevPage = uint.MaxValue; + List pageList = null; + foreach (var relocRva in allRvas) { + uint page = relocRva & ~0xFFFU; + if (page != prevPage) { + prevPage = page; + if (pageList != null) + totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); + pageList = new List(); + relocSections.Add(pageList); + } + pageList.Add(relocRva); + } + if (pageList != null) + totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); } /// public uint GetFileLength() { - return 12; + return totalSize; } /// @@ -45,11 +96,38 @@ public uint GetVirtualSize() { /// public void WriteTo(BinaryWriter writer) { - uint rva = (uint)StartupStub.RelocRVA; - writer.Write(rva & ~0xFFFU); - writer.Write(12); - writer.Write((ushort)(0x3000 | (rva & 0xFFF))); - writer.Write((ushort)0); + bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + // 3 = IMAGE_REL_BASED_HIGHLOW, A = IMAGE_REL_BASED_DIR64 + uint relocType = is64bit ? 0xA000U : 0x3000; + foreach (var pageList in relocSections) { + writer.Write(pageList[0] & ~0xFFFU); + writer.Write((uint)(8 + ((pageList.Count + 1) & ~1) * 2)); + foreach (var rva in pageList) + writer.Write((ushort)(relocType | (rva & 0xFFF))); + if ((pageList.Count & 1) != 0) + writer.Write((ushort)0); + } + } + + /// + /// Adds a relocation + /// + /// RVA of location + public void Add(RVA rva) { + if (isReadOnly) + throw new InvalidOperationException("Can't add a relocation when the relocs section is read-only"); + allRelocRvas.Add(new RelocInfo(null, (uint)rva)); + } + + /// + /// Adds a relocation + /// + /// Chunk or null. If it's null, is the RVA + /// Offset relative to the start of , or if is null, this is the RVA + public void Add(IChunk chunk, uint offset) { + if (isReadOnly) + throw new InvalidOperationException("Can't add a relocation when the relocs section is read-only"); + allRelocRvas.Add(new RelocInfo(chunk, offset)); } } } diff --git a/src/DotNet/Writer/StartupStub.cs b/src/DotNet/Writer/StartupStub.cs index 30db0d408..c1c627712 100644 --- a/src/DotNet/Writer/StartupStub.cs +++ b/src/DotNet/Writer/StartupStub.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.IO; +using System.IO; using dnlib.IO; using dnlib.PE; @@ -9,10 +9,13 @@ namespace dnlib.DotNet.Writer { /// Stores the instruction that jumps to _CorExeMain/_CorDllMain /// public sealed class StartupStub : IChunk { + const StubType stubType = StubType.EntryPoint; + readonly RelocDirectory relocDirectory; + readonly Machine machine; + readonly CpuArch cpuArch; + readonly LogError logError; FileOffset offset; RVA rva; - uint length; - uint padding; /// /// Gets/sets the @@ -38,14 +41,28 @@ public RVA RVA { /// Gets the address of the JMP instruction /// public RVA EntryPointRVA { - get { return rva + padding; } + get { return rva + (cpuArch == null ? 0 : cpuArch.GetStubCodeOffset(stubType)); } } + internal bool Enable { get; set; } + + internal uint Alignment { + get { return cpuArch == null ? 1 : cpuArch.GetStubAlignment(stubType); } + } + + internal delegate void LogError(string format, params object[] args); + /// - /// Gets the address of the operand of the JMP instruction + /// Constructor /// - public RVA RelocRVA { - get { return EntryPointRVA + 2; } + /// Reloc directory + /// Machine + /// Error logger + internal StartupStub(RelocDirectory relocDirectory, Machine machine, LogError logError) { + this.relocDirectory = relocDirectory; + this.machine = machine; + this.logError = logError; + CpuArch.TryGetCpuArch(machine, out cpuArch); } /// @@ -53,13 +70,24 @@ public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; - padding = rva.AlignUp(4) - rva + 2; - length = padding + 6; + if (!Enable) + return; + + if (cpuArch == null) { + logError("The module needs an unmanaged entry point but the CPU architecture isn't supported: {0} (0x{1:X4})", machine, (ushort)machine); + return; + } + + cpuArch.WriteStubRelocs(stubType, relocDirectory, this, 0); } /// public uint GetFileLength() { - return length; + if (!Enable) + return 0; + if (cpuArch == null) + return 0; + return cpuArch.GetStubSize(stubType); } /// @@ -69,10 +97,11 @@ public uint GetVirtualSize() { /// public void WriteTo(BinaryWriter writer) { - writer.WriteZeros((int)padding); - writer.Write((byte)0xFF); - writer.Write((byte)0x25); - writer.Write((uint)PEHeaders.ImageBase + (uint)ImportDirectory.IatCorXxxMainRVA); + if (!Enable) + return; + if (cpuArch == null) + return; + cpuArch.WriteStub(stubType, writer, PEHeaders.ImageBase, (uint)rva, (uint)ImportDirectory.IatCorXxxMainRVA); } } } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 8984e4a18..068e7c74d 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -61,6 +61,7 @@ + @@ -162,6 +163,8 @@ + + @@ -326,6 +329,7 @@ + From f03d74b9710c933ee718c54e011f5439a4ecba22 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 4 Mar 2018 17:30:55 +0100 Subject: [PATCH 094/511] Misc --- src/DotNet/CpuArch.cs | 3 +-- src/DotNet/Writer/ManagedExportsWriter.cs | 19 ++++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 1c07a27a0..c97b1abc2 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -151,8 +151,7 @@ public override void WriteStub(StubType stubType, BinaryWriter writer, ulong ima default: throw new ArgumentOutOfRangeException(); } - - } + } } sealed class X64CpuArch : CpuArch { diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 96a69bc8f..1d1ffe538 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -335,10 +335,6 @@ public int MethodNamesCount { get { return methodNamesCount; } } - public int TotalNamesCount { - get { return names.Count; } - } - struct NameInfo { public readonly uint Offset; public readonly byte[] Bytes; @@ -411,8 +407,8 @@ struct SdataBytesInfo { public byte[] Data; public uint namesBlobStreamOffset; public uint moduleNameOffset; - public uint exportDirmoduleNameStreamOffset; - public uint exportDiraddressOfFunctionsStreamOffset; + public uint exportDirModuleNameStreamOffset; + public uint exportDirAddressOfFunctionsStreamOffset; public uint addressOfFunctionsStreamOffset; public uint addressOfNamesStreamOffset; public uint addressOfNameOrdinalsStreamOffset; @@ -462,6 +458,7 @@ void WriteSdataBlob(uint timestamp) { sdataBytesInfo.moduleNameOffset = namesBlob.GetOtherNameOffset(moduleName); sortedNameInfos.Sort((a, b) => CompareTo(a.NameBytes, b.NameBytes)); + Debug.Assert(sortedNameInfos.Count == sdataBytesInfo.MethodNameOffsets.Length); uint ordinalBase = uint.MaxValue; foreach (var info in allMethodInfos) { @@ -477,12 +474,12 @@ void WriteSdataBlob(uint timestamp) { writer.Write(0U); // Characteristics writer.Write(timestamp); writer.Write(0U); // MajorVersion, MinorVersion - sdataBytesInfo.exportDirmoduleNameStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.exportDirModuleNameStreamOffset = (uint)writer.BaseStream.Position; writer.Write(0U); // Name writer.Write(ordinalBase); // Base writer.Write((uint)allMethodInfos.Count); // NumberOfFunctions writer.Write(sdataBytesInfo.MethodNameOffsets.Length); // NumberOfNames - sdataBytesInfo.exportDiraddressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; writer.Write(0U); // AddressOfFunctions writer.Write(0U); // AddressOfNames writer.Write(0U); // AddressOfNameOrdinals @@ -490,7 +487,7 @@ void WriteSdataBlob(uint timestamp) { sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; WriteZeroes(writer, allMethodInfos.Count * 4); sdataBytesInfo.addressOfNamesStreamOffset = (uint)writer.BaseStream.Position; - WriteZeroes(writer, namesBlob.TotalNamesCount * 4); + WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 4); sdataBytesInfo.addressOfNameOrdinalsStreamOffset = (uint)writer.BaseStream.Position; WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 2); sdataBytesInfo.namesBlobStreamOffset = (uint)writer.BaseStream.Position; @@ -512,10 +509,10 @@ void PatchSdataBytesBlob() { var writer = new BinaryWriter(new MemoryStream(sdataBytesInfo.Data)); - writer.BaseStream.Position = sdataBytesInfo.exportDirmoduleNameStreamOffset; + writer.BaseStream.Position = sdataBytesInfo.exportDirModuleNameStreamOffset; writer.Write(namesBaseOffset + sdataBytesInfo.moduleNameOffset); - writer.BaseStream.Position = sdataBytesInfo.exportDiraddressOfFunctionsStreamOffset; + writer.BaseStream.Position = sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset; writer.Write(rva + sdataBytesInfo.addressOfFunctionsStreamOffset); // AddressOfFunctions if (sdataBytesInfo.MethodNameOffsets.Length != 0) { writer.Write(rva + sdataBytesInfo.addressOfNamesStreamOffset); // AddressOfNames From fd4ef8d159eb4e3317391fff83d88cbe8979d364 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 4 Mar 2018 21:59:25 +0100 Subject: [PATCH 095/511] Update credits --- LICENSE.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE.txt b/LICENSE.txt index 76a568767..6b8c1eacf 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -8,6 +8,7 @@ Contributors Ki, "yck1509 ", https://github.com/yck1509 kiootic, "kiootic ", https://github.com/kiootic +SlowLogicBoy, https://github.com/SlowLogicBoy MIT LICENSE ----------- From 21e9387203338714371c1dc692933d8f25053bb4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 5 Mar 2018 18:25:50 +0100 Subject: [PATCH 096/511] Update .editorconfig --- .editorconfig | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/.editorconfig b/.editorconfig index fdbdd033f..e50fdca43 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,11 +1,11 @@ root = true [*] +#end_of_line = indent_size = 4 indent_style = tab insert_final_newline = true tab_width = 4 -#end_of_line = [*.json] @@ -29,82 +29,82 @@ indent_style = space indent_style = space [*.{cs,vb}] +dotnet_separate_import_directive_groups = false dotnet_sort_system_directives_first = true -dotnet_style_qualification_for_field = false:suggestion -dotnet_style_qualification_for_property = false:suggestion -dotnet_style_qualification_for_method = false:suggestion -dotnet_style_qualification_for_event = false:suggestion -dotnet_style_predefined_type_for_locals_parameters_members = true:none -dotnet_style_predefined_type_for_member_access = true:none -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation = true:suggestion +dotnet_style_collection_initializer = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion -dotnet_separate_import_directive_groups = false +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:none +dotnet_style_predefined_type_for_member_access = true:none +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_is_null_check_over_reference_equality_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_property = false:suggestion dotnet_style_require_accessibility_modifiers = never:info [*.cs] -csharp_style_throw_expression = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_var_for_built_in_types = false:none -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_expression_bodied_constructors = true:suggestion -csharp_style_expression_bodied_methods = true:suggestion -csharp_style_expression_bodied_operators = true:suggestion -csharp_style_expression_bodied_properties = true:suggestion -csharp_style_expression_bodied_indexers = true:suggestion -csharp_style_expression_bodied_accessors = true:suggestion +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = flush_left +csharp_indent_switch_labels = false +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = none +csharp_new_line_between_query_expression_clauses = true csharp_prefer_braces = false -csharp_space_between_method_declaration_name_and_open_parenthesis = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_between_parentheses = +csharp_prefer_simple_default_expression = true:suggestion +#csharp_preferred_modifier_order = +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true csharp_space_after_cast = false -csharp_space_around_declaration_statements = false -csharp_space_before_open_square_brackets = false -csharp_space_between_empty_square_brackets = false -csharp_space_between_square_brackets = false csharp_space_after_colon_in_inheritance_clause = true csharp_space_after_comma = true csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false csharp_space_before_colon_in_inheritance_clause = true csharp_space_before_comma = false csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false csharp_space_before_semicolon_in_for_statement = false -csharp_space_around_binary_operators = before_and_after -csharp_indent_braces = false -csharp_indent_block_contents = true -csharp_indent_switch_labels = false -csharp_indent_case_contents = true -csharp_indent_labels = flush_left -csharp_preserve_single_line_blocks = true -csharp_preserve_single_line_statements = true -csharp_new_line_before_open_brace = none -csharp_new_line_before_else = true -csharp_new_line_before_catch = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_between_query_expression_clauses = true -csharp_indent_case_contents_when_block = false -csharp_prefer_inferred_anonymous_type_member_names = true:suggestion -csharp_prefer_inferred_tuple_names = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -#csharp_preferred_modifier_order = +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = +csharp_space_between_square_brackets = false +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_deconstructed_variable_declaration = false:none +csharp_style_expression_bodied_accessors = true:suggestion +csharp_style_expression_bodied_constructors = true:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_methods = true:suggestion +csharp_style_expression_bodied_operators = true:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_var_elsewhere = true:suggestion +csharp_style_var_for_built_in_types = false:none +csharp_style_var_when_type_is_apparent = true:suggestion [*.vb] -visual_basic_prefer_inferred_anonymous_type_member_names = true:suggestion -visual_basic_prefer_inferred_tuple_names = true:suggestion #visual_basic_preferred_modifier_order = From 443ec9778e9087917896b0f28922df50c47f1672 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 5 Mar 2018 18:26:05 +0100 Subject: [PATCH 097/511] Update project and solutions to need VS2017 and C# 7.2, use portable PDB files --- dnlib.netstandard.sln | 4 ++-- dnlib.sln | 6 +++-- src/dnlib.csproj | 7 +++--- src/dnlib.netstandard.csproj | 45 ++++++++++++++++++++---------------- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/dnlib.netstandard.sln b/dnlib.netstandard.sln index b9316a5c2..f724bc63f 100644 --- a/dnlib.netstandard.sln +++ b/dnlib.netstandard.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27130.2010 -MinimumVisualStudioVersion = 10.0.40219.1 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 15.0.26206.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib.netstandard", "src\dnlib.netstandard.csproj", "{80695BC3-65CA-403E-B161-57D4F6EC5CC3}" EndProject Global diff --git a/dnlib.sln b/dnlib.sln index e8dc7640b..9127821ce 100644 --- a/dnlib.sln +++ b/dnlib.sln @@ -1,6 +1,8 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 15.0.26206.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dnlib", "src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples", "Examples\Examples.csproj", "{F27E72B5-C4BD-40BF-AD19-4C8A99B55872}" diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 068e7c74d..86a077b80 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -15,7 +15,7 @@ 512 true ..\dnlib.snk - 4 + 7.2 true @@ -27,7 +27,7 @@ true - full + portable false ..\Debug\bin\ TRACE;DEBUG;$(MoreDefineConstants) @@ -37,7 +37,8 @@ true - pdbonly + true + portable true ..\Release\bin\ TRACE;$(MoreDefineConstants) diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index 2252f5b79..079a2a5b1 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -1,22 +1,27 @@ - - netstandard2.0 - dnlib - dnlib - true - true - ..\dnlib.snk - true - ..\$(Configuration)\bin - $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml - false - - - - - - - - - + + + netstandard2.0 + dnlib + dnlib + true + true + ..\dnlib.snk + true + ..\$(Configuration)\bin + $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml + false + 512 + 7.2 + true + portable + + + + + + + + + From 9c9b6add8b4129a183c4a54ddc07b388947bffeb Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 5 Mar 2018 18:26:16 +0100 Subject: [PATCH 098/511] Use C# 7.2 code --- src/DotNet/AllTypesHelper.cs | 2 +- src/DotNet/AssemblyDef.cs | 298 ++--- src/DotNet/AssemblyHash.cs | 8 +- src/DotNet/AssemblyNameComparer.cs | 30 +- src/DotNet/AssemblyNameInfo.cs | 128 +- src/DotNet/AssemblyRef.cs | 219 ++-- src/DotNet/AssemblyResolver.cs | 66 +- src/DotNet/CallingConventionSig.cs | 410 ++---- src/DotNet/ClassLayout.cs | 26 +- src/DotNet/Constant.cs | 30 +- src/DotNet/CorLibTypes.cs | 84 +- src/DotNet/CpuArch.cs | 4 +- src/DotNet/CustomAttribute.cs | 132 +- src/DotNet/CustomAttributeCollection.cs | 15 +- src/DotNet/CustomAttributeReader.cs | 101 +- src/DotNet/DeclSecurity.cs | 68 +- src/DotNet/DeclSecurityReader.cs | 22 +- src/DotNet/Emit/DynamicMethodBodyReader.cs | 58 +- src/DotNet/Emit/ExceptionHandler.cs | 4 +- src/DotNet/Emit/Instruction.cs | 113 +- src/DotNet/Emit/InstructionPrinter.cs | 12 +- src/DotNet/Emit/LocalList.cs | 156 +-- src/DotNet/Emit/MethodBody.cs | 98 +- src/DotNet/Emit/MethodBodyReader.cs | 73 +- src/DotNet/Emit/MethodBodyReaderBase.cs | 74 +- src/DotNet/Emit/MethodTableToTypeConverter.cs | 11 +- src/DotNet/Emit/MethodUtils.cs | 4 +- src/DotNet/Emit/OpCode.cs | 106 +- src/DotNet/EventDef.cs | 191 +-- src/DotNet/ExportedType.cs | 297 ++--- src/DotNet/FieldDef.cs | 340 ++--- src/DotNet/FileDef.cs | 75 +- src/DotNet/FrameworkRedirect.cs | 5 +- src/DotNet/FullNameCreator.cs | 418 +++--- src/DotNet/GenericArguments.cs | 30 +- src/DotNet/GenericParam.cs | 216 +--- src/DotNet/GenericParamConstraint.cs | 56 +- src/DotNet/GenericParamContext.cs | 22 +- src/DotNet/IAssemblyResolver.cs | 14 +- src/DotNet/ICodedToken.cs | 102 +- src/DotNet/ICorLibTypes.cs | 11 +- src/DotNet/ILogger.cs | 95 +- src/DotNet/IResolver.cs | 30 +- src/DotNet/ITokenResolver.cs | 4 +- src/DotNet/ITypeDefFinder.cs | 32 +- src/DotNet/ImplMap.cs | 121 +- src/DotNet/Importer.cs | 117 +- src/DotNet/InterfaceImpl.cs | 50 +- src/DotNet/MD/BlobStream.cs | 13 +- src/DotNet/MD/CodedToken.cs | 30 +- src/DotNet/MD/ColumnInfo.cs | 20 +- src/DotNet/MD/CompressedMetaData.cs | 27 +- src/DotNet/MD/DotNetStream.cs | 40 +- src/DotNet/MD/DotNetTableSizes.cs | 14 +- src/DotNet/MD/ENCMetaData.cs | 25 +- src/DotNet/MD/GuidStream.cs | 4 +- src/DotNet/MD/HotHeapStream.cs | 7 +- src/DotNet/MD/HotStream.cs | 16 +- src/DotNet/MD/HotTableStream.cs | 3 +- src/DotNet/MD/ImageCor20Header.cs | 78 +- src/DotNet/MD/MDTable.cs | 54 +- src/DotNet/MD/MetaData.cs | 140 +- src/DotNet/MD/MetaDataCreator.cs | 12 +- src/DotNet/MD/MetaDataHeader.cs | 72 +- src/DotNet/MD/RawRowEqualityComparer.cs | 1138 ++++++++--------- src/DotNet/MD/RawTableRows.cs | 40 +- src/DotNet/MD/RidList.cs | 40 +- src/DotNet/MD/StreamHeader.cs | 18 +- src/DotNet/MD/StringsStream.cs | 4 +- src/DotNet/MD/TableInfo.cs | 16 +- src/DotNet/MD/TablesStream.cs | 77 +- src/DotNet/MD/TablesStream_Read.cs | 5 +- src/DotNet/MD/USStream.cs | 7 +- src/DotNet/MDToken.cs | 86 +- src/DotNet/ManifestResource.cs | 71 +- src/DotNet/MarshalBlobReader.cs | 31 +- src/DotNet/MarshalType.cs | 152 +-- src/DotNet/MemberFinder.cs | 29 +- src/DotNet/MemberRef.cs | 219 +--- src/DotNet/MethodDef.cs | 505 +++----- src/DotNet/MethodExportInfo.cs | 16 +- src/DotNet/MethodExportInfoProvider.cs | 14 +- src/DotNet/MethodOverride.cs | 4 +- src/DotNet/MethodSpec.cs | 172 +-- src/DotNet/ModuleContext.cs | 4 +- src/DotNet/ModuleCreationOptions.cs | 10 +- src/DotNet/ModuleDef.cs | 477 +++---- src/DotNet/ModuleDefMD.cs | 482 ++----- src/DotNet/ModuleLoader.cs | 114 +- src/DotNet/ModuleRef.cs | 79 +- src/DotNet/NullResolver.cs | 20 +- src/DotNet/ParamDef.cs | 132 +- src/DotNet/ParameterList.cs | 155 +-- src/DotNet/Pdb/Dss/ImageStreamIStream.cs | 23 +- src/DotNet/Pdb/Dss/MDEmitter.cs | 539 ++------ src/DotNet/Pdb/Dss/PinnedMetaData.cs | 28 +- src/DotNet/Pdb/Dss/StreamIStream.cs | 18 +- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 32 +- src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs | 20 +- src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 30 +- src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs | 7 +- src/DotNet/Pdb/Dss/SymbolReaderCreator.cs | 30 +- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 27 +- src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 45 +- src/DotNet/Pdb/Dss/SymbolVariableImpl.cs | 17 +- src/DotNet/Pdb/Dss/SymbolWriter.cs | 124 +- src/DotNet/Pdb/Dss/SymbolWriterCreator.cs | 10 +- src/DotNet/Pdb/Managed/DbiDocument.cs | 28 +- src/DotNet/Pdb/Managed/DbiFunction.cs | 15 +- src/DotNet/Pdb/Managed/DbiNamespace.cs | 8 +- src/DotNet/Pdb/Managed/DbiScope.cs | 58 +- src/DotNet/Pdb/Managed/DbiVariable.cs | 16 +- src/DotNet/Pdb/Managed/MsfStream.cs | 4 +- src/DotNet/Pdb/Managed/PdbAddress.cs | 47 +- src/DotNet/Pdb/Managed/PdbReader.cs | 34 +- src/DotNet/Pdb/Managed/SymbolReaderCreator.cs | 12 +- src/DotNet/Pdb/ManagedSymbolReaderCreator.cs | 19 +- src/DotNet/Pdb/PdbConstant.cs | 24 +- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 368 ++---- src/DotNet/Pdb/PdbDocument.cs | 42 +- src/DotNet/Pdb/PdbImport.cs | 104 +- src/DotNet/Pdb/PdbLocal.cs | 18 +- src/DotNet/Pdb/PdbScope.cs | 44 +- src/DotNet/Pdb/PdbState.cs | 32 +- src/DotNet/Pdb/Portable/DocumentNameReader.cs | 10 +- .../Pdb/Portable/ImportScopeBlobReader.cs | 5 +- .../Pdb/Portable/ImportScopeBlobWriter.cs | 10 +- src/DotNet/Pdb/Portable/ListCache.cs | 4 +- .../Portable/LocalConstantSigBlobReader.cs | 10 +- .../Portable/LocalConstantSigBlobWriter.cs | 16 +- .../PortablePdbCustomDebugInfoReader.cs | 14 +- .../PortablePdbCustomDebugInfoWriter.cs | 6 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 53 +- src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs | 34 +- src/DotNet/Pdb/Portable/SymbolMethodImpl.cs | 22 +- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 46 +- src/DotNet/Pdb/Portable/SymbolVariableImpl.cs | 19 +- src/DotNet/Pdb/Symbols/SymbolReader.cs | 1 - .../WindowsPdb/PdbCustomDebugInfoReader.cs | 6 +- .../WindowsPdb/PdbCustomDebugInfoWriter.cs | 25 +- .../Pdb/WindowsPdb/SymbolWriterCreator.cs | 8 +- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 53 +- src/DotNet/PropertyDef.cs | 214 +--- src/DotNet/PublicKey.cs | 4 +- src/DotNet/PublicKeyBase.cs | 52 +- src/DotNet/PublicKeyToken.cs | 8 +- src/DotNet/RecursionCounter.cs | 8 +- src/DotNet/ReflectionExtensions.cs | 19 +- src/DotNet/Resolver.cs | 44 +- src/DotNet/Resource.cs | 103 +- src/DotNet/Resources/BuiltInResourceData.cs | 16 +- src/DotNet/Resources/ResourceDataCreator.cs | 114 +- src/DotNet/Resources/ResourceElement.cs | 4 +- src/DotNet/Resources/ResourceElementSet.cs | 12 +- src/DotNet/Resources/ResourceReader.cs | 44 +- src/DotNet/Resources/ResourceWriter.cs | 7 +- src/DotNet/Resources/UserResourceData.cs | 28 +- src/DotNet/Resources/UserResourceType.cs | 12 +- src/DotNet/SecurityAttribute.cs | 16 +- src/DotNet/SigComparer.cs | 647 +++------- src/DotNet/SignatureReader.cs | 131 +- src/DotNet/StandAloneSig.cs | 62 +- src/DotNet/StrongNameKey.cs | 74 +- src/DotNet/StrongNameSigner.cs | 4 +- src/DotNet/TIAHelper.cs | 17 +- src/DotNet/TypeDef.cs | 591 +++------ src/DotNet/TypeDefFinder.cs | 15 +- src/DotNet/TypeHelper.cs | 107 +- src/DotNet/TypeNameParser.cs | 72 +- src/DotNet/TypeRef.cs | 223 +--- src/DotNet/TypeSig.cs | 505 ++------ src/DotNet/TypeSpec.cs | 174 +-- src/DotNet/UTF8String.cs | 272 +--- src/DotNet/Utils.cs | 52 +- src/DotNet/VTableFixups.cs | 72 +- src/DotNet/WinMDHelpers.cs | 91 +- src/DotNet/Writer/BinaryReaderChunk.cs | 20 +- src/DotNet/Writer/BlobHeap.cs | 25 +- src/DotNet/Writer/ByteArrayChunk.cs | 32 +- src/DotNet/Writer/ChunkList.cs | 4 +- src/DotNet/Writer/ChunkListBase.cs | 35 +- src/DotNet/Writer/CustomAttributeWriter.cs | 62 +- src/DotNet/Writer/DebugDirectory.cs | 28 +- src/DotNet/Writer/DeclSecurityWriter.cs | 35 +- src/DotNet/Writer/GuidHeap.cs | 18 +- src/DotNet/Writer/HeapBase.cs | 32 +- src/DotNet/Writer/HotHeap.cs | 44 +- src/DotNet/Writer/HotPool.cs | 46 +- src/DotNet/Writer/HotTable.cs | 40 +- src/DotNet/Writer/IChunk.cs | 2 +- src/DotNet/Writer/ImageCor20Header.cs | 30 +- src/DotNet/Writer/ImportAddressTable.cs | 16 +- src/DotNet/Writer/ImportDirectory.cs | 28 +- src/DotNet/Writer/MDTable.cs | 59 +- src/DotNet/Writer/MDTableWriter.cs | 2 +- src/DotNet/Writer/ManagedExportsWriter.cs | 175 +-- src/DotNet/Writer/MarshalBlobWriter.cs | 25 +- src/DotNet/Writer/MaxStackCalculator.cs | 33 +- src/DotNet/Writer/MetaData.cs | 477 +++---- src/DotNet/Writer/MetaDataHeader.cs | 40 +- src/DotNet/Writer/MethodBody.cs | 50 +- src/DotNet/Writer/MethodBodyChunks.cs | 25 +- src/DotNet/Writer/MethodBodyWriter.cs | 44 +- src/DotNet/Writer/MethodBodyWriterBase.cs | 18 +- src/DotNet/Writer/ModuleWriter.cs | 66 +- src/DotNet/Writer/ModuleWriterBase.cs | 116 +- src/DotNet/Writer/NativeModuleWriter.cs | 63 +- src/DotNet/Writer/NetResources.cs | 26 +- src/DotNet/Writer/NormalMetaData.cs | 53 +- src/DotNet/Writer/PEHeaders.cs | 48 +- src/DotNet/Writer/PESection.cs | 20 +- src/DotNet/Writer/PdbHeap.cs | 16 +- src/DotNet/Writer/PreserveTokensMetaData.cs | 143 +-- src/DotNet/Writer/RelocDirectory.cs | 26 +- src/DotNet/Writer/SectionSizes.cs | 4 +- src/DotNet/Writer/SerializerMethodContext.cs | 13 +- src/DotNet/Writer/SignatureWriter.cs | 30 +- src/DotNet/Writer/StartupStub.cs | 21 +- src/DotNet/Writer/StringsHeap.cs | 34 +- src/DotNet/Writer/StrongNameSignature.cs | 24 +- src/DotNet/Writer/TablesHeap.cs | 71 +- src/DotNet/Writer/USHeap.cs | 25 +- src/DotNet/Writer/UniqueChunkList.cs | 7 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 90 +- src/IO/BinaryReaderStream.cs | 32 +- src/IO/FileOffset.cs | 8 +- src/IO/FileSection.cs | 11 +- src/IO/IBinaryReader.cs | 42 +- src/IO/IImageStream.cs | 8 +- src/IO/IImageStreamCreator.cs | 4 +- src/IO/ImageStreamCreator.cs | 8 +- src/IO/MemoryImageStream.cs | 34 +- src/IO/MemoryMappedFileStreamCreator.cs | 29 +- src/IO/MemoryStreamCreator.cs | 22 +- src/IO/UnmanagedMemoryImageStream.cs | 24 +- src/IO/UnmanagedMemoryStreamCreator.cs | 18 +- src/PE/IPEImage.cs | 14 +- src/PE/ImageDataDirectory.cs | 12 +- src/PE/ImageDebugDirectory.cs | 32 +- src/PE/ImageDosHeader.cs | 6 +- src/PE/ImageFileHeader.cs | 44 +- src/PE/ImageNTHeaders.cs | 20 +- src/PE/ImageOptionalHeader32.cs | 184 +-- src/PE/ImageOptionalHeader64.cs | 182 +-- src/PE/ImageSectionHeader.cs | 64 +- src/PE/PEImage.cs | 67 +- src/PE/PEInfo.cs | 32 +- src/PE/RVA.cs | 8 +- src/Threading/IThreadSafeList.cs | 55 +- src/Threading/Lock.cs | 8 +- src/Threading/ThreadSafeListWrapper.cs | 52 +- src/Utils/LazyList.cs | 60 +- src/Utils/SimpleLazyList.cs | 12 +- src/Utils/UserValue.cs | 8 +- src/W32Resources/ResourceData.cs | 18 +- src/W32Resources/ResourceDirectory.cs | 36 +- src/W32Resources/ResourceDirectoryEntry.cs | 12 +- src/W32Resources/ResourceName.cs | 62 +- src/W32Resources/Win32Resources.cs | 12 +- 259 files changed, 5914 insertions(+), 12896 deletions(-) diff --git a/src/DotNet/AllTypesHelper.cs b/src/DotNet/AllTypesHelper.cs index 1d0429ba8..234fbbe91 100644 --- a/src/DotNet/AllTypesHelper.cs +++ b/src/DotNet/AllTypesHelper.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet { /// /// Returns types without getting stuck in an infinite loop /// - public struct AllTypesHelper { + public readonly struct AllTypesHelper { /// /// Gets a list of all types and nested types /// diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index e4778badf..86fb68400 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -28,32 +28,26 @@ public abstract class AssemblyDef : IHasCustomAttribute, IHasDeclSecurity, IHasC protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.Assembly, rid); } - } + public MDToken MDToken => new MDToken(Table.Assembly, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 14; } - } + public int HasCustomAttributeTag => 14; /// - public int HasDeclSecurityTag { - get { return 2; } - } + public int HasDeclSecurityTag => 2; /// /// From column Assembly.HashAlgId /// public AssemblyHashAlgorithm HashAlgorithm { - get { return hashAlgorithm; } - set { hashAlgorithm = value; } + get => hashAlgorithm; + set => hashAlgorithm = value; } /// protected AssemblyHashAlgorithm hashAlgorithm; @@ -64,12 +58,8 @@ public AssemblyHashAlgorithm HashAlgorithm { /// /// If is null public Version Version { - get { return version; } - set { - if (value == null) - throw new ArgumentNullException("value"); - version = value; - } + get => version; + set => version = value ?? throw new ArgumentNullException(nameof(value)); } /// protected Version version; @@ -78,8 +68,8 @@ public Version Version { /// From column Assembly.Flags /// public AssemblyAttributes Attributes { - get { return (AssemblyAttributes)attributes; } - set { attributes = (int)value; } + get => (AssemblyAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -89,8 +79,8 @@ public AssemblyAttributes Attributes { /// /// An empty is created if the caller writes null public PublicKey PublicKey { - get { return publicKey; } - set { publicKey = value ?? new PublicKey(); } + get => publicKey; + set => publicKey = value ?? new PublicKey(); } /// protected PublicKey publicKey; @@ -98,16 +88,14 @@ public PublicKey PublicKey { /// /// Gets the public key token which is calculated from /// - public PublicKeyToken PublicKeyToken { - get { return publicKey.Token; } - } + public PublicKeyToken PublicKeyToken => publicKey.Token; /// /// From column Assembly.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -116,8 +104,8 @@ public UTF8String Name { /// From column Assembly.Locale /// public UTF8String Culture { - get { return culture; } - set { culture = value; } + get => culture; + set => culture = value; } /// Name protected UTF8String culture; @@ -133,24 +121,17 @@ public ThreadSafe.IList DeclSecurities { /// protected ThreadSafe.IList declSecurities; /// Initializes - protected virtual void InitializeDeclSecurities() { + protected virtual void InitializeDeclSecurities() => Interlocked.CompareExchange(ref declSecurities, ThreadSafeListCreator.Create(), null); - } /// - public PublicKeyBase PublicKeyOrToken { - get { return publicKey; } - } + public PublicKeyBase PublicKeyOrToken => publicKey; /// - public string FullName { - get { return GetFullNameWithPublicKeyToken(); } - } + public string FullName => GetFullNameWithPublicKeyToken(); /// - public string FullNameToken { - get { return GetFullNameWithPublicKeyToken(); } - } + public string FullNameToken => GetFullNameWithPublicKeyToken(); /// /// Gets all modules. The first module is always the . @@ -165,9 +146,8 @@ public ThreadSafe.IList Modules { /// protected LazyList modules; /// Initializes - protected virtual void InitializeModules() { + protected virtual void InitializeModules() => Interlocked.CompareExchange(ref modules, new LazyList(this), null); - } /// /// Gets all custom attributes @@ -182,25 +162,18 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 14; } - } + public int HasCustomDebugInformationTag => 14; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -215,28 +188,21 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// - public bool HasDeclSecurities { - get { return DeclSecurities.Count > 0; } - } + public bool HasDeclSecurities => DeclSecurities.Count > 0; /// /// true if is not empty /// - public bool HasModules { - get { return Modules.Count > 0; } - } + public bool HasModules => Modules.Count > 0; /// /// Gets the manifest (main) module. This is always the first module in . /// null is returned if is empty. /// - public ModuleDef ManifestModule { - get { return Modules.Get(0, null); } - } + public ModuleDef ManifestModule => Modules.Get(0, null); /// /// Modify property: = @@ -284,128 +250,110 @@ void ModifyAttributes(bool set, AssemblyAttributes flags) { /// Gets/sets the bit /// public bool HasPublicKey { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PublicKey) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.PublicKey); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.PublicKey) != 0; + set => ModifyAttributes(value, AssemblyAttributes.PublicKey); } /// /// Gets/sets the processor architecture /// public AssemblyAttributes ProcessorArchitecture { - get { return (AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask; } - set { ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); } + get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask; + set => ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); } /// /// Gets/sets the processor architecture /// public AssemblyAttributes ProcessorArchitectureFull { - get { return (AssemblyAttributes)attributes & AssemblyAttributes.PA_FullMask; } - set { ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); } + get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_FullMask; + set => ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); } /// /// true if unspecified processor architecture /// - public bool IsProcessorArchitectureNone { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; } - } + public bool IsProcessorArchitectureNone => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; /// /// true if neutral (PE32) architecture /// - public bool IsProcessorArchitectureMSIL { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; } - } + public bool IsProcessorArchitectureMSIL => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; /// /// true if x86 (PE32) architecture /// - public bool IsProcessorArchitectureX86 { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; } - } + public bool IsProcessorArchitectureX86 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; /// /// true if IA-64 (PE32+) architecture /// - public bool IsProcessorArchitectureIA64 { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; } - } + public bool IsProcessorArchitectureIA64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; /// /// true if x64 (PE32+) architecture /// - public bool IsProcessorArchitectureX64 { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; } - } + public bool IsProcessorArchitectureX64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; /// /// true if ARM (PE32) architecture /// - public bool IsProcessorArchitectureARM { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; } - } + public bool IsProcessorArchitectureARM => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; /// /// true if eg. reference assembly (not runnable) /// - public bool IsProcessorArchitectureNoPlatform { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; } - } + public bool IsProcessorArchitectureNoPlatform => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; /// /// Gets/sets the bit /// public bool IsProcessorArchitectureSpecified { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Specified) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.PA_Specified); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Specified) != 0; + set => ModifyAttributes(value, AssemblyAttributes.PA_Specified); } /// /// Gets/sets the bit /// public bool EnableJITcompileTracking { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; + set => ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); } /// /// Gets/sets the bit /// public bool DisableJITcompileOptimizer { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; + set => ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); } /// /// Gets/sets the bit /// public bool IsRetargetable { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.Retargetable) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.Retargetable); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.Retargetable) != 0; + set => ModifyAttributes(value, AssemblyAttributes.Retargetable); } /// /// Gets/sets the content type /// public AssemblyAttributes ContentType { - get { return (AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask; } - set { ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); } + get => (AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask; + set => ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); } /// /// true if content type is Default /// - public bool IsContentTypeDefault { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; } - } + public bool IsContentTypeDefault => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; /// /// true if content type is WindowsRuntime /// - public bool IsContentTypeWindowsRuntime { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; } - } + public bool IsContentTypeWindowsRuntime => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; /// /// Finds a module in this assembly @@ -430,9 +378,8 @@ public ModuleDef FindModule(UTF8String name) { /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(string fileName, ModuleContext context) { - return Load(fileName, new ModuleCreationOptions(context)); - } + public static AssemblyDef Load(string fileName, ModuleContext context) => + Load(fileName, new ModuleCreationOptions(context)); /// /// Creates an instance from a file @@ -444,13 +391,13 @@ public static AssemblyDef Load(string fileName, ModuleContext context) { /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(string fileName, ModuleCreationOptions options = null) { if (fileName == null) - throw new ArgumentNullException("fileName"); + throw new ArgumentNullException(nameof(fileName)); ModuleDef module = null; try { module = ModuleDefMD.Load(fileName, options); var asm = module.Assembly; if (asm == null) - throw new BadImageFormatException(string.Format("{0} is only a .NET module, not a .NET assembly. Use ModuleDef.Load().", fileName)); + throw new BadImageFormatException($"{fileName} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { @@ -468,9 +415,8 @@ public static AssemblyDef Load(string fileName, ModuleCreationOptions options = /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(byte[] data, ModuleContext context) { - return Load(data, new ModuleCreationOptions(context)); - } + public static AssemblyDef Load(byte[] data, ModuleContext context) => + Load(data, new ModuleCreationOptions(context)); /// /// Creates an instance from a byte[] @@ -482,13 +428,13 @@ public static AssemblyDef Load(byte[] data, ModuleContext context) { /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(byte[] data, ModuleCreationOptions options = null) { if (data == null) - throw new ArgumentNullException("data"); + throw new ArgumentNullException(nameof(data)); ModuleDef module = null; try { module = ModuleDefMD.Load(data, options); var asm = module.Assembly; if (asm == null) - throw new BadImageFormatException(string.Format("{0} is only a .NET module, not a .NET assembly. Use ModuleDef.Load().", module.ToString())); + throw new BadImageFormatException($"{module.ToString()} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { @@ -506,9 +452,8 @@ public static AssemblyDef Load(byte[] data, ModuleCreationOptions options = null /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(IntPtr addr, ModuleContext context) { - return Load(addr, new ModuleCreationOptions(context)); - } + public static AssemblyDef Load(IntPtr addr, ModuleContext context) => + Load(addr, new ModuleCreationOptions(context)); /// /// Creates an instance from a memory location @@ -520,13 +465,13 @@ public static AssemblyDef Load(IntPtr addr, ModuleContext context) { /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options = null) { if (addr == IntPtr.Zero) - throw new ArgumentNullException("addr"); + throw new ArgumentNullException(nameof(addr)); ModuleDef module = null; try { module = ModuleDefMD.Load(addr, options); var asm = module.Assembly; if (asm == null) - throw new BadImageFormatException(string.Format("{0} (addr: {1:X8}) is only a .NET module, not a .NET assembly. Use ModuleDef.Load().", module.ToString(), addr.ToInt64())); + throw new BadImageFormatException($"{module.ToString()} (addr: {addr.ToInt64():X8}) is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { @@ -546,9 +491,8 @@ public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options = null /// A new instance /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) - public static AssemblyDef Load(Stream stream, ModuleContext context) { - return Load(stream, new ModuleCreationOptions(context)); - } + public static AssemblyDef Load(Stream stream, ModuleContext context) => + Load(stream, new ModuleCreationOptions(context)); /// /// Creates an instance from a stream @@ -562,13 +506,13 @@ public static AssemblyDef Load(Stream stream, ModuleContext context) { /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = null) { if (stream == null) - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); ModuleDef module = null; try { module = ModuleDefMD.Load(stream, options); var asm = module.Assembly; if (asm == null) - throw new BadImageFormatException(string.Format("{0} is only a .NET module, not a .NET assembly. Use ModuleDef.Load().", module.ToString())); + throw new BadImageFormatException($"{module.ToString()} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { @@ -581,20 +525,14 @@ public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = nu /// /// Gets the assembly name with the public key /// - public string GetFullNameWithPublicKey() { - return GetFullName(publicKey); - } + public string GetFullNameWithPublicKey() => GetFullName(publicKey); /// /// Gets the assembly name with the public key token /// - public string GetFullNameWithPublicKeyToken() { - return GetFullName(publicKey.Token); - } + public string GetFullNameWithPublicKeyToken() => GetFullName(publicKey.Token); - string GetFullName(PublicKeyBase pkBase) { - return Utils.GetAssemblyNameString(name, version, culture, pkBase, Attributes); - } + string GetFullName(PublicKeyBase pkBase) => Utils.GetAssemblyNameString(name, version, culture, pkBase, Attributes); /// /// Finds a . For speed, enable @@ -639,18 +577,16 @@ public TypeDef Find(TypeRef typeRef) { /// /// Filename /// Writer options - public void Write(string filename, ModuleWriterOptions options = null) { + public void Write(string filename, ModuleWriterOptions options = null) => ManifestModule.Write(filename, options); - } /// /// Writes the assembly to a stream. /// /// Destination stream /// Writer options - public void Write(Stream dest, ModuleWriterOptions options = null) { + public void Write(Stream dest, ModuleWriterOptions options = null) => ManifestModule.Write(dest, options); - } /// /// Checks whether this assembly is a friend assembly of @@ -670,7 +606,7 @@ public bool IsFriendAssemblyOf(AssemblyDef targetAsm) { foreach (var ca in targetAsm.CustomAttributes.FindAll("System.Runtime.CompilerServices.InternalsVisibleToAttribute")) { if (ca.ConstructorArguments.Count != 1) continue; - var arg = ca.ConstructorArguments.Get(0, default(CAArgument)); + var arg = ca.ConstructorArguments.Get(0, default); if (arg.Type.GetElementType() != ElementType.String) continue; var asmName = arg.Value as UTF8String; @@ -819,9 +755,7 @@ void IListListener.OnClear() { } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -875,17 +809,15 @@ public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey) /// If any of the args is invalid public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey, UTF8String locale) { if ((object)name == null) - throw new ArgumentNullException("name"); - if (version == null) - throw new ArgumentNullException("version"); + throw new ArgumentNullException(nameof(name)); if ((object)locale == null) - throw new ArgumentNullException("locale"); - this.modules = new LazyList(this); + throw new ArgumentNullException(nameof(locale)); + modules = new LazyList(this); this.name = name; - this.version = version; + this.version = version ?? throw new ArgumentNullException(nameof(version)); this.publicKey = publicKey ?? new PublicKey(); - this.culture = locale; - this.attributes = (int)AssemblyAttributes.None; + culture = locale; + attributes = (int)AssemblyAttributes.None; } /// @@ -895,8 +827,8 @@ public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey, UT /// If is null public AssemblyDefUser(AssemblyName asmName) : this(new AssemblyNameInfo(asmName)) { - this.hashAlgorithm = (AssemblyHashAlgorithm)asmName.HashAlgorithm; - this.attributes = (int)asmName.Flags; + hashAlgorithm = (AssemblyHashAlgorithm)asmName.HashAlgorithm; + attributes = (int)asmName.Flags; } /// @@ -906,14 +838,14 @@ public AssemblyDefUser(AssemblyName asmName) /// If is null public AssemblyDefUser(IAssembly asmName) { if (asmName == null) - throw new ArgumentNullException("asmName"); - this.modules = new LazyList(this); - this.name = asmName.Name; - this.version = asmName.Version ?? new Version(0, 0, 0, 0); - this.publicKey = asmName.PublicKeyOrToken as PublicKey ?? new PublicKey(); - this.culture = asmName.Culture; - this.attributes = (int)AssemblyAttributes.None; - this.hashAlgorithm = AssemblyHashAlgorithm.SHA1; + throw new ArgumentNullException(nameof(asmName)); + modules = new LazyList(this); + name = asmName.Name; + version = asmName.Version ?? new Version(0, 0, 0, 0); + publicKey = asmName.PublicKeyOrToken as PublicKey ?? new PublicKey(); + culture = asmName.Culture; + attributes = (int)AssemblyAttributes.None; + hashAlgorithm = AssemblyHashAlgorithm.SHA1; } } @@ -927,9 +859,7 @@ sealed class AssemblyDefMD : AssemblyDef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeDeclSecurities() { @@ -996,8 +926,7 @@ void InitializeTargetFrameworkAttribute() { if (caRow == null) continue; var caType = readerModule.ResolveCustomAttributeType(caRow.Type, gpContext); - UTF8String ns, name; - if (!TryGetName(caType, out ns, out name)) + if (!TryGetName(caType, out var ns, out var name)) continue; if (ns != nameSystemRuntimeVersioning || name != nameTargetFrameworkAttribute) continue; @@ -1007,9 +936,7 @@ void InitializeTargetFrameworkAttribute() { var s = ca.ConstructorArguments[0].Value as UTF8String; if ((object)s == null) continue; - string tmpFramework, tmpProfile; - Version tmpVersion; - if (TryCreateTargetFrameworkInfo(s, out tmpFramework, out tmpVersion, out tmpProfile)) { + if (TryCreateTargetFrameworkInfo(s, out var tmpFramework, out var tmpVersion, out var tmpProfile)) { tfaFramework = tmpFramework; tfaVersion = tmpVersion; tfaProfile = tmpProfile; @@ -1025,21 +952,16 @@ void InitializeTargetFrameworkAttribute() { static bool TryGetName(ICustomAttributeType caType, out UTF8String ns, out UTF8String name) { ITypeDefOrRef type; - var mr = caType as MemberRef; - if (mr != null) + if (caType is MemberRef mr) type = mr.DeclaringType; - else { - var md = caType as MethodDef; - type = md == null ? null : md.DeclaringType; - } - var tr = type as TypeRef; - if (tr != null) { + else + type = (caType as MethodDef)?.DeclaringType; + if (type is TypeRef tr) { ns = tr.Namespace; name = tr.Name; return true; } - var td = type as TypeDef; - if (td != null) { + if (type is TypeDef td) { ns = td.Namespace; name = td.Name; return true; @@ -1093,10 +1015,7 @@ static bool TryCreateTargetFrameworkInfo(string attrString, out string framework return true; } - static int ParseInt32(string s) { - int res; - return int.TryParse(s, out res) ? res : 0; - } + static int ParseInt32(string s) => int.TryParse(s, out int res) ? res : 0; static bool TryParse(string s, out Version version) { Match m; @@ -1135,15 +1054,14 @@ public AssemblyDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.AssemblyTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Assembly rid {0} does not exist", rid)); + throw new BadImageFormatException($"Assembly rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; if (rid != 1) - this.modules = new LazyList(this); - uint publicKey, name; - uint culture = readerModule.TablesStream.ReadAssemblyRow(origRid, out this.hashAlgorithm, out this.version, out this.attributes, out publicKey, out name); + modules = new LazyList(this); + uint culture = readerModule.TablesStream.ReadAssemblyRow(origRid, out hashAlgorithm, out version, out attributes, out uint publicKey, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); this.culture = readerModule.StringsStream.ReadNoNull(culture); this.publicKey = new PublicKey(readerModule.BlobStream.Read(publicKey)); diff --git a/src/DotNet/AssemblyHash.cs b/src/DotNet/AssemblyHash.cs index 9f01522c9..d16c0108c 100644 --- a/src/DotNet/AssemblyHash.cs +++ b/src/DotNet/AssemblyHash.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet { /// /// Hashes some data according to a /// - struct AssemblyHash : IDisposable { + readonly struct AssemblyHash : IDisposable { readonly HashAlgorithm hasher; /// @@ -78,9 +78,7 @@ public static byte[] Hash(byte[] data, AssemblyHashAlgorithm hashAlgo) { /// Hash data /// /// Data - public void Hash(byte[] data) { - Hash(data, 0, data.Length); - } + public void Hash(byte[] data) => Hash(data, 0, data.Length); /// /// Hash data @@ -128,7 +126,7 @@ public static PublicKeyToken CreatePublicKeyToken(byte[] publicKeyData) { if (publicKeyData == null) return new PublicKeyToken(); var hash = Hash(publicKeyData, AssemblyHashAlgorithm.SHA1); - byte[] pkt = new byte[8]; + var pkt = new byte[8]; for (int i = 0; i < pkt.Length && i < hash.Length; i++) pkt[i] = hash[hash.Length - i - 1]; return new PublicKeyToken(pkt); diff --git a/src/DotNet/AssemblyNameComparer.cs b/src/DotNet/AssemblyNameComparer.cs index ed6f6535f..65224c2c3 100644 --- a/src/DotNet/AssemblyNameComparer.cs +++ b/src/DotNet/AssemblyNameComparer.cs @@ -43,7 +43,7 @@ public enum AssemblyNameComparerFlags { /// /// Compares two assembly names /// - public struct AssemblyNameComparer : IEqualityComparer { + public readonly struct AssemblyNameComparer : IEqualityComparer { /// /// Compares the name, version, public key token, culture and content type /// @@ -64,45 +64,33 @@ public struct AssemblyNameComparer : IEqualityComparer { /// /// Gets the bit /// - public bool CompareName { - get { return (flags & AssemblyNameComparerFlags.Name) != 0; } - } + public bool CompareName => (flags & AssemblyNameComparerFlags.Name) != 0; /// /// Gets the bit /// - public bool CompareVersion { - get { return (flags & AssemblyNameComparerFlags.Version) != 0; } - } + public bool CompareVersion => (flags & AssemblyNameComparerFlags.Version) != 0; /// /// Gets the bit /// - public bool ComparePublicKeyToken { - get { return (flags & AssemblyNameComparerFlags.PublicKeyToken) != 0; } - } + public bool ComparePublicKeyToken => (flags & AssemblyNameComparerFlags.PublicKeyToken) != 0; /// /// Gets the bit /// - public bool CompareCulture { - get { return (flags & AssemblyNameComparerFlags.Culture) != 0; } - } + public bool CompareCulture => (flags & AssemblyNameComparerFlags.Culture) != 0; /// /// Gets the bit /// - public bool CompareContentType { - get { return (flags & AssemblyNameComparerFlags.ContentType) != 0; } - } + public bool CompareContentType => (flags & AssemblyNameComparerFlags.ContentType) != 0; /// /// Constructor /// /// Comparison flags - public AssemblyNameComparer(AssemblyNameComparerFlags flags) { - this.flags = flags; - } + public AssemblyNameComparer(AssemblyNameComparerFlags flags) => this.flags = flags; /// /// Compares two assembly names @@ -140,9 +128,7 @@ public int CompareTo(IAssembly a, IAssembly b) { /// First /// Second /// true if equal, false otherwise - public bool Equals(IAssembly a, IAssembly b) { - return CompareTo(a, b) == 0; - } + public bool Equals(IAssembly a, IAssembly b) => CompareTo(a, b) == 0; /// /// Figures out which of two assembly names is closer to another assembly name diff --git a/src/DotNet/AssemblyNameInfo.cs b/src/DotNet/AssemblyNameInfo.cs index 45fbe9426..bc947e9c0 100644 --- a/src/DotNet/AssemblyNameInfo.cs +++ b/src/DotNet/AssemblyNameInfo.cs @@ -19,56 +19,54 @@ public sealed class AssemblyNameInfo : IAssembly { /// Gets/sets the /// public AssemblyHashAlgorithm HashAlgId { - get { return hashAlgId; } - set { hashAlgId = value; } + get => hashAlgId; + set => hashAlgId = value; } /// /// Gets/sets the or null if none specified /// public Version Version { - get { return version; } - set { version = value; } + get => version; + set => version = value; } /// /// Gets/sets the /// public AssemblyAttributes Attributes { - get { return flags; } - set { flags = value; } + get => flags; + set => flags = value; } /// /// Gets/sets the public key or token /// public PublicKeyBase PublicKeyOrToken { - get { return publicKeyOrToken; } - set { publicKeyOrToken = value; } + get => publicKeyOrToken; + set => publicKeyOrToken = value; } /// /// Gets/sets the name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets/sets the culture or null if none specified /// public UTF8String Culture { - get { return culture; } - set { culture = value; } + get => culture; + set => culture = value; } /// /// Gets the full name of the assembly /// - public string FullName { - get { return FullNameToken; } - } + public string FullName => FullNameToken; /// /// Gets the full name of the assembly but use a public key token @@ -88,9 +86,7 @@ public string FullNameToken { /// /// Value to AND /// Value to OR - void ModifyAttributes(AssemblyAttributes andMask, AssemblyAttributes orMask) { - Attributes = (Attributes & andMask) | orMask; - } + void ModifyAttributes(AssemblyAttributes andMask, AssemblyAttributes orMask) => Attributes = (Attributes & andMask) | orMask; /// /// Set or clear flags in @@ -109,128 +105,110 @@ void ModifyAttributes(bool set, AssemblyAttributes flags) { /// Gets/sets the bit /// public bool HasPublicKey { - get { return (Attributes & AssemblyAttributes.PublicKey) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.PublicKey); } + get => (Attributes & AssemblyAttributes.PublicKey) != 0; + set => ModifyAttributes(value, AssemblyAttributes.PublicKey); } /// /// Gets/sets the processor architecture /// public AssemblyAttributes ProcessorArchitecture { - get { return Attributes & AssemblyAttributes.PA_Mask; } - set { ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); } + get => Attributes & AssemblyAttributes.PA_Mask; + set => ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); } /// /// Gets/sets the processor architecture /// public AssemblyAttributes ProcessorArchitectureFull { - get { return Attributes & AssemblyAttributes.PA_FullMask; } - set { ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); } + get => Attributes & AssemblyAttributes.PA_FullMask; + set => ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); } /// /// true if unspecified processor architecture /// - public bool IsProcessorArchitectureNone { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; } - } + public bool IsProcessorArchitectureNone => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; /// /// true if neutral (PE32) architecture /// - public bool IsProcessorArchitectureMSIL { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; } - } + public bool IsProcessorArchitectureMSIL => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; /// /// true if x86 (PE32) architecture /// - public bool IsProcessorArchitectureX86 { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; } - } + public bool IsProcessorArchitectureX86 => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; /// /// true if IA-64 (PE32+) architecture /// - public bool IsProcessorArchitectureIA64 { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; } - } + public bool IsProcessorArchitectureIA64 => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; /// /// true if x64 (PE32+) architecture /// - public bool IsProcessorArchitectureX64 { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; } - } + public bool IsProcessorArchitectureX64 => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; /// /// true if ARM (PE32) architecture /// - public bool IsProcessorArchitectureARM { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; } - } + public bool IsProcessorArchitectureARM => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; /// /// true if eg. reference assembly (not runnable) /// - public bool IsProcessorArchitectureNoPlatform { - get { return (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; } - } + public bool IsProcessorArchitectureNoPlatform => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; /// /// Gets/sets the bit /// public bool IsProcessorArchitectureSpecified { - get { return (Attributes & AssemblyAttributes.PA_Specified) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.PA_Specified); } + get => (Attributes & AssemblyAttributes.PA_Specified) != 0; + set => ModifyAttributes(value, AssemblyAttributes.PA_Specified); } /// /// Gets/sets the bit /// public bool EnableJITcompileTracking { - get { return (Attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); } + get => (Attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; + set => ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); } /// /// Gets/sets the bit /// public bool DisableJITcompileOptimizer { - get { return (Attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); } + get => (Attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; + set => ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); } /// /// Gets/sets the bit /// public bool IsRetargetable { - get { return (Attributes & AssemblyAttributes.Retargetable) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.Retargetable); } + get => (Attributes & AssemblyAttributes.Retargetable) != 0; + set => ModifyAttributes(value, AssemblyAttributes.Retargetable); } /// /// Gets/sets the content type /// public AssemblyAttributes ContentType { - get { return Attributes & AssemblyAttributes.ContentType_Mask; } - set { ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); } + get => Attributes & AssemblyAttributes.ContentType_Mask; + set => ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); } /// /// true if content type is Default /// - public bool IsContentTypeDefault { - get { return (Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; } - } + public bool IsContentTypeDefault => (Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; /// /// true if content type is WindowsRuntime /// - public bool IsContentTypeWindowsRuntime { - get { return (Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; } - } + public bool IsContentTypeWindowsRuntime => (Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; /// /// Default constructor @@ -254,12 +232,12 @@ public AssemblyNameInfo(IAssembly asm) { if (asm == null) return; var asmDef = asm as AssemblyDef; - this.hashAlgId = asmDef == null ? 0 : asmDef.HashAlgorithm; - this.version = asm.Version ?? new Version(0, 0, 0, 0); - this.flags = asm.Attributes; - this.publicKeyOrToken = asm.PublicKeyOrToken; - this.name = UTF8String.IsNullOrEmpty(asm.Name) ? UTF8String.Empty : asm.Name; - this.culture = UTF8String.IsNullOrEmpty(asm.Culture) ? UTF8String.Empty : asm.Culture; + hashAlgId = asmDef == null ? 0 : asmDef.HashAlgorithm; + version = asm.Version ?? new Version(0, 0, 0, 0); + flags = asm.Attributes; + publicKeyOrToken = asm.PublicKeyOrToken; + name = UTF8String.IsNullOrEmpty(asm.Name) ? UTF8String.Empty : asm.Name; + culture = UTF8String.IsNullOrEmpty(asm.Culture) ? UTF8String.Empty : asm.Culture; } /// @@ -269,18 +247,16 @@ public AssemblyNameInfo(IAssembly asm) { public AssemblyNameInfo(AssemblyName asmName) { if (asmName == null) return; - this.hashAlgId = (AssemblyHashAlgorithm)asmName.HashAlgorithm; - this.version = asmName.Version ?? new Version(0, 0, 0, 0); - this.flags = (AssemblyAttributes)asmName.Flags; - this.publicKeyOrToken = (PublicKeyBase)PublicKeyBase.CreatePublicKey(asmName.GetPublicKey()) ?? + hashAlgId = (AssemblyHashAlgorithm)asmName.HashAlgorithm; + version = asmName.Version ?? new Version(0, 0, 0, 0); + flags = (AssemblyAttributes)asmName.Flags; + publicKeyOrToken = (PublicKeyBase)PublicKeyBase.CreatePublicKey(asmName.GetPublicKey()) ?? PublicKeyBase.CreatePublicKeyToken(asmName.GetPublicKeyToken()); - this.name = asmName.Name ?? string.Empty; - this.culture = asmName.CultureInfo != null && asmName.CultureInfo.Name != null ? asmName.CultureInfo.Name : string.Empty; + name = asmName.Name ?? string.Empty; + culture = asmName.CultureInfo != null && asmName.CultureInfo.Name != null ? asmName.CultureInfo.Name : string.Empty; } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } } diff --git a/src/DotNet/AssemblyRef.cs b/src/DotNet/AssemblyRef.cs index 58b7aad1c..81f08f57f 100644 --- a/src/DotNet/AssemblyRef.cs +++ b/src/DotNet/AssemblyRef.cs @@ -31,40 +31,28 @@ public abstract class AssemblyRef : IHasCustomAttribute, IImplementation, IResol protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.AssemblyRef, rid); } - } + public MDToken MDToken => new MDToken(Table.AssemblyRef, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 15; } - } + public int HasCustomAttributeTag => 15; /// - public int ImplementationTag { - get { return 1; } - } + public int ImplementationTag => 1; /// - public int ResolutionScopeTag { - get { return 2; } - } + public int ResolutionScopeTag => 2; /// - public ScopeType ScopeType { - get { return ScopeType.AssemblyRef; } - } + public ScopeType ScopeType => ScopeType.AssemblyRef; /// - public string ScopeName { - get { return FullName; } - } + public string ScopeName => FullName; /// /// From columns AssemblyRef.MajorVersion, AssemblyRef.MinorVersion, @@ -72,12 +60,8 @@ public string ScopeName { /// /// If is null public Version Version { - get { return version; } - set { - if (value == null) - throw new ArgumentNullException("value"); - version = value; - } + get => version; + set => version = value ?? throw new ArgumentNullException(nameof(value)); } /// protected Version version; @@ -86,8 +70,8 @@ public Version Version { /// From column AssemblyRef.Flags /// public AssemblyAttributes Attributes { - get { return (AssemblyAttributes)attributes; } - set { attributes = (int)value; } + get => (AssemblyAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -97,12 +81,8 @@ public AssemblyAttributes Attributes { /// /// If is null public PublicKeyBase PublicKeyOrToken { - get { return publicKeyOrToken; } - set { - if (value == null) - throw new ArgumentNullException("value"); - publicKeyOrToken = value; - } + get => publicKeyOrToken; + set => publicKeyOrToken = value ?? throw new ArgumentNullException(nameof(value)); } /// protected PublicKeyBase publicKeyOrToken; @@ -111,8 +91,8 @@ public PublicKeyBase PublicKeyOrToken { /// From column AssemblyRef.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -121,8 +101,8 @@ public UTF8String Name { /// From column AssemblyRef.Locale /// public UTF8String Culture { - get { return culture; } - set { culture = value; } + get => culture; + set => culture = value; } /// Culture protected UTF8String culture; @@ -131,8 +111,8 @@ public UTF8String Culture { /// From column AssemblyRef.HashValue /// public byte[] Hash { - get { return hashValue; } - set { hashValue = value; } + get => hashValue; + set => hashValue = value; } /// protected byte[] hashValue; @@ -150,24 +130,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 15; } - } + public int HasCustomDebugInformationTag => 15; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -182,28 +155,21 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// - public string FullName { - get { return FullNameToken; } - } + public string FullName => FullNameToken; /// /// Same as , except that it uses the PublicKey if available. /// - public string RealFullName { - get { return Utils.GetAssemblyNameString(name, version, culture, publicKeyOrToken, Attributes); } - } + public string RealFullName => Utils.GetAssemblyNameString(name, version, culture, publicKeyOrToken, Attributes); /// /// Gets the full name of the assembly but use a public key token /// - public string FullNameToken { - get { return Utils.GetAssemblyNameString(name, version, culture, PublicKeyBase.ToPublicKeyToken(publicKeyOrToken), Attributes); } - } + public string FullNameToken => Utils.GetAssemblyNameString(name, version, culture, PublicKeyBase.ToPublicKeyToken(publicKeyOrToken), Attributes); /// /// Modify property: = @@ -251,133 +217,113 @@ void ModifyAttributes(bool set, AssemblyAttributes flags) { /// Gets/sets the bit /// public bool HasPublicKey { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PublicKey) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.PublicKey); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.PublicKey) != 0; + set => ModifyAttributes(value, AssemblyAttributes.PublicKey); } /// /// Gets/sets the processor architecture /// public AssemblyAttributes ProcessorArchitecture { - get { return (AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask; } - set { ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); } + get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask; + set => ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); } /// /// Gets/sets the processor architecture /// public AssemblyAttributes ProcessorArchitectureFull { - get { return (AssemblyAttributes)attributes & AssemblyAttributes.PA_FullMask; } - set { ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); } + get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_FullMask; + set => ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); } /// /// true if unspecified processor architecture /// - public bool IsProcessorArchitectureNone { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; } - } + public bool IsProcessorArchitectureNone => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; /// /// true if neutral (PE32) architecture /// - public bool IsProcessorArchitectureMSIL { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; } - } + public bool IsProcessorArchitectureMSIL => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; /// /// true if x86 (PE32) architecture /// - public bool IsProcessorArchitectureX86 { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; } - } + public bool IsProcessorArchitectureX86 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; /// /// true if IA-64 (PE32+) architecture /// - public bool IsProcessorArchitectureIA64 { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; } - } + public bool IsProcessorArchitectureIA64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; /// /// true if x64 (PE32+) architecture /// - public bool IsProcessorArchitectureX64 { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; } - } + public bool IsProcessorArchitectureX64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; /// /// true if ARM (PE32) architecture /// - public bool IsProcessorArchitectureARM { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; } - } + public bool IsProcessorArchitectureARM => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; /// /// true if eg. reference assembly (not runnable) /// - public bool IsProcessorArchitectureNoPlatform { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; } - } + public bool IsProcessorArchitectureNoPlatform => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; /// /// Gets/sets the bit /// public bool IsProcessorArchitectureSpecified { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Specified) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.PA_Specified); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Specified) != 0; + set => ModifyAttributes(value, AssemblyAttributes.PA_Specified); } /// /// Gets/sets the bit /// public bool EnableJITcompileTracking { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; + set => ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); } /// /// Gets/sets the bit /// public bool DisableJITcompileOptimizer { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; + set => ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); } /// /// Gets/sets the bit /// public bool IsRetargetable { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.Retargetable) != 0; } - set { ModifyAttributes(value, AssemblyAttributes.Retargetable); } + get => ((AssemblyAttributes)attributes & AssemblyAttributes.Retargetable) != 0; + set => ModifyAttributes(value, AssemblyAttributes.Retargetable); } /// /// Gets/sets the content type /// public AssemblyAttributes ContentType { - get { return (AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask; } - set { ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); } + get => (AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask; + set => ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); } /// /// true if content type is Default /// - public bool IsContentTypeDefault { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; } - } + public bool IsContentTypeDefault => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; /// /// true if content type is WindowsRuntime /// - public bool IsContentTypeWindowsRuntime { - get { return ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; } - } + public bool IsContentTypeWindowsRuntime => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -387,30 +333,22 @@ public class AssemblyRefUser : AssemblyRef { /// /// Creates a reference to CLR 1.0's mscorlib /// - public static AssemblyRefUser CreateMscorlibReferenceCLR10() { - return new AssemblyRefUser("mscorlib", new Version(1, 0, 3300, 0), new PublicKeyToken("b77a5c561934e089")); - } + public static AssemblyRefUser CreateMscorlibReferenceCLR10() => new AssemblyRefUser("mscorlib", new Version(1, 0, 3300, 0), new PublicKeyToken("b77a5c561934e089")); /// /// Creates a reference to CLR 1.1's mscorlib /// - public static AssemblyRefUser CreateMscorlibReferenceCLR11() { - return new AssemblyRefUser("mscorlib", new Version(1, 0, 5000, 0), new PublicKeyToken("b77a5c561934e089")); - } + public static AssemblyRefUser CreateMscorlibReferenceCLR11() => new AssemblyRefUser("mscorlib", new Version(1, 0, 5000, 0), new PublicKeyToken("b77a5c561934e089")); /// /// Creates a reference to CLR 2.0's mscorlib /// - public static AssemblyRefUser CreateMscorlibReferenceCLR20() { - return new AssemblyRefUser("mscorlib", new Version(2, 0, 0, 0), new PublicKeyToken("b77a5c561934e089")); - } + public static AssemblyRefUser CreateMscorlibReferenceCLR20() => new AssemblyRefUser("mscorlib", new Version(2, 0, 0, 0), new PublicKeyToken("b77a5c561934e089")); /// /// Creates a reference to CLR 4.0's mscorlib /// - public static AssemblyRefUser CreateMscorlibReferenceCLR40() { - return new AssemblyRefUser("mscorlib", new Version(4, 0, 0, 0), new PublicKeyToken("b77a5c561934e089")); - } + public static AssemblyRefUser CreateMscorlibReferenceCLR40() => new AssemblyRefUser("mscorlib", new Version(4, 0, 0, 0), new PublicKeyToken("b77a5c561934e089")); /// /// Default constructor @@ -459,16 +397,14 @@ public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey /// If any of the args is invalid public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey, UTF8String locale) { if ((object)name == null) - throw new ArgumentNullException("name"); - if (version == null) - throw new ArgumentNullException("version"); + throw new ArgumentNullException(nameof(name)); if ((object)locale == null) - throw new ArgumentNullException("locale"); + throw new ArgumentNullException(nameof(locale)); this.name = name; - this.version = version; - this.publicKeyOrToken = publicKey; - this.culture = locale; - this.attributes = (int)(publicKey is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None); + this.version = version ?? throw new ArgumentNullException(nameof(version)); + publicKeyOrToken = publicKey; + culture = locale; + attributes = (int)(publicKey is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None); } /// @@ -477,9 +413,7 @@ public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey /// Assembly name info /// If is null public AssemblyRefUser(AssemblyName asmName) - : this(new AssemblyNameInfo(asmName)) { - this.attributes = (int)asmName.Flags; - } + : this(new AssemblyNameInfo(asmName)) => attributes = (int)asmName.Flags; /// /// Constructor @@ -489,11 +423,11 @@ public AssemblyRefUser(IAssembly assembly) { if (assembly == null) throw new ArgumentNullException("asmName"); - this.version = assembly.Version ?? new Version(0, 0, 0, 0); - this.publicKeyOrToken = assembly.PublicKeyOrToken; - this.name = UTF8String.IsNullOrEmpty(assembly.Name) ? UTF8String.Empty : assembly.Name; - this.culture = assembly.Culture; - this.attributes = (int)((publicKeyOrToken is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None) | assembly.ContentType); + version = assembly.Version ?? new Version(0, 0, 0, 0); + publicKeyOrToken = assembly.PublicKeyOrToken; + name = UTF8String.IsNullOrEmpty(assembly.Name) ? UTF8String.Empty : assembly.Name; + culture = assembly.Culture; + attributes = (int)((publicKeyOrToken is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None) | assembly.ContentType); } } @@ -507,9 +441,7 @@ sealed class AssemblyRefMD : AssemblyRef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -537,15 +469,14 @@ public AssemblyRefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.AssemblyRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("AssemblyRef rid {0} does not exist", rid)); + throw new BadImageFormatException($"AssemblyRef rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint publicKeyOrToken, name, culture; - uint hashValue = readerModule.TablesStream.ReadAssemblyRefRow(origRid, out this.version, out this.attributes, out publicKeyOrToken, out name, out culture); + uint hashValue = readerModule.TablesStream.ReadAssemblyRefRow(origRid, out version, out attributes, out uint publicKeyOrToken, out uint name, out uint culture); var pkData = readerModule.BlobStream.Read(publicKeyOrToken); - if ((this.attributes & (uint)AssemblyAttributes.PublicKey) != 0) + if ((attributes & (uint)AssemblyAttributes.PublicKey) != 0) this.publicKeyOrToken = new PublicKey(pkData); else this.publicKeyOrToken = new PublicKeyToken(pkData); diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 9cbd81a77..d9c55d761 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -53,10 +53,10 @@ sealed class GacInfo { public readonly IList SubDirs; public GacInfo(int version, string prefix, string path, IList subDirs) { - this.Version = version; - this.Prefix = prefix; - this.Path = path; - this.SubDirs = subDirs; + Version = version; + Prefix = prefix; + Path = path; + SubDirs = subDirs; } } @@ -146,8 +146,8 @@ static IEnumerable FindMonoPrefixes() { /// Gets/sets the default /// public ModuleContext DefaultModuleContext { - get { return defaultModuleContext; } - set { defaultModuleContext = value; } + get => defaultModuleContext; + set => defaultModuleContext = value; } /// @@ -156,8 +156,8 @@ public ModuleContext DefaultModuleContext { /// assembly that is closest to the requested assembly. /// public bool FindExactMatch { - get { return findExactMatch; } - set { findExactMatch = value; } + get => findExactMatch; + set => findExactMatch = value; } /// @@ -167,8 +167,8 @@ public bool FindExactMatch { /// ignored if is true. /// public bool EnableFrameworkRedirect { - get { return enableFrameworkRedirect; } - set { enableFrameworkRedirect = value; } + get => enableFrameworkRedirect; + set => enableFrameworkRedirect = value; } /// @@ -177,31 +177,27 @@ public bool EnableFrameworkRedirect { /// enabled by default since these modules shouldn't be modified by the user. /// public bool EnableTypeDefCache { - get { return enableTypeDefCache; } - set { enableTypeDefCache = value; } + get => enableTypeDefCache; + set => enableTypeDefCache = value; } /// /// true to search the Global Assembly Cache. Default value is true. /// public bool UseGAC { - get { return useGac; } - set { useGac = value; } + get => useGac; + set => useGac = value; } /// /// Gets paths searched before trying the standard locations /// - public ThreadSafe.IList PreSearchPaths { - get { return preSearchPaths; } - } + public ThreadSafe.IList PreSearchPaths => preSearchPaths; /// /// Gets paths searched after trying the standard locations /// - public ThreadSafe.IList PostSearchPaths { - get { return postSearchPaths; } - } + public ThreadSafe.IList PostSearchPaths => postSearchPaths; /// /// Default constructor @@ -226,7 +222,7 @@ public AssemblyResolver(ModuleContext defaultModuleContext) /// paths, not just the module search paths and the GAC. public AssemblyResolver(ModuleContext defaultModuleContext, bool addOtherSearchPaths) { this.defaultModuleContext = defaultModuleContext; - this.enableFrameworkRedirect = true; + enableFrameworkRedirect = true; if (addOtherSearchPaths) AddOtherSearchPaths(postSearchPaths); } @@ -242,7 +238,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - AssemblyDef resolvedAssembly = Resolve2(assembly, sourceModule); + var resolvedAssembly = Resolve2(assembly, sourceModule); if (resolvedAssembly == null) { string asmName = UTF8String.ToSystemStringOrEmpty(assembly.Name); string asmNameTrimmed = asmName.Trim(); @@ -266,9 +262,8 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { var key1 = GetAssemblyNameKey(resolvedAssembly); var key2 = GetAssemblyNameKey(assembly); - AssemblyDef asm1, asm2; - cachedAssemblies.TryGetValue(key1, out asm1); - cachedAssemblies.TryGetValue(key2, out asm2); + cachedAssemblies.TryGetValue(key1, out var asm1); + cachedAssemblies.TryGetValue(key2, out var asm2); if (asm1 != resolvedAssembly && asm2 != resolvedAssembly) { // This assembly was just resolved @@ -307,11 +302,10 @@ public bool AddToCache(AssemblyDef asm) { if (asm == null) return false; var asmKey = GetAssemblyNameKey(asm); - AssemblyDef cachedAsm; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (cachedAssemblies.TryGetValue(asmKey, out cachedAsm) && cachedAsm != null) + if (cachedAssemblies.TryGetValue(asmKey, out var cachedAsm) && cachedAsm != null) return asm == cachedAsm; cachedAssemblies[asmKey] = asm; return true; @@ -359,9 +353,7 @@ static string GetAssemblyNameKey(IAssembly asmName) { } AssemblyDef Resolve2(IAssembly assembly, ModuleDef sourceModule) { - AssemblyDef resolvedAssembly; - - if (cachedAssemblies.TryGetValue(GetAssemblyNameKey(assembly), out resolvedAssembly)) + if (cachedAssemblies.TryGetValue(GetAssemblyNameKey(assembly), out var resolvedAssembly)) return resolvedAssembly; var moduleContext = defaultModuleContext; @@ -470,8 +462,7 @@ AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumer bool IsCached(AssemblyDef asm) { if (asm == null) return false; - AssemblyDef cachedAsm; - return cachedAssemblies.TryGetValue(GetAssemblyNameKey(asm), out cachedAsm) && + return cachedAssemblies.TryGetValue(GetAssemblyNameKey(asm), out var cachedAsm) && cachedAsm == asm; } @@ -588,7 +579,7 @@ IEnumerable FindAssembliesGacExactly(GacInfo gacInfo, IAssembly assembly foreach (var subDir in gacInfo.SubDirs) { var baseDir = Path.Combine(gacInfo.Path, subDir); baseDir = Path.Combine(baseDir, asmSimpleName); - baseDir = Path.Combine(baseDir, string.Format("{0}{1}_{2}_{3}", gacInfo.Prefix, verString, cultureString, pktString)); + baseDir = Path.Combine(baseDir, $"{gacInfo.Prefix}{verString}_{cultureString}_{pktString}"); var pathName = Path.Combine(baseDir, asmSimpleName + ".dll"); if (File.Exists(pathName)) yield return pathName; @@ -661,11 +652,10 @@ IEnumerable FindAssembliesModuleSearchPaths(IAssembly assembly, ModuleDe /// The module or null if unknown /// A list of all search paths to use for this module IEnumerable GetSearchPaths(ModuleDef module) { - ModuleDef keyModule = module; + var keyModule = module; if (keyModule == null) keyModule = nullModule; - IList searchPaths; - if (moduleSearchPaths.TryGetValue(keyModule, out searchPaths)) + if (moduleSearchPaths.TryGetValue(keyModule, out var searchPaths)) return searchPaths; moduleSearchPaths[keyModule] = searchPaths = new List(GetModuleSearchPaths(module)); return searchPaths; @@ -678,9 +668,7 @@ IEnumerable GetSearchPaths(ModuleDef module) { /// /// The module or null if unknown /// A list of search paths - protected virtual IEnumerable GetModuleSearchPaths(ModuleDef module) { - return GetModulePrivateSearchPaths(module); - } + protected virtual IEnumerable GetModuleSearchPaths(ModuleDef module) => GetModulePrivateSearchPaths(module); /// /// Gets all private assembly search paths as found in the module's .config file. diff --git a/src/DotNet/CallingConventionSig.cs b/src/DotNet/CallingConventionSig.cs index b78e8f2d3..2c444480f 100644 --- a/src/DotNet/CallingConventionSig.cs +++ b/src/DotNet/CallingConventionSig.cs @@ -37,99 +37,75 @@ public abstract class CallingConventionSig : IContainsGenericParameter { /// Gets/sets the extra data found after the signature /// public byte[] ExtraData { - get { return extraData; } - set { extraData = value; } + get => extraData; + set => extraData = value; } /// /// Returns true if is set /// - public bool IsDefault { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.Default; } - } + public bool IsDefault => (callingConvention & CallingConvention.Mask) == CallingConvention.Default; /// /// Returns true if is set /// - public bool IsC { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.C; } - } + public bool IsC => (callingConvention & CallingConvention.Mask) == CallingConvention.C; /// /// Returns true if is set /// - public bool IsStdCall { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.StdCall; } - } + public bool IsStdCall => (callingConvention & CallingConvention.Mask) == CallingConvention.StdCall; /// /// Returns true if is set /// - public bool IsThisCall { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.ThisCall; } - } + public bool IsThisCall => (callingConvention & CallingConvention.Mask) == CallingConvention.ThisCall; /// /// Returns true if is set /// - public bool IsFastCall { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.FastCall; } - } + public bool IsFastCall => (callingConvention & CallingConvention.Mask) == CallingConvention.FastCall; /// /// Returns true if is set /// - public bool IsVarArg { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.VarArg; } - } + public bool IsVarArg => (callingConvention & CallingConvention.Mask) == CallingConvention.VarArg; /// /// Returns true if is set /// - public bool IsField { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.Field; } - } + public bool IsField => (callingConvention & CallingConvention.Mask) == CallingConvention.Field; /// /// Returns true if is set /// - public bool IsLocalSig { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.LocalSig; } - } + public bool IsLocalSig => (callingConvention & CallingConvention.Mask) == CallingConvention.LocalSig; /// /// Returns true if is set /// - public bool IsProperty { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.Property; } - } + public bool IsProperty => (callingConvention & CallingConvention.Mask) == CallingConvention.Property; /// /// Returns true if is set /// - public bool IsUnmanaged { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.Unmanaged; } - } + public bool IsUnmanaged => (callingConvention & CallingConvention.Mask) == CallingConvention.Unmanaged; /// /// Returns true if is set /// - public bool IsGenericInst { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.GenericInst; } - } + public bool IsGenericInst => (callingConvention & CallingConvention.Mask) == CallingConvention.GenericInst; /// /// Returns true if is set /// - public bool IsNativeVarArg { - get { return (callingConvention & CallingConvention.Mask) == CallingConvention.NativeVarArg; } - } + public bool IsNativeVarArg => (callingConvention & CallingConvention.Mask) == CallingConvention.NativeVarArg; /// /// Gets/sets the bit /// public bool Generic { - get { return (callingConvention & CallingConvention.Generic) != 0; } + get => (callingConvention & CallingConvention.Generic) != 0; set { if (value) callingConvention |= CallingConvention.Generic; @@ -142,7 +118,7 @@ public bool Generic { /// Gets/sets the bit /// public bool HasThis { - get { return (callingConvention & CallingConvention.HasThis) != 0; } + get => (callingConvention & CallingConvention.HasThis) != 0; set { if (value) callingConvention |= CallingConvention.HasThis; @@ -155,7 +131,7 @@ public bool HasThis { /// Gets/sets the bit /// public bool ExplicitThis { - get { return (callingConvention & CallingConvention.ExplicitThis) != 0; } + get => (callingConvention & CallingConvention.ExplicitThis) != 0; set { if (value) callingConvention |= CallingConvention.ExplicitThis; @@ -168,7 +144,7 @@ public bool ExplicitThis { /// Gets/sets the bit /// public bool ReservedByCLR { - get { return (callingConvention & CallingConvention.ReservedByCLR) != 0; } + get => (callingConvention & CallingConvention.ReservedByCLR) != 0; set { if (value) callingConvention |= CallingConvention.ReservedByCLR; @@ -180,17 +156,13 @@ public bool ReservedByCLR { /// /// true if there's an implicit this parameter /// - public bool ImplicitThis { - get { return HasThis && !ExplicitThis; } - } + public bool ImplicitThis => HasThis && !ExplicitThis; /// /// true if this contains a /// or a . /// - public bool ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// /// Default constructor @@ -202,16 +174,12 @@ protected CallingConventionSig() { /// Constructor /// /// The calling convention - protected CallingConventionSig(CallingConvention callingConvention) { - this.callingConvention = callingConvention; - } + protected CallingConventionSig(CallingConvention callingConvention) => this.callingConvention = callingConvention; /// /// Gets the calling convention /// - public CallingConvention GetCallingConvention() { - return callingConvention; - } + public CallingConvention GetCallingConvention() => callingConvention; } /// @@ -224,23 +192,21 @@ public sealed class FieldSig : CallingConventionSig { /// Gets/sets the field type /// public TypeSig Type { - get { return type; } - set { type = value; } + get => type; + set => type = value; } /// /// Default constructor /// - public FieldSig() { - this.callingConvention = CallingConvention.Field; - } + public FieldSig() => callingConvention = CallingConvention.Field; /// /// Constructor /// /// Field type public FieldSig(TypeSig type) { - this.callingConvention = CallingConvention.Field; + callingConvention = CallingConvention.Field; this.type = type; } @@ -257,14 +223,10 @@ internal FieldSig(CallingConvention callingConvention, TypeSig type) { /// /// Clone this /// - public FieldSig Clone() { - return new FieldSig(callingConvention, type); - } + public FieldSig Clone() => new FieldSig(callingConvention, type); /// - public override string ToString() { - return FullNameCreator.FullName(type == null ? null : type, false, null, null, null, null); - } + public override string ToString() => FullNameCreator.FullName(type, false, null, null, null, null); } /// @@ -284,31 +246,29 @@ public abstract class MethodBaseSig : CallingConventionSig { /// Gets/sets the calling convention /// public CallingConvention CallingConvention { - get { return callingConvention; } - set { callingConvention = value; } + get => callingConvention; + set => callingConvention = value; } /// /// Gets/sets the return type /// public TypeSig RetType { - get { return retType; } - set { retType = value; } + get => retType; + set => retType = value; } /// /// Gets the parameters. This is never null /// - public ThreadSafe.IList Params { - get { return parameters; } - } + public ThreadSafe.IList Params => parameters; /// /// Gets/sets the generic param count /// public uint GenParamCount { - get { return genParamCount; } - set { genParamCount = value; } + get => genParamCount; + set => genParamCount = value; } /// @@ -316,8 +276,8 @@ public uint GenParamCount { /// if there's no sentinel. It can still be empty even if it's not null. /// public ThreadSafe.IList ParamsAfterSentinel { - get { return paramsAfterSentinel; } - set { paramsAfterSentinel = value; } + get => paramsAfterSentinel; + set => paramsAfterSentinel = value; } } @@ -332,26 +292,22 @@ public sealed class MethodSig : MethodBaseSig { /// and it's a hint to the module writer if it tries to re-use the same token. /// public uint OriginalToken { - get { return origToken; } - set { origToken = value; } + get => origToken; + set => origToken = value; } /// /// Creates a static MethodSig /// /// Return type - public static MethodSig CreateStatic(TypeSig retType) { - return new MethodSig(CallingConvention.Default, 0, retType); - } + public static MethodSig CreateStatic(TypeSig retType) => new MethodSig(CallingConvention.Default, 0, retType); /// /// Creates a static MethodSig /// /// Return type /// Arg type #1 - public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1) { - return new MethodSig(CallingConvention.Default, 0, retType, argType1); - } + public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default, 0, retType, argType1); /// /// Creates a static MethodSig @@ -359,9 +315,7 @@ public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1) { /// Return type /// Arg type #1 /// Arg type #2 - public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) { - return new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2); - } + public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2); /// /// Creates a static MethodSig @@ -370,35 +324,27 @@ public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig /// Arg type #1 /// Arg type #2 /// Arg type #3 - public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - return new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2, argType3); - } + public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2, argType3); /// /// Creates a static MethodSig /// /// Return type /// Argument types - public static MethodSig CreateStatic(TypeSig retType, params TypeSig[] argTypes) { - return new MethodSig(CallingConvention.Default, 0, retType, argTypes); - } + public static MethodSig CreateStatic(TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default, 0, retType, argTypes); /// /// Creates an instance MethodSig /// /// Return type - public static MethodSig CreateInstance(TypeSig retType) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType); - } + public static MethodSig CreateInstance(TypeSig retType) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType); /// /// Creates an instance MethodSig /// /// Return type /// Arg type #1 - public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1); - } + public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1); /// /// Creates an instance MethodSig @@ -406,9 +352,7 @@ public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1) { /// Return type /// Arg type #1 /// Arg type #2 - public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2); - } + public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2); /// /// Creates an instance MethodSig @@ -417,27 +361,21 @@ public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSi /// Arg type #1 /// Arg type #2 /// Arg type #3 - public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2, argType3); - } + public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2, argType3); /// /// Creates an instance MethodSig /// /// Return type /// Argument types - public static MethodSig CreateInstance(TypeSig retType, params TypeSig[] argTypes) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argTypes); - } + public static MethodSig CreateInstance(TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argTypes); /// /// Creates a static generic MethodSig /// /// Number of generic parameters /// Return type - public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType) { - return new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType); - } + public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType); /// /// Creates a static generic MethodSig @@ -445,9 +383,7 @@ public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType) /// Number of generic parameters /// Return type /// Arg type #1 - public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) { - return new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1); - } + public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1); /// /// Creates a static generic MethodSig @@ -456,9 +392,7 @@ public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, /// Return type /// Arg type #1 /// Arg type #2 - public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) { - return new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1, argType2); - } + public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1, argType2); /// /// Creates a static generic MethodSig @@ -468,9 +402,7 @@ public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, /// Arg type #1 /// Arg type #2 /// Arg type #3 - public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - return new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1, argType2, argType3); - } + public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1, argType2, argType3); /// /// Creates a static generic MethodSig @@ -478,18 +410,14 @@ public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, /// Number of generic parameters /// Return type /// Argument types - public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, params TypeSig[] argTypes) { - return new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argTypes); - } + public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argTypes); /// /// Creates an instance generic MethodSig /// /// Number of generic parameters /// Return type - public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType); - } + public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType); /// /// Creates an instance generic MethodSig @@ -497,9 +425,7 @@ public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retTyp /// Number of generic parameters /// Return type /// Arg type #1 - public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1); - } + public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1); /// /// Creates an instance generic MethodSig @@ -508,9 +434,7 @@ public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retTyp /// Return type /// Arg type #1 /// Arg type #2 - public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1, argType2); - } + public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1, argType2); /// /// Creates an instance generic MethodSig @@ -520,9 +444,7 @@ public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retTyp /// Arg type #1 /// Arg type #2 /// Arg type #3 - public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1, argType2, argType3); - } + public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1, argType2, argType3); /// /// Creates an instance generic MethodSig @@ -530,16 +452,12 @@ public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retTyp /// Number of generic parameters /// Return type /// Argument types - public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, params TypeSig[] argTypes) { - return new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argTypes); - } + public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argTypes); /// /// Default constructor /// - public MethodSig() { - this.parameters = ThreadSafeListCreator.Create(); - } + public MethodSig() => parameters = ThreadSafeListCreator.Create(); /// /// Constructor @@ -547,7 +465,7 @@ public MethodSig() { /// Calling convention public MethodSig(CallingConvention callingConvention) { this.callingConvention = callingConvention; - this.parameters = ThreadSafeListCreator.Create(); + parameters = ThreadSafeListCreator.Create(); } /// @@ -558,7 +476,7 @@ public MethodSig(CallingConvention callingConvention) { public MethodSig(CallingConvention callingConvention, uint genParamCount) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; - this.parameters = ThreadSafeListCreator.Create(); + parameters = ThreadSafeListCreator.Create(); } /// @@ -571,7 +489,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(); + parameters = ThreadSafeListCreator.Create(); } /// @@ -585,7 +503,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argType1); + parameters = ThreadSafeListCreator.Create(argType1); } /// @@ -600,7 +518,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argType1, argType2); + parameters = ThreadSafeListCreator.Create(argType1, argType2); } /// @@ -616,7 +534,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argType1, argType2, argType3); + parameters = ThreadSafeListCreator.Create(argType1, argType2, argType3); } /// @@ -630,7 +548,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argTypes); + parameters = ThreadSafeListCreator.Create(argTypes); } /// @@ -644,7 +562,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argTypes); + parameters = ThreadSafeListCreator.Create(argTypes); } /// @@ -659,21 +577,17 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argTypes); + parameters = ThreadSafeListCreator.Create(argTypes); this.paramsAfterSentinel = paramsAfterSentinel == null ? null : ThreadSafeListCreator.Create(paramsAfterSentinel); } /// /// Clone this /// - public MethodSig Clone() { - return new MethodSig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); - } + public MethodSig Clone() => new MethodSig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); /// - public override string ToString() { - return FullNameCreator.MethodBaseSigFullName(this, null); - } + public override string ToString() => FullNameCreator.MethodBaseSigFullName(this, null); } /// @@ -684,18 +598,14 @@ public sealed class PropertySig : MethodBaseSig { /// Creates a static PropertySig /// /// Return type - public static PropertySig CreateStatic(TypeSig retType) { - return new PropertySig(false, retType); - } + public static PropertySig CreateStatic(TypeSig retType) => new PropertySig(false, retType); /// /// Creates a static PropertySig /// /// Return type /// Arg type #1 - public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1) { - return new PropertySig(false, retType, argType1); - } + public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1) => new PropertySig(false, retType, argType1); /// /// Creates a static PropertySig @@ -703,9 +613,7 @@ public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1) { /// Return type /// Arg type #1 /// Arg type #2 - public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) { - return new PropertySig(false, retType, argType1, argType2); - } + public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) => new PropertySig(false, retType, argType1, argType2); /// /// Creates a static PropertySig @@ -714,35 +622,27 @@ public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSi /// Arg type #1 /// Arg type #2 /// Arg type #3 - public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - return new PropertySig(false, retType, argType1, argType2, argType3); - } + public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new PropertySig(false, retType, argType1, argType2, argType3); /// /// Creates a static PropertySig /// /// Return type /// Argument types - public static PropertySig CreateStatic(TypeSig retType, params TypeSig[] argTypes) { - return new PropertySig(false, retType, argTypes); - } + public static PropertySig CreateStatic(TypeSig retType, params TypeSig[] argTypes) => new PropertySig(false, retType, argTypes); /// /// Creates an instance PropertySig /// /// Return type - public static PropertySig CreateInstance(TypeSig retType) { - return new PropertySig(true, retType); - } + public static PropertySig CreateInstance(TypeSig retType) => new PropertySig(true, retType); /// /// Creates an instance PropertySig /// /// Return type /// Arg type #1 - public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1) { - return new PropertySig(true, retType, argType1); - } + public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1) => new PropertySig(true, retType, argType1); /// /// Creates an instance PropertySig @@ -750,9 +650,7 @@ public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1) { /// Return type /// Arg type #1 /// Arg type #2 - public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) { - return new PropertySig(true, retType, argType1, argType2); - } + public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) => new PropertySig(true, retType, argType1, argType2); /// /// Creates an instance PropertySig @@ -761,25 +659,21 @@ public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, Type /// Arg type #1 /// Arg type #2 /// Arg type #3 - public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - return new PropertySig(true, retType, argType1, argType2, argType3); - } + public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new PropertySig(true, retType, argType1, argType2, argType3); /// /// Creates an instance PropertySig /// /// Return type /// Argument types - public static PropertySig CreateInstance(TypeSig retType, params TypeSig[] argTypes) { - return new PropertySig(true, retType, argTypes); - } + public static PropertySig CreateInstance(TypeSig retType, params TypeSig[] argTypes) => new PropertySig(true, retType, argTypes); /// /// Default constructor /// public PropertySig() { - this.callingConvention = CallingConvention.Property; - this.parameters = ThreadSafeListCreator.Create(); + callingConvention = CallingConvention.Property; + parameters = ThreadSafeListCreator.Create(); } /// @@ -788,7 +682,7 @@ public PropertySig() { /// Calling convention (must have Property set) internal PropertySig(CallingConvention callingConvention) { this.callingConvention = callingConvention; - this.parameters = ThreadSafeListCreator.Create(); + parameters = ThreadSafeListCreator.Create(); } /// @@ -796,8 +690,8 @@ internal PropertySig(CallingConvention callingConvention) { /// /// true if instance, false if static public PropertySig(bool hasThis) { - this.callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - this.parameters = ThreadSafeListCreator.Create(); + callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); + parameters = ThreadSafeListCreator.Create(); } /// @@ -806,9 +700,9 @@ public PropertySig(bool hasThis) { /// true if instance, false if static /// Return type public PropertySig(bool hasThis, TypeSig retType) { - this.callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); + callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(); + parameters = ThreadSafeListCreator.Create(); } /// @@ -818,9 +712,9 @@ public PropertySig(bool hasThis, TypeSig retType) { /// Return type /// Arg type #1 public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1) { - this.callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); + callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argType1); + parameters = ThreadSafeListCreator.Create(argType1); } /// @@ -831,9 +725,9 @@ public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1) { /// Arg type #1 /// Arg type #2 public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argType2) { - this.callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); + callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argType1, argType2); + parameters = ThreadSafeListCreator.Create(argType1, argType2); } /// @@ -845,9 +739,9 @@ public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argT /// Arg type #2 /// Arg type #3 public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - this.callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); + callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argType1, argType2, argType3); + parameters = ThreadSafeListCreator.Create(argType1, argType2, argType3); } /// @@ -857,9 +751,9 @@ public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argT /// Return type /// Argument types public PropertySig(bool hasThis, TypeSig retType, params TypeSig[] argTypes) { - this.callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); + callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argTypes); + parameters = ThreadSafeListCreator.Create(argTypes); } /// @@ -874,21 +768,17 @@ internal PropertySig(CallingConvention callingConvention, uint genParamCount, Ty this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; - this.parameters = ThreadSafeListCreator.Create(argTypes); + parameters = ThreadSafeListCreator.Create(argTypes); this.paramsAfterSentinel = paramsAfterSentinel == null ? null : ThreadSafeListCreator.Create(paramsAfterSentinel); } /// /// Clone this /// - public PropertySig Clone() { - return new PropertySig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); - } + public PropertySig Clone() => new PropertySig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); /// - public override string ToString() { - return FullNameCreator.MethodBaseSigFullName(this, null); - } + public override string ToString() => FullNameCreator.MethodBaseSigFullName(this, null); } /// @@ -900,16 +790,14 @@ public sealed class LocalSig : CallingConventionSig { /// /// All local types. This is never null. /// - public ThreadSafe.IList Locals { - get { return locals; } - } + public ThreadSafe.IList Locals => locals; /// /// Default constructor /// public LocalSig() { - this.callingConvention = CallingConvention.LocalSig; - this.locals = ThreadSafeListCreator.Create(); + callingConvention = CallingConvention.LocalSig; + locals = ThreadSafeListCreator.Create(); } /// @@ -919,7 +807,7 @@ public LocalSig() { /// Number of locals internal LocalSig(CallingConvention callingConvention, uint count) { this.callingConvention = callingConvention; - this.locals = ThreadSafeListCreator.Create((int)count); + locals = ThreadSafeListCreator.Create((int)count); } /// @@ -927,8 +815,8 @@ internal LocalSig(CallingConvention callingConvention, uint count) { /// /// Local type #1 public LocalSig(TypeSig local1) { - this.callingConvention = CallingConvention.LocalSig; - this.locals = ThreadSafeListCreator.Create(local1); + callingConvention = CallingConvention.LocalSig; + locals = ThreadSafeListCreator.Create(local1); } /// @@ -937,8 +825,8 @@ public LocalSig(TypeSig local1) { /// Local type #1 /// Local type #2 public LocalSig(TypeSig local1, TypeSig local2) { - this.callingConvention = CallingConvention.LocalSig; - this.locals = ThreadSafeListCreator.Create(local1, local2); + callingConvention = CallingConvention.LocalSig; + locals = ThreadSafeListCreator.Create(local1, local2); } /// @@ -948,8 +836,8 @@ public LocalSig(TypeSig local1, TypeSig local2) { /// Local type #2 /// Local type #3 public LocalSig(TypeSig local1, TypeSig local2, TypeSig local3) { - this.callingConvention = CallingConvention.LocalSig; - this.locals = ThreadSafeListCreator.Create(local1, local2, local3); + callingConvention = CallingConvention.LocalSig; + locals = ThreadSafeListCreator.Create(local1, local2, local3); } /// @@ -957,7 +845,7 @@ public LocalSig(TypeSig local1, TypeSig local2, TypeSig local3) { /// /// All locals public LocalSig(params TypeSig[] locals) { - this.callingConvention = CallingConvention.LocalSig; + callingConvention = CallingConvention.LocalSig; this.locals = ThreadSafeListCreator.Create(locals); } @@ -966,7 +854,7 @@ public LocalSig(params TypeSig[] locals) { /// /// All locals public LocalSig(IList locals) { - this.callingConvention = CallingConvention.LocalSig; + callingConvention = CallingConvention.LocalSig; this.locals = ThreadSafeListCreator.Create(locals); } @@ -976,16 +864,14 @@ public LocalSig(IList locals) { /// All locals (this instance now owns it) /// Dummy internal LocalSig(IList locals, bool dummy) { - this.callingConvention = CallingConvention.LocalSig; + callingConvention = CallingConvention.LocalSig; this.locals = ThreadSafeListCreator.MakeThreadSafe(locals); } /// /// Clone this /// - public LocalSig Clone() { - return new LocalSig(locals); - } + public LocalSig Clone() => new LocalSig(locals); } /// @@ -997,16 +883,14 @@ public sealed class GenericInstMethodSig : CallingConventionSig { /// /// Gets the generic arguments (must be instantiated types, i.e., closed types) /// - public ThreadSafe.IList GenericArguments { - get { return genericArgs; } - } + public ThreadSafe.IList GenericArguments => genericArgs; /// /// Default constructor /// public GenericInstMethodSig() { - this.callingConvention = CallingConvention.GenericInst; - this.genericArgs = ThreadSafeListCreator.Create(); + callingConvention = CallingConvention.GenericInst; + genericArgs = ThreadSafeListCreator.Create(); } /// @@ -1016,7 +900,7 @@ public GenericInstMethodSig() { /// Number of generic args internal GenericInstMethodSig(CallingConvention callingConvention, uint size) { this.callingConvention = callingConvention; - this.genericArgs = ThreadSafeListCreator.Create((int)size); + genericArgs = ThreadSafeListCreator.Create((int)size); } /// @@ -1024,8 +908,8 @@ internal GenericInstMethodSig(CallingConvention callingConvention, uint size) { /// /// Generic arg #1 public GenericInstMethodSig(TypeSig arg1) { - this.callingConvention = CallingConvention.GenericInst; - this.genericArgs = ThreadSafeListCreator.Create(arg1); + callingConvention = CallingConvention.GenericInst; + genericArgs = ThreadSafeListCreator.Create(arg1); } /// @@ -1034,8 +918,8 @@ public GenericInstMethodSig(TypeSig arg1) { /// Generic arg #1 /// Generic arg #2 public GenericInstMethodSig(TypeSig arg1, TypeSig arg2) { - this.callingConvention = CallingConvention.GenericInst; - this.genericArgs = ThreadSafeListCreator.Create(arg1, arg2); + callingConvention = CallingConvention.GenericInst; + genericArgs = ThreadSafeListCreator.Create(arg1, arg2); } /// @@ -1045,8 +929,8 @@ public GenericInstMethodSig(TypeSig arg1, TypeSig arg2) { /// Generic arg #2 /// Generic arg #3 public GenericInstMethodSig(TypeSig arg1, TypeSig arg2, TypeSig arg3) { - this.callingConvention = CallingConvention.GenericInst; - this.genericArgs = ThreadSafeListCreator.Create(arg1, arg2, arg3); + callingConvention = CallingConvention.GenericInst; + genericArgs = ThreadSafeListCreator.Create(arg1, arg2, arg3); } /// @@ -1054,8 +938,8 @@ public GenericInstMethodSig(TypeSig arg1, TypeSig arg2, TypeSig arg3) { /// /// Generic args public GenericInstMethodSig(params TypeSig[] args) { - this.callingConvention = CallingConvention.GenericInst; - this.genericArgs = ThreadSafeListCreator.Create(args); + callingConvention = CallingConvention.GenericInst; + genericArgs = ThreadSafeListCreator.Create(args); } /// @@ -1063,16 +947,14 @@ public GenericInstMethodSig(params TypeSig[] args) { /// /// Generic args public GenericInstMethodSig(IList args) { - this.callingConvention = CallingConvention.GenericInst; - this.genericArgs = ThreadSafeListCreator.Create(args); + callingConvention = CallingConvention.GenericInst; + genericArgs = ThreadSafeListCreator.Create(args); } /// /// Clone this /// - public GenericInstMethodSig Clone() { - return new GenericInstMethodSig(genericArgs); - } + public GenericInstMethodSig Clone() => new GenericInstMethodSig(genericArgs); } public static partial class Extensions { @@ -1081,72 +963,56 @@ public static partial class Extensions { /// /// this /// Field type or null if none - public static TypeSig GetFieldType(this FieldSig sig) { - return sig == null ? null : sig.Type; - } + public static TypeSig GetFieldType(this FieldSig sig) => sig?.Type; /// /// Gets the return type /// /// this /// Return type or null if none - public static TypeSig GetRetType(this MethodBaseSig sig) { - return sig == null ? null : sig.RetType; - } + public static TypeSig GetRetType(this MethodBaseSig sig) => sig?.RetType; /// /// Gets the parameters /// /// this /// The parameters - public static IList GetParams(this MethodBaseSig sig) { - return sig == null ? ThreadSafeListCreator.Create() : sig.Params; - } + public static IList GetParams(this MethodBaseSig sig) => sig?.Params ?? ThreadSafeListCreator.Create(); /// /// Gets the parameter count /// /// this /// Parameter count - public static int GetParamCount(this MethodBaseSig sig) { - return sig == null ? 0 : sig.Params.Count; - } + public static int GetParamCount(this MethodBaseSig sig) => sig?.Params.Count ?? 0; /// /// Gets the generic parameter count /// /// this /// Generic parameter count - public static uint GetGenParamCount(this MethodBaseSig sig) { - return sig == null ? 0 : sig.GenParamCount; - } + public static uint GetGenParamCount(this MethodBaseSig sig) => sig?.GenParamCount ?? 0; /// /// Gets the parameters after the sentinel /// /// this /// Parameters after sentinel or null if none - public static IList GetParamsAfterSentinel(this MethodBaseSig sig) { - return sig == null ? null : sig.ParamsAfterSentinel; - } + public static IList GetParamsAfterSentinel(this MethodBaseSig sig) => sig?.ParamsAfterSentinel; /// /// Gets the locals /// /// this /// All locals - public static IList GetLocals(this LocalSig sig) { - return sig == null ? ThreadSafeListCreator.Create() : sig.Locals; - } + public static IList GetLocals(this LocalSig sig) => sig?.Locals ?? ThreadSafeListCreator.Create(); /// /// Gets the generic arguments /// /// this /// All generic arguments - public static IList GetGenericArguments(this GenericInstMethodSig sig) { - return sig == null ? ThreadSafeListCreator.Create() : sig.GenericArguments; - } + public static IList GetGenericArguments(this GenericInstMethodSig sig) => sig?.GenericArguments ?? ThreadSafeListCreator.Create(); /// /// Gets the property @@ -1154,8 +1020,6 @@ public static IList GetGenericArguments(this GenericInstMethodSig sig) /// this /// The type's property or /// false if input isnull - public static bool GetIsDefault(this CallingConventionSig sig) { - return sig == null ? false : sig.IsDefault; - } + public static bool GetIsDefault(this CallingConventionSig sig) => sig?.IsDefault ?? false; } } diff --git a/src/DotNet/ClassLayout.cs b/src/DotNet/ClassLayout.cs index bc59668b5..fb44363c1 100644 --- a/src/DotNet/ClassLayout.cs +++ b/src/DotNet/ClassLayout.cs @@ -14,22 +14,20 @@ public abstract class ClassLayout : IMDTokenProvider { protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.ClassLayout, rid); } - } + public MDToken MDToken => new MDToken(Table.ClassLayout, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// /// From column ClassLayout.PackingSize /// public ushort PackingSize { - get { return packingSize; } - set { packingSize = value; } + get => packingSize; + set => packingSize = value; } /// protected ushort packingSize; @@ -38,8 +36,8 @@ public ushort PackingSize { /// From column ClassLayout.ClassSize /// public uint ClassSize { - get { return classSize; } - set { classSize = value; } + get => classSize; + set => classSize = value; } /// protected uint classSize; @@ -73,9 +71,7 @@ sealed class ClassLayoutMD : ClassLayout, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// /// Constructor @@ -89,11 +85,11 @@ public ClassLayoutMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ClassLayoutTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("ClassLayout rid {0} does not exist", rid)); + throw new BadImageFormatException($"ClassLayout rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; - this.classSize = readerModule.TablesStream.ReadClassLayoutRow(origRid, out this.packingSize); + classSize = readerModule.TablesStream.ReadClassLayoutRow(origRid, out packingSize); } } } diff --git a/src/DotNet/Constant.cs b/src/DotNet/Constant.cs index 750948b31..5e5c74b60 100644 --- a/src/DotNet/Constant.cs +++ b/src/DotNet/Constant.cs @@ -15,22 +15,20 @@ public abstract class Constant : IMDTokenProvider { protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.Constant, rid); } - } + public MDToken MDToken => new MDToken(Table.Constant, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// /// From column Constant.Type /// public ElementType Type { - get { return type; } - set { type = value; } + get => type; + set => type = value; } /// protected ElementType type; @@ -39,8 +37,8 @@ public ElementType Type { /// From column Constant.Value /// public object Value { - get { return value; } - set { this.value = value; } + get => value; + set => this.value = value; } /// protected object value; @@ -61,7 +59,7 @@ public ConstantUser() { /// /// Value public ConstantUser(object value) { - this.type = GetElementType(value); + type = GetElementType(value); this.value = value; } @@ -104,9 +102,7 @@ sealed class ConstantMD : Constant, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// /// Constructor @@ -120,12 +116,12 @@ public ConstantMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ConstantTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Constant rid {0} does not exist", rid)); + throw new BadImageFormatException($"Constant rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; - uint value = readerModule.TablesStream.ReadConstantRow(origRid, out this.type); - this.value = GetValue(this.type, readerModule.BlobStream.ReadNoNull(value)); + uint value = readerModule.TablesStream.ReadConstantRow(origRid, out type); + this.value = GetValue(type, readerModule.BlobStream.ReadNoNull(value)); } static object GetValue(ElementType etype, byte[] data) { diff --git a/src/DotNet/CorLibTypes.cs b/src/DotNet/CorLibTypes.cs index a5fc6948d..60a24ec28 100644 --- a/src/DotNet/CorLibTypes.cs +++ b/src/DotNet/CorLibTypes.cs @@ -27,99 +27,61 @@ public sealed class CorLibTypes : ICorLibTypes { readonly AssemblyRef corLibAssemblyRef; /// - public CorLibTypeSig Void { - get { return typeVoid; } - } + public CorLibTypeSig Void => typeVoid; /// - public CorLibTypeSig Boolean { - get { return typeBoolean; } - } + public CorLibTypeSig Boolean => typeBoolean; /// - public CorLibTypeSig Char { - get { return typeChar; } - } + public CorLibTypeSig Char => typeChar; /// - public CorLibTypeSig SByte { - get { return typeSByte; } - } + public CorLibTypeSig SByte => typeSByte; /// - public CorLibTypeSig Byte { - get { return typeByte; } - } + public CorLibTypeSig Byte => typeByte; /// - public CorLibTypeSig Int16 { - get { return typeInt16; } - } + public CorLibTypeSig Int16 => typeInt16; /// - public CorLibTypeSig UInt16 { - get { return typeUInt16; } - } + public CorLibTypeSig UInt16 => typeUInt16; /// - public CorLibTypeSig Int32 { - get { return typeInt32; } - } + public CorLibTypeSig Int32 => typeInt32; /// - public CorLibTypeSig UInt32 { - get { return typeUInt32; } - } + public CorLibTypeSig UInt32 => typeUInt32; /// - public CorLibTypeSig Int64 { - get { return typeInt64; } - } + public CorLibTypeSig Int64 => typeInt64; /// - public CorLibTypeSig UInt64 { - get { return typeUInt64; } - } + public CorLibTypeSig UInt64 => typeUInt64; /// - public CorLibTypeSig Single { - get { return typeSingle; } - } + public CorLibTypeSig Single => typeSingle; /// - public CorLibTypeSig Double { - get { return typeDouble; } - } + public CorLibTypeSig Double => typeDouble; /// - public CorLibTypeSig String { - get { return typeString; } - } + public CorLibTypeSig String => typeString; /// - public CorLibTypeSig TypedReference { - get { return typeTypedReference; } - } + public CorLibTypeSig TypedReference => typeTypedReference; /// - public CorLibTypeSig IntPtr { - get { return typeIntPtr; } - } + public CorLibTypeSig IntPtr => typeIntPtr; /// - public CorLibTypeSig UIntPtr { - get { return typeUIntPtr; } - } + public CorLibTypeSig UIntPtr => typeUIntPtr; /// - public CorLibTypeSig Object { - get { return typeObject; } - } + public CorLibTypeSig Object => typeObject; /// - public AssemblyRef AssemblyRef { - get { return corLibAssemblyRef; } - } + public AssemblyRef AssemblyRef => corLibAssemblyRef; /// /// Constructor @@ -141,9 +103,7 @@ public CorLibTypes(ModuleDef module, AssemblyRef corLibAssemblyRef) { Initialize(); } - AssemblyRef CreateCorLibAssemblyRef() { - return module.UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20()); - } + AssemblyRef CreateCorLibAssemblyRef() => module.UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20()); void Initialize() { bool isCorLib = module.Assembly.IsCorLib(); @@ -178,8 +138,6 @@ ITypeDefOrRef CreateCorLibTypeRef(bool isCorLib, string name) { } /// - public TypeRef GetTypeRef(string @namespace, string name) { - return module.UpdateRowId(new TypeRefUser(module, @namespace, name, corLibAssemblyRef)); - } + public TypeRef GetTypeRef(string @namespace, string name) => module.UpdateRowId(new TypeRefUser(module, @namespace, name, corLibAssemblyRef)); } } diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index c97b1abc2..cc065d21c 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -49,9 +49,7 @@ abstract class CpuArch { /// public abstract uint GetStubCodeOffset(StubType stubType); - public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { - return toCpuArch.TryGetValue(machine, out cpuArch); - } + public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) => toCpuArch.TryGetValue(machine, out cpuArch); /// /// Gets the RVA of the func field that the stub jumps to diff --git a/src/DotNet/CustomAttribute.cs b/src/DotNet/CustomAttribute.cs index f3bacf34e..c02a4f0fc 100644 --- a/src/DotNet/CustomAttribute.cs +++ b/src/DotNet/CustomAttribute.cs @@ -26,31 +26,24 @@ public sealed class CustomAttribute : ICustomAttribute { /// Gets/sets the custom attribute constructor /// public ICustomAttributeType Constructor { - get { return ctor; } - set { ctor = value; } + get => ctor; + set => ctor = value; } /// /// Gets the attribute type /// - public ITypeDefOrRef AttributeType { - get { - var cat = ctor; - return cat == null ? null : cat.DeclaringType; - } - } + public ITypeDefOrRef AttributeType => ctor?.DeclaringType; /// /// Gets the full name of the attribute type /// public string TypeFullName { get { - var mrCtor = ctor as MemberRef; - if (mrCtor != null) + if (ctor is MemberRef mrCtor) return mrCtor.GetDeclaringTypeFullName() ?? string.Empty; - var mdCtor = ctor as MethodDef; - if (mdCtor != null) { + if (ctor is MethodDef mdCtor) { var declType = mdCtor.DeclaringType; if (declType != null) return declType.FullName; @@ -63,44 +56,32 @@ public string TypeFullName { /// /// true if the raw custom attribute blob hasn't been parsed /// - public bool IsRawBlob { - get { return rawData != null; } - } + public bool IsRawBlob => rawData != null; /// /// Gets the raw custom attribute blob or null if the CA was successfully parsed. /// - public byte[] RawData { - get { return rawData; } - } + public byte[] RawData => rawData; /// /// Gets all constructor arguments /// - public ThreadSafe.IList ConstructorArguments { - get { return arguments; } - } + public ThreadSafe.IList ConstructorArguments => arguments; /// /// true if is not empty /// - public bool HasConstructorArguments { - get { return arguments.Count > 0; } - } + public bool HasConstructorArguments => arguments.Count > 0; /// /// Gets all named arguments (field and property values) /// - public ThreadSafe.IList NamedArguments { - get { return namedArguments; } - } + public ThreadSafe.IList NamedArguments => namedArguments; /// /// true if is not empty /// - public bool HasNamedArguments { - get { return namedArguments.Count > 0; } - } + public bool HasNamedArguments => namedArguments.Count > 0; /// /// Gets all s that are field arguments @@ -132,9 +113,7 @@ public IEnumerable Properties { /// Custom attribute constructor /// Raw custom attribute blob public CustomAttribute(ICustomAttributeType ctor, byte[] rawData) - : this(ctor, null, null, null) { - this.rawData = rawData; - } + : this(ctor, null, null, null) => this.rawData = rawData; /// /// Constructor @@ -205,36 +184,28 @@ internal CustomAttribute(ICustomAttributeType ctor, List arguments, /// /// Name of field /// A instance or null if not found - public CANamedArgument GetField(string name) { - return GetNamedArgument(name, true); - } + public CANamedArgument GetField(string name) => GetNamedArgument(name, true); /// /// Gets the field named /// /// Name of field /// A instance or null if not found - public CANamedArgument GetField(UTF8String name) { - return GetNamedArgument(name, true); - } + public CANamedArgument GetField(UTF8String name) => GetNamedArgument(name, true); /// /// Gets the property named /// /// Name of property /// A instance or null if not found - public CANamedArgument GetProperty(string name) { - return GetNamedArgument(name, false); - } + public CANamedArgument GetProperty(string name) => GetNamedArgument(name, false); /// /// Gets the property named /// /// Name of property /// A instance or null if not found - public CANamedArgument GetProperty(UTF8String name) { - return GetNamedArgument(name, false); - } + public CANamedArgument GetProperty(UTF8String name) => GetNamedArgument(name, false); /// /// Gets the property/field named @@ -294,9 +265,7 @@ public byte[] GetBlob() { byte[] blob; /// - public override string ToString() { - return TypeFullName; - } + public override string ToString() => TypeFullName; } /// @@ -310,16 +279,16 @@ public struct CAArgument : ICloneable { /// Gets/sets the argument type /// public TypeSig Type { - get { return type; } - set { type = value; } + get => type; + set => type = value; } /// /// Gets/sets the argument value /// public object Value { - get { return value; } - set { this.value = value; } + get => value; + set => this.value = value; } /// @@ -328,7 +297,7 @@ public object Value { /// Argument type public CAArgument(TypeSig type) { this.type = type; - this.value = null; + value = null; } /// @@ -341,9 +310,7 @@ public CAArgument(TypeSig type, object value) { this.value = value; } - object ICloneable.Clone() { - return Clone(); - } + object ICloneable.Clone() => Clone(); /// /// Clones this instance and any s and s @@ -354,8 +321,7 @@ public CAArgument Clone() { var value = this.value; if (value is CAArgument) value = ((CAArgument)value).Clone(); - else if (value is IList) { - var args = (IList)value; + else if (value is IList args) { var newArgs = ThreadSafeListCreator.Create(args.Count); foreach (var arg in args.GetSafeEnumerable()) newArgs.Add(arg.Clone()); @@ -365,10 +331,7 @@ public CAArgument Clone() { } /// - public override string ToString() { - object v = value; - return string.Format("{0} ({1})", v == null ? "null" : v, type); - } + public override string ToString() => $"{value ?? "null"} ({type})"; } /// @@ -384,56 +347,56 @@ public sealed class CANamedArgument : ICloneable { /// true if it's a field /// public bool IsField { - get { return isField; } - set { isField = value; } + get => isField; + set => isField = value; } /// /// true if it's a property /// public bool IsProperty { - get { return !isField; } - set { isField = !value; } + get => !isField; + set => isField = !value; } /// /// Gets/sets the field/property type /// public TypeSig Type { - get { return type; } - set { type = value; } + get => type; + set => type = value; } /// /// Gets/sets the property/field name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets/sets the argument /// public CAArgument Argument { - get { return argument; } - set { argument = value; } + get => argument; + set => argument = value; } /// /// Gets/sets the argument type /// public TypeSig ArgumentType { - get { return argument.Type; } - set { argument.Type = value; } + get => argument.Type; + set => argument.Type = value; } /// /// Gets/sets the argument value /// public object Value { - get { return argument.Value; } - set { argument.Value = value; } + get => argument.Value; + set => argument.Value = value; } /// @@ -446,9 +409,7 @@ public CANamedArgument() { /// Constructor /// /// true if field, false if property - public CANamedArgument(bool isField) { - this.isField = isField; - } + public CANamedArgument(bool isField) => this.isField = isField; /// /// Constructor @@ -486,22 +447,15 @@ public CANamedArgument(bool isField, TypeSig type, UTF8String name, CAArgument a this.argument = argument; } - object ICloneable.Clone() { - return Clone(); - } + object ICloneable.Clone() => Clone(); /// /// Clones this instance and any s referenced from this instance. /// /// - public CANamedArgument Clone() { - return new CANamedArgument(isField, type, name, argument.Clone()); - } + public CANamedArgument Clone() => new CANamedArgument(isField, type, name, argument.Clone()); /// - public override string ToString() { - object v = Value; - return string.Format("({0}) {1} {2} = {3} ({4})", isField ? "field" : "property", type, name, v == null ? "null" : v, ArgumentType); - } + public override string ToString() => $"({(isField ? "field" : "property")}) {type} {name} = {Value ?? "null"} ({ArgumentType})"; } } diff --git a/src/DotNet/CustomAttributeCollection.cs b/src/DotNet/CustomAttributeCollection.cs index a18c333a0..ba005d4e6 100644 --- a/src/DotNet/CustomAttributeCollection.cs +++ b/src/DotNet/CustomAttributeCollection.cs @@ -30,20 +30,17 @@ public CustomAttributeCollection(int length, object context, MFunc /// Full name of custom attribute type /// true if the custom attribute type is present, false otherwise - public bool IsDefined(string fullName) { - return Find(fullName) != null; - } + public bool IsDefined(string fullName) => Find(fullName) != null; /// /// Removes all custom attributes of a certain type /// /// Full name of custom attribute type that should be removed - public void RemoveAll(string fullName) { + public void RemoveAll(string fullName) => this.IterateAllReverse((tsList, index, value) => { if (value.TypeFullName == fullName) RemoveAt_NoLock(index); }); - } /// /// Finds a custom attribute @@ -76,9 +73,7 @@ public IEnumerable FindAll(string fullName) { /// /// Custom attribute type /// The first found or null if none found - public CustomAttribute Find(IType attrType) { - return Find(attrType, 0); - } + public CustomAttribute Find(IType attrType) => Find(attrType, 0); /// /// Finds a custom attribute @@ -100,9 +95,7 @@ public CustomAttribute Find(IType attrType, SigComparerOptions options) { /// /// Custom attribute type /// All s of the requested type - public IEnumerable FindAll(IType attrType) { - return FindAll(attrType, 0); - } + public IEnumerable FindAll(IType attrType) => FindAll(attrType, 0); /// /// Finds all custom attributes of a certain type diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 06abc6593..d9f4cd6c7 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -19,9 +19,7 @@ sealed class CAAssemblyRefFinder : IAssemblyRefFinder { /// Constructor /// /// The module to search first - public CAAssemblyRefFinder(ModuleDef module) { - this.module = module; - } + public CAAssemblyRefFinder(ModuleDef module) => this.module = module; /// public AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { @@ -104,9 +102,7 @@ public struct CustomAttributeReader : IDisposable { /// Custom attribute constructor /// Offset of custom attribute in the #Blob stream /// A new instance - public static CustomAttribute Read(ModuleDefMD readerModule, ICustomAttributeType ctor, uint offset) { - return Read(readerModule, ctor, offset, new GenericParamContext()); - } + public static CustomAttribute Read(ModuleDefMD readerModule, ICustomAttributeType ctor, uint offset) => Read(readerModule, ctor, offset, new GenericParamContext()); /// /// Reads a custom attribute @@ -132,9 +128,7 @@ public static CustomAttribute Read(ModuleDefMD readerModule, ICustomAttributeTyp } } - CustomAttribute CreateRaw(ICustomAttributeType ctor) { - return new CustomAttribute(ctor, GetRawBlob()); - } + CustomAttribute CreateRaw(ICustomAttributeType ctor) => new CustomAttribute(ctor, GetRawBlob()); /// /// Reads a custom attribute @@ -143,9 +137,7 @@ CustomAttribute CreateRaw(ICustomAttributeType ctor) { /// CA blob /// Custom attribute constructor /// A new instance - public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttributeType ctor) { - return Read(module, MemoryImageStream.Create(caBlob), ctor, new GenericParamContext()); - } + public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttributeType ctor) => Read(module, MemoryImageStream.Create(caBlob), ctor, new GenericParamContext()); /// /// Reads a custom attribute @@ -154,9 +146,7 @@ public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttri /// A stream positioned at the the first byte of the CA blob /// Custom attribute constructor /// A new instance - public static CustomAttribute Read(ModuleDef module, IBinaryReader stream, ICustomAttributeType ctor) { - return Read(module, stream, ctor, new GenericParamContext()); - } + public static CustomAttribute Read(ModuleDef module, IBinaryReader stream, ICustomAttributeType ctor) => Read(module, stream, ctor, new GenericParamContext()); /// /// Reads a custom attribute @@ -166,9 +156,7 @@ public static CustomAttribute Read(ModuleDef module, IBinaryReader stream, ICust /// Custom attribute constructor /// Generic parameter context /// A new instance - public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttributeType ctor, GenericParamContext gpContext) { - return Read(module, MemoryImageStream.Create(caBlob), ctor, gpContext); - } + public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttributeType ctor, GenericParamContext gpContext) => Read(module, MemoryImageStream.Create(caBlob), ctor, gpContext); /// /// Reads a custom attribute @@ -217,54 +205,45 @@ internal static List ReadNamedArguments(ModuleDef module, IBina } CustomAttributeReader(ModuleDefMD readerModule, uint offset, GenericParamContext gpContext) { - this.module = readerModule; - this.reader = readerModule.BlobStream.CreateStream(offset); - this.ownReader = true; - this.genericArguments = null; - this.recursionCounter = new RecursionCounter(); - this.verifyReadAllBytes = false; + module = readerModule; + reader = readerModule.BlobStream.CreateStream(offset); + ownReader = true; + genericArguments = null; + recursionCounter = new RecursionCounter(); + verifyReadAllBytes = false; this.gpContext = gpContext; } CustomAttributeReader(ModuleDef module, IBinaryReader reader, GenericParamContext gpContext) { this.module = module; this.reader = reader; - this.ownReader = false; - this.genericArguments = null; - this.recursionCounter = new RecursionCounter(); - this.verifyReadAllBytes = false; + ownReader = false; + genericArguments = null; + recursionCounter = new RecursionCounter(); + verifyReadAllBytes = false; this.gpContext = gpContext; } CustomAttributeReader(ModuleDef module, IBinaryReader reader, bool ownRerader, GenericParamContext gpContext) { this.module = module; this.reader = reader; - this.ownReader = ownRerader; - this.genericArguments = null; - this.recursionCounter = new RecursionCounter(); - this.verifyReadAllBytes = false; + ownReader = ownRerader; + genericArguments = null; + recursionCounter = new RecursionCounter(); + verifyReadAllBytes = false; this.gpContext = gpContext; } - byte[] GetRawBlob() { - return reader.ReadAllBytes(); - } + byte[] GetRawBlob() => reader.ReadAllBytes(); CustomAttribute Read(ICustomAttributeType ctor) { - var methodSig = ctor == null ? null : ctor.MethodSig; + var methodSig = ctor?.MethodSig; if (methodSig == null) throw new CABlobParserException("ctor is null or not a method"); - var mrCtor = ctor as MemberRef; - if (mrCtor != null) { - var owner = mrCtor.Class as TypeSpec; - if (owner != null) { - var gis = owner.TypeSig as GenericInstSig; - if (gis != null) { - genericArguments = new GenericArguments(); - genericArguments.PushTypeArgs(gis.GenericArguments); - } - } + if (ctor is MemberRef mrCtor && mrCtor.Class is TypeSpec owner && owner.TypeSig is GenericInstSig gis) { + genericArguments = new GenericArguments(); + genericArguments.PushTypeArgs(gis.GenericArguments); } bool isEmpty = methodSig.Params.Count == 0 && reader.Position == reader.Length; @@ -290,8 +269,7 @@ CustomAttribute Read(ICustomAttributeType ctor) { static IBinaryReader CloneBlobReader(IBinaryReader reader) { if (reader == null) return null; - var imgStream = reader as IImageStream; - if (imgStream != null) + if (reader is IImageStream imgStream) return imgStream.Clone(); return MemoryImageStream.Create(reader.ReadAllBytes()); } @@ -306,9 +284,7 @@ List ReadNamedArguments(int numNamedArgs) { return namedArgs; } - TypeSig FixTypeSig(TypeSig type) { - return SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); - } + TypeSig FixTypeSig(TypeSig type) => SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); TypeSig SubstituteGenericParameter(TypeSig type) { if (genericArguments == null) @@ -323,8 +299,7 @@ CAArgument ReadFixedArg(TypeSig argType) { throw new CABlobParserException("null argType"); CAArgument result; - var arrayType = argType as SZArraySig; - if (arrayType != null) + if (argType is SZArraySig arrayType) result = ReadArrayArgument(arrayType); else result = ReadElem(argType); @@ -336,8 +311,7 @@ CAArgument ReadFixedArg(TypeSig argType) { CAArgument ReadElem(TypeSig argType) { if (argType == null) throw new CABlobParserException("null argType"); - TypeSig realArgType; - var value = ReadValue((SerializationType)argType.ElementType, argType, out realArgType); + var value = ReadValue((SerializationType)argType.ElementType, argType, out var realArgType); if (realArgType == null) throw new CABlobParserException("Invalid arg type"); @@ -435,10 +409,8 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy var arraySig = realArgType as SZArraySig; if (arraySig != null) result = ReadArrayArgument(arraySig); - else { - TypeSig tmpType; - result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out tmpType); - } + else + result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out var tmpType); break; // It's ET.Class if it's eg. a ctor System.Type arg type @@ -486,8 +458,7 @@ object ReadEnumValue(TypeSig underlyingType) { if (underlyingType != null) { if (underlyingType.ElementType < ElementType.Boolean || underlyingType.ElementType > ElementType.U8) throw new CABlobParserException("Invalid enum underlying type"); - TypeSig realArgType; - return ReadValue((SerializationType)underlyingType.ElementType, underlyingType, out realArgType); + return ReadValue((SerializationType)underlyingType.ElementType, underlyingType, out var realArgType); } // We couldn't resolve the type ref. It should be an enum, but we don't know for sure. @@ -534,8 +505,7 @@ static TypeSig GetEnumUnderlyingType(TypeSig type) { /// A or null if we couldn't resolve the /// or if is a type spec static TypeDef GetTypeDef(TypeSig type) { - var tdr = type as TypeDefOrRefSig; - if (tdr != null) { + if (type is TypeDefOrRefSig tdr) { var td = tdr.TypeDef; if (td != null) return td; @@ -577,7 +547,7 @@ CANamedArgument ReadNamedArgument() { default: throw new CABlobParserException("Named argument is not a field/property"); } - TypeSig fieldPropType = ReadFieldOrPropType(); + var fieldPropType = ReadFieldOrPropType(); var name = ReadUTF8String(); var argument = ReadFixedArg(fieldPropType); @@ -616,8 +586,7 @@ UTF8String ReadUTF8String() { if (reader.ReadByte() == 0xFF) return null; reader.Position--; - uint len; - if (!reader.ReadCompressedUInt32(out len)) + if (!reader.ReadCompressedUInt32(out uint len)) throw new CABlobParserException("Could not read compressed UInt32"); if (len == 0) return UTF8String.Empty; diff --git a/src/DotNet/DeclSecurity.cs b/src/DotNet/DeclSecurity.cs index 4e75092d7..9003be31d 100644 --- a/src/DotNet/DeclSecurity.cs +++ b/src/DotNet/DeclSecurity.cs @@ -26,27 +26,23 @@ public abstract class DeclSecurity : IHasCustomAttribute, IHasCustomDebugInforma protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.DeclSecurity, rid); } - } + public MDToken MDToken => new MDToken(Table.DeclSecurity, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 8; } - } + public int HasCustomAttributeTag => 8; /// /// From column DeclSecurity.Action /// public SecurityAction Action { - get { return action; } - set { action = value; } + get => action; + set => action = value; } /// protected SecurityAction action; @@ -64,9 +60,8 @@ public ThreadSafe.IList SecurityAttributes { /// protected ThreadSafe.IList securityAttributes; /// Initializes - protected virtual void InitializeSecurityAttributes() { + protected virtual void InitializeSecurityAttributes() => Interlocked.CompareExchange(ref securityAttributes, ThreadSafeListCreator.Create(), null); - } /// /// Gets all custom attributes @@ -81,24 +76,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 8; } - } + public int HasCustomDebugInformationTag => 8; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -113,16 +101,13 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// true if is not empty /// - public bool HasSecurityAttributes { - get { return SecurityAttributes.Count > 0; } - } + public bool HasSecurityAttributes => SecurityAttributes.Count > 0; /// /// Gets the blob data or null if there's none @@ -134,9 +119,7 @@ public bool HasSecurityAttributes { /// Returns the .NET 1.x XML string or null if it's not a .NET 1.x format /// /// - public string GetNet1xXmlString() { - return GetNet1xXmlStringInternal(SecurityAttributes); - } + public string GetNet1xXmlString() => GetNet1xXmlStringInternal(SecurityAttributes); internal static string GetNet1xXmlStringInternal(IList secAttrs) { if (secAttrs == null || secAttrs.Count != 1) @@ -157,8 +140,7 @@ internal static string GetNet1xXmlStringInternal(IList secAtt var utf8 = arg.Value as UTF8String; if ((object)utf8 != null) return utf8; - var s = arg.Value as string; - if (s != null) + if (arg.Value is string s) return s; return null; } @@ -181,13 +163,11 @@ public DeclSecurityUser() { /// The security attributes (now owned by this) public DeclSecurityUser(SecurityAction action, IList securityAttrs) { this.action = action; - this.securityAttributes = ThreadSafeListCreator.MakeThreadSafe(securityAttrs); + securityAttributes = ThreadSafeListCreator.MakeThreadSafe(securityAttrs); } /// - public override byte[] GetBlob() { - return null; - } + public override byte[] GetBlob() => null; } /// @@ -201,9 +181,7 @@ sealed class DeclSecurityMD : DeclSecurity, IMDTokenProviderMD { readonly uint permissionSet; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeSecurityAttributes() { @@ -239,17 +217,15 @@ public DeclSecurityMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.DeclSecurityTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("DeclSecurity rid {0} does not exist", rid)); + throw new BadImageFormatException($"DeclSecurity rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - this.permissionSet = readerModule.TablesStream.ReadDeclSecurityRow(origRid, out this.action); + permissionSet = readerModule.TablesStream.ReadDeclSecurityRow(origRid, out action); } /// - public override byte[] GetBlob() { - return readerModule.BlobStream.Read(permissionSet); - } + public override byte[] GetBlob() => readerModule.BlobStream.Read(permissionSet); } } diff --git a/src/DotNet/DeclSecurityReader.cs b/src/DotNet/DeclSecurityReader.cs index a62ac6b7c..a829219d6 100644 --- a/src/DotNet/DeclSecurityReader.cs +++ b/src/DotNet/DeclSecurityReader.cs @@ -15,7 +15,7 @@ namespace dnlib.DotNet { /// /// Reads DeclSecurity blobs /// - public struct DeclSecurityReader : IDisposable { + public readonly struct DeclSecurityReader : IDisposable { readonly IBinaryReader reader; readonly ModuleDef module; readonly GenericParamContext gpContext; @@ -26,9 +26,7 @@ public struct DeclSecurityReader : IDisposable { /// Module that will own the returned list /// #Blob offset of DeclSecurity signature /// A list of s - public static ThreadSafe.IList Read(ModuleDefMD module, uint sig) { - return Read(module, module.BlobStream.CreateStream(sig), new GenericParamContext()); - } + public static ThreadSafe.IList Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateStream(sig), new GenericParamContext()); /// /// Reads a DeclSecurity blob @@ -37,9 +35,7 @@ public static ThreadSafe.IList Read(ModuleDefMD module, uint /// #Blob offset of DeclSecurity signature /// Generic parameter context /// A list of s - public static ThreadSafe.IList Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) { - return Read(module, module.BlobStream.CreateStream(sig), gpContext); - } + public static ThreadSafe.IList Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateStream(sig), gpContext); /// /// Reads a DeclSecurity blob @@ -47,9 +43,7 @@ public static ThreadSafe.IList Read(ModuleDefMD module, uint /// Module that will own the returned list /// DeclSecurity blob /// A list of s - public static ThreadSafe.IList Read(ModuleDef module, byte[] blob) { - return Read(module, MemoryImageStream.Create(blob), new GenericParamContext()); - } + public static ThreadSafe.IList Read(ModuleDef module, byte[] blob) => Read(module, MemoryImageStream.Create(blob), new GenericParamContext()); /// /// Reads a DeclSecurity blob @@ -58,9 +52,7 @@ public static ThreadSafe.IList Read(ModuleDef module, byte[] /// DeclSecurity blob /// Generic parameter context/// /// A list of s - public static ThreadSafe.IList Read(ModuleDef module, byte[] blob, GenericParamContext gpContext) { - return Read(module, MemoryImageStream.Create(blob), gpContext); - } + public static ThreadSafe.IList Read(ModuleDef module, byte[] blob, GenericParamContext gpContext) => Read(module, MemoryImageStream.Create(blob), gpContext); /// /// Reads a DeclSecurity blob @@ -68,9 +60,7 @@ public static ThreadSafe.IList Read(ModuleDef module, byte[] /// Module that will own the returned list /// DeclSecurity stream that will be owned by us /// A list of s - public static ThreadSafe.IList Read(ModuleDef module, IBinaryReader signature) { - return Read(module, signature, new GenericParamContext()); - } + public static ThreadSafe.IList Read(ModuleDef module, IBinaryReader signature) => Read(module, signature, new GenericParamContext()); /// /// Reads a DeclSecurity blob diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 552b15270..25a186a46 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -54,9 +54,7 @@ class ReflectionFieldInfo { readonly string fieldName1; readonly string fieldName2; - public ReflectionFieldInfo(string fieldName) { - this.fieldName1 = fieldName; - } + public ReflectionFieldInfo(string fieldName) => fieldName1 = fieldName; public ReflectionFieldInfo(string fieldName1, string fieldName2) { this.fieldName1 = fieldName1; @@ -67,7 +65,7 @@ public object Read(object instance) { if (fieldInfo == null) InitializeField(instance.GetType()); if (fieldInfo == null) - throw new Exception(string.Format("Couldn't find field '{0}' or '{1}'", fieldName1, fieldName2)); + throw new Exception($"Couldn't find field '{fieldName1}' or '{fieldName2}'"); return fieldInfo.GetValue(instance); } @@ -109,15 +107,14 @@ public DynamicMethodBodyReader(ModuleDef module, object obj) /// Generic parameter context public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext gpContext) { this.module = module; - this.importer = new Importer(module, ImporterOptions.TryToUseDefs, gpContext); + importer = new Importer(module, ImporterOptions.TryToUseDefs, gpContext); this.gpContext = gpContext; - this.methodName = null; + methodName = null; if (obj == null) - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); - var del = obj as Delegate; - if (del != null) { + if (obj is Delegate del) { obj = del.Method; if (obj == null) throw new Exception("Delegate.Method == null"); @@ -162,9 +159,9 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext ehHeader = rslvExceptionHeaderFieldInfo.Read(obj) as byte[]; UpdateLocals(rslvLocalsFieldInfo.Read(obj) as byte[]); - this.reader = MemoryImageStream.Create(code); - this.method = CreateMethodDef(delMethod); - this.parameters = this.method.Parameters; + reader = MemoryImageStream.Create(code); + method = CreateMethodDef(delMethod); + parameters = method.Parameters; } class ExceptionInfo { @@ -234,8 +231,7 @@ MethodDef CreateMethodDef(SR.MethodBase delMethod) { } TypeSig GetReturnType(SR.MethodBase mb) { - var mi = mb as SR.MethodInfo; - if (mi != null) + if (mb is SR.MethodInfo mi) return importer.ImportAsTypeSig(mi.ReturnType); return module.CorLibTypes.Void; } @@ -353,34 +349,22 @@ public MethodDef GetMethod() { } /// - protected override IField ReadInlineField(Instruction instr) { - return ReadToken(reader.ReadUInt32()) as IField; - } + protected override IField ReadInlineField(Instruction instr) => ReadToken(reader.ReadUInt32()) as IField; /// - protected override IMethod ReadInlineMethod(Instruction instr) { - return ReadToken(reader.ReadUInt32()) as IMethod; - } + protected override IMethod ReadInlineMethod(Instruction instr) => ReadToken(reader.ReadUInt32()) as IMethod; /// - protected override MethodSig ReadInlineSig(Instruction instr) { - return ReadToken(reader.ReadUInt32()) as MethodSig; - } + protected override MethodSig ReadInlineSig(Instruction instr) => ReadToken(reader.ReadUInt32()) as MethodSig; /// - protected override string ReadInlineString(Instruction instr) { - return ReadToken(reader.ReadUInt32()) as string ?? string.Empty; - } + protected override string ReadInlineString(Instruction instr) => ReadToken(reader.ReadUInt32()) as string ?? string.Empty; /// - protected override ITokenOperand ReadInlineTok(Instruction instr) { - return ReadToken(reader.ReadUInt32()) as ITokenOperand; - } + protected override ITokenOperand ReadInlineTok(Instruction instr) => ReadToken(reader.ReadUInt32()) as ITokenOperand; /// - protected override ITypeDefOrRef ReadInlineType(Instruction instr) { - return ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; - } + protected override ITypeDefOrRef ReadInlineType(Instruction instr) => ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; object ReadToken(uint token) { uint rid = token & 0x00FFFFFF; @@ -427,8 +411,7 @@ IMethod ImportMethod(uint rid) { obj = method; } - var dm = obj as DynamicMethod; - if (dm != null) + if (obj is DynamicMethod dm) throw new Exception("DynamicMethod calls another DynamicMethod"); return null; @@ -488,8 +471,7 @@ object Resolve(uint index) { } ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.TypeDefOrRef.Decode(codedToken, out token)) + if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -501,8 +483,6 @@ ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, Generi return null; } - TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) { - return importer.ImportAsTypeSig(MethodTableToTypeConverter.Convert(address)); - } + TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) => importer.ImportAsTypeSig(MethodTableToTypeConverter.Convert(address)); } } diff --git a/src/DotNet/Emit/ExceptionHandler.cs b/src/DotNet/Emit/ExceptionHandler.cs index b4ecb1cd9..d0d4ceff8 100644 --- a/src/DotNet/Emit/ExceptionHandler.cs +++ b/src/DotNet/Emit/ExceptionHandler.cs @@ -53,8 +53,6 @@ public ExceptionHandler() { /// Constructor /// /// Exception clause type - public ExceptionHandler(ExceptionHandlerType handlerType) { - this.HandlerType = handlerType; - } + public ExceptionHandler(ExceptionHandlerType handlerType) => HandlerType = handlerType; } } diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index ba8829cd4..4e3fd37b1 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -40,9 +40,7 @@ public Instruction() { /// Constructor /// /// Opcode - public Instruction(OpCode opCode) { - this.OpCode = opCode; - } + public Instruction(OpCode opCode) => OpCode = opCode; /// /// Constructor @@ -50,8 +48,8 @@ public Instruction(OpCode opCode) { /// Opcode /// The operand public Instruction(OpCode opCode, object operand) { - this.OpCode = opCode; - this.Operand = operand; + OpCode = opCode; + Operand = operand; } /// @@ -61,7 +59,7 @@ public Instruction(OpCode opCode, object operand) { /// A new instance public static Instruction Create(OpCode opCode) { if (opCode.OperandType != OperandType.InlineNone) - throw new ArgumentException("Must be a no-operand opcode", "opCode"); + throw new ArgumentException("Must be a no-operand opcode", nameof(opCode)); return new Instruction(opCode); } @@ -73,7 +71,7 @@ public static Instruction Create(OpCode opCode) { /// A new instance public static Instruction Create(OpCode opCode, byte value) { if (opCode.Code != Code.Unaligned) - throw new ArgumentException("Opcode does not have a byte operand", "opCode"); + throw new ArgumentException("Opcode does not have a byte operand", nameof(opCode)); return new Instruction(opCode, value); } @@ -85,7 +83,7 @@ public static Instruction Create(OpCode opCode, byte value) { /// A new instance public static Instruction Create(OpCode opCode, sbyte value) { if (opCode.Code != Code.Ldc_I4_S) - throw new ArgumentException("Opcode does not have a sbyte operand", "opCode"); + throw new ArgumentException("Opcode does not have a sbyte operand", nameof(opCode)); return new Instruction(opCode, value); } @@ -97,7 +95,7 @@ public static Instruction Create(OpCode opCode, sbyte value) { /// A new instance public static Instruction Create(OpCode opCode, int value) { if (opCode.OperandType != OperandType.InlineI) - throw new ArgumentException("Opcode does not have an int32 operand", "opCode"); + throw new ArgumentException("Opcode does not have an int32 operand", nameof(opCode)); return new Instruction(opCode, value); } @@ -109,7 +107,7 @@ public static Instruction Create(OpCode opCode, int value) { /// A new instance public static Instruction Create(OpCode opCode, long value) { if (opCode.OperandType != OperandType.InlineI8) - throw new ArgumentException("Opcode does not have an int64 operand", "opCode"); + throw new ArgumentException("Opcode does not have an int64 operand", nameof(opCode)); return new Instruction(opCode, value); } @@ -121,7 +119,7 @@ public static Instruction Create(OpCode opCode, long value) { /// A new instance public static Instruction Create(OpCode opCode, float value) { if (opCode.OperandType != OperandType.ShortInlineR) - throw new ArgumentException("Opcode does not have a real4 operand", "opCode"); + throw new ArgumentException("Opcode does not have a real4 operand", nameof(opCode)); return new Instruction(opCode, value); } @@ -133,7 +131,7 @@ public static Instruction Create(OpCode opCode, float value) { /// A new instance public static Instruction Create(OpCode opCode, double value) { if (opCode.OperandType != OperandType.InlineR) - throw new ArgumentException("Opcode does not have a real8 operand", "opCode"); + throw new ArgumentException("Opcode does not have a real8 operand", nameof(opCode)); return new Instruction(opCode, value); } @@ -145,7 +143,7 @@ public static Instruction Create(OpCode opCode, double value) { /// A new instance public static Instruction Create(OpCode opCode, string s) { if (opCode.OperandType != OperandType.InlineString) - throw new ArgumentException("Opcode does not have a string operand", "opCode"); + throw new ArgumentException("Opcode does not have a string operand", nameof(opCode)); return new Instruction(opCode, s); } @@ -157,7 +155,7 @@ public static Instruction Create(OpCode opCode, string s) { /// A new instance public static Instruction Create(OpCode opCode, Instruction target) { if (opCode.OperandType != OperandType.ShortInlineBrTarget && opCode.OperandType != OperandType.InlineBrTarget) - throw new ArgumentException("Opcode does not have an instruction operand", "opCode"); + throw new ArgumentException("Opcode does not have an instruction operand", nameof(opCode)); return new Instruction(opCode, target); } @@ -169,7 +167,7 @@ public static Instruction Create(OpCode opCode, Instruction target) { /// A new instance public static Instruction Create(OpCode opCode, IList targets) { if (opCode.OperandType != OperandType.InlineSwitch) - throw new ArgumentException("Opcode does not have a targets array operand", "opCode"); + throw new ArgumentException("Opcode does not have a targets array operand", nameof(opCode)); return new Instruction(opCode, ThreadSafeListCreator.MakeThreadSafe(targets)); } @@ -181,7 +179,7 @@ public static Instruction Create(OpCode opCode, IList targets) { /// A new instance public static Instruction Create(OpCode opCode, ITypeDefOrRef type) { if (opCode.OperandType != OperandType.InlineType && opCode.OperandType != OperandType.InlineTok) - throw new ArgumentException("Opcode does not have a type operand", "opCode"); + throw new ArgumentException("Opcode does not have a type operand", nameof(opCode)); return new Instruction(opCode, type); } @@ -191,9 +189,7 @@ public static Instruction Create(OpCode opCode, ITypeDefOrRef type) { /// The opcode /// The type /// A new instance - public static Instruction Create(OpCode opCode, CorLibTypeSig type) { - return Create(opCode, type.TypeDefOrRef); - } + public static Instruction Create(OpCode opCode, CorLibTypeSig type) => Create(opCode, type.TypeDefOrRef); /// /// Creates a new instruction with a method/field operand @@ -203,7 +199,7 @@ public static Instruction Create(OpCode opCode, CorLibTypeSig type) { /// A new instance public static Instruction Create(OpCode opCode, MemberRef mr) { if (opCode.OperandType != OperandType.InlineField && opCode.OperandType != OperandType.InlineMethod && opCode.OperandType != OperandType.InlineTok) - throw new ArgumentException("Opcode does not have a field operand", "opCode"); + throw new ArgumentException("Opcode does not have a field operand", nameof(opCode)); return new Instruction(opCode, mr); } @@ -215,7 +211,7 @@ public static Instruction Create(OpCode opCode, MemberRef mr) { /// A new instance public static Instruction Create(OpCode opCode, IField field) { if (opCode.OperandType != OperandType.InlineField && opCode.OperandType != OperandType.InlineTok) - throw new ArgumentException("Opcode does not have a field operand", "opCode"); + throw new ArgumentException("Opcode does not have a field operand", nameof(opCode)); return new Instruction(opCode, field); } @@ -227,7 +223,7 @@ public static Instruction Create(OpCode opCode, IField field) { /// A new instance public static Instruction Create(OpCode opCode, IMethod method) { if (opCode.OperandType != OperandType.InlineMethod && opCode.OperandType != OperandType.InlineTok) - throw new ArgumentException("Opcode does not have a method operand", "opCode"); + throw new ArgumentException("Opcode does not have a method operand", nameof(opCode)); return new Instruction(opCode, method); } @@ -239,7 +235,7 @@ public static Instruction Create(OpCode opCode, IMethod method) { /// A new instance public static Instruction Create(OpCode opCode, ITokenOperand token) { if (opCode.OperandType != OperandType.InlineTok) - throw new ArgumentException("Opcode does not have a token operand", "opCode"); + throw new ArgumentException("Opcode does not have a token operand", nameof(opCode)); return new Instruction(opCode, token); } @@ -251,7 +247,7 @@ public static Instruction Create(OpCode opCode, ITokenOperand token) { /// A new instance public static Instruction Create(OpCode opCode, MethodSig methodSig) { if (opCode.OperandType != OperandType.InlineSig) - throw new ArgumentException("Opcode does not have a method sig operand", "opCode"); + throw new ArgumentException("Opcode does not have a method sig operand", nameof(opCode)); return new Instruction(opCode, methodSig); } @@ -263,7 +259,7 @@ public static Instruction Create(OpCode opCode, MethodSig methodSig) { /// A new instance public static Instruction Create(OpCode opCode, Parameter parameter) { if (opCode.OperandType != OperandType.ShortInlineVar && opCode.OperandType != OperandType.InlineVar) - throw new ArgumentException("Opcode does not have a method parameter operand", "opCode"); + throw new ArgumentException("Opcode does not have a method parameter operand", nameof(opCode)); return new Instruction(opCode, parameter); } @@ -275,7 +271,7 @@ public static Instruction Create(OpCode opCode, Parameter parameter) { /// A new instance public static Instruction Create(OpCode opCode, Local local) { if (opCode.OperandType != OperandType.ShortInlineVar && opCode.OperandType != OperandType.InlineVar) - throw new ArgumentException("Opcode does not have a method local operand", "opCode"); + throw new ArgumentException("Opcode does not have a method local operand", nameof(opCode)); return new Instruction(opCode, local); } @@ -343,17 +339,13 @@ public int GetSize() { } } - static bool IsSystemVoid(TypeSig type) { - return type.RemovePinnedAndModifiers().GetElementType() == ElementType.Void; - } + static bool IsSystemVoid(TypeSig type) => type.RemovePinnedAndModifiers().GetElementType() == ElementType.Void; /// /// Updates with the new stack size /// /// Current stack size - public void UpdateStack(ref int stack) { - UpdateStack(ref stack, false); - } + public void UpdateStack(ref int stack) => UpdateStack(ref stack, false); /// /// Updates with the new stack size @@ -362,8 +354,7 @@ public void UpdateStack(ref int stack) { /// true if the method has a return value, /// false otherwise public void UpdateStack(ref int stack, bool methodHasReturnValue) { - int pushes, pops; - CalculateStackUsage(methodHasReturnValue, out pushes, out pops); + CalculateStackUsage(methodHasReturnValue, out int pushes, out int pops); if (pops == -1) stack = 0; else @@ -376,9 +367,7 @@ public void UpdateStack(ref int stack, bool methodHasReturnValue) { /// Updated with number of stack pushes /// Updated with number of stack pops or -1 if the stack should /// be cleared. - public void CalculateStackUsage(out int pushes, out int pops) { - CalculateStackUsage(false, out pushes, out pops); - } + public void CalculateStackUsage(out int pushes, out int pops) => CalculateStackUsage(false, out pushes, out pops); /// /// Calculates stack usage @@ -405,8 +394,7 @@ void CalculateStackUsageCall(OpCode opCode, out int pushes, out int pops) { MethodSig sig; var op = Operand; - var method = op as IMethod; - if (method != null) + if (op is IMethod method) sig = method.MethodSig; else sig = op as MethodSig; // calli instruction @@ -504,30 +492,22 @@ void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int push /// /// Checks whether it's one of the leave instructions /// - public bool IsLeave() { - return OpCode == OpCodes.Leave || OpCode == OpCodes.Leave_S; - } + public bool IsLeave() => OpCode == OpCodes.Leave || OpCode == OpCodes.Leave_S; /// /// Checks whether it's one of the br instructions /// - public bool IsBr() { - return OpCode == OpCodes.Br || OpCode == OpCodes.Br_S; - } + public bool IsBr() => OpCode == OpCodes.Br || OpCode == OpCodes.Br_S; /// /// Checks whether it's one of the brfalse instructions /// - public bool IsBrfalse() { - return OpCode == OpCodes.Brfalse || OpCode == OpCodes.Brfalse_S; - } + public bool IsBrfalse() => OpCode == OpCodes.Brfalse || OpCode == OpCodes.Brfalse_S; /// /// Checks whether it's one of the brtrue instructions /// - public bool IsBrtrue() { - return OpCode == OpCodes.Brtrue || OpCode == OpCodes.Brtrue_S; - } + public bool IsBrtrue() => OpCode == OpCodes.Brtrue || OpCode == OpCodes.Brtrue_S; /// /// Checks whether it's one of the conditional branch instructions (bcc, brtrue, brfalse) @@ -609,7 +589,7 @@ public int GetLdcI4Value() { case Code.Ldc_I4_S: return (sbyte)Operand; case Code.Ldc_I4: return (int)Operand; default: - throw new InvalidOperationException(string.Format("Not a ldc.i4 instruction: {0}", this)); + throw new InvalidOperationException($"Not a ldc.i4 instruction: {this}"); } } @@ -748,9 +728,7 @@ public int GetParameterIndex() { /// /// All parameters /// A parameter or null if it doesn't exist - public Parameter GetParameter(IList parameters) { - return parameters.Get(GetParameterIndex(), null); - } + public Parameter GetParameter(IList parameters) => parameters.Get(GetParameterIndex(), null); /// /// Returns an argument type @@ -773,19 +751,16 @@ public TypeSig GetArgumentType(MethodSig methodSig, ITypeDefOrRef declaringType) /// Clone this instance. The and fields /// are shared by this instance and the created instance. /// - public Instruction Clone() { - return new Instruction { + public Instruction Clone() => + new Instruction { Offset = Offset, OpCode = OpCode, Operand = Operand, SequencePoint = SequencePoint, }; - } /// - public override string ToString() { - return InstructionPrinter.ToString(this); - } + public override string ToString() => InstructionPrinter.ToString(this); } static partial class Extensions { @@ -794,35 +769,27 @@ static partial class Extensions { /// /// this /// - public static OpCode GetOpCode(this Instruction self) { - return self == null ? OpCodes.UNKNOWN1 : self.OpCode; - } + public static OpCode GetOpCode(this Instruction self) => self?.OpCode ?? OpCodes.UNKNOWN1; /// /// Gets the operand or null if is null /// /// this /// - public static object GetOperand(this Instruction self) { - return self == null ? null : self.Operand; - } + public static object GetOperand(this Instruction self) => self?.Operand; /// /// Gets the offset or 0 if is null /// /// this /// - public static uint GetOffset(this Instruction self) { - return self == null ? 0 : self.Offset; - } + public static uint GetOffset(this Instruction self) => self?.Offset ?? 0; /// /// Gets the sequence point or null if is null /// /// this /// - public static dnlib.DotNet.Pdb.SequencePoint GetSequencePoint(this Instruction self) { - return self == null ? null : self.SequencePoint; - } + public static dnlib.DotNet.Pdb.SequencePoint GetSequencePoint(this Instruction self) => self?.SequencePoint; } } diff --git a/src/DotNet/Emit/InstructionPrinter.cs b/src/DotNet/Emit/InstructionPrinter.cs index 00163a1fc..4a477f83b 100644 --- a/src/DotNet/Emit/InstructionPrinter.cs +++ b/src/DotNet/Emit/InstructionPrinter.cs @@ -20,7 +20,7 @@ public static string ToString(Instruction instr) { var sb = new StringBuilder(); - sb.Append(string.Format("IL_{0:X4}: ", instr.Offset)); + sb.Append($"IL_{instr.Offset:X4}: "); sb.Append(instr.OpCode.Name); AddOperandString(sb, instr, " "); @@ -43,9 +43,7 @@ public static string GetOperandString(Instruction instr) { /// /// Place result here /// The instruction - public static void AddOperandString(StringBuilder sb, Instruction instr) { - AddOperandString(sb, instr, string.Empty); - } + public static void AddOperandString(StringBuilder sb, Instruction instr) => AddOperandString(sb, instr, string.Empty); /// /// Add an instruction's operand to @@ -81,7 +79,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string case OperandType.InlineR: case OperandType.ShortInlineI: case OperandType.ShortInlineR: - sb.Append(string.Format("{0}{1}", extra, op)); + sb.Append($"{extra}{op}"); break; case OperandType.InlineSig: @@ -129,7 +127,7 @@ static void AddInstructionTarget(StringBuilder sb, Instruction targetInstr) { if (targetInstr == null) sb.Append("null"); else - sb.Append(string.Format("IL_{0:X4}", targetInstr.Offset)); + sb.Append($"IL_{targetInstr.Offset:X4}"); } static void EscapeString(StringBuilder sb, string s, bool addQuotes) { @@ -152,7 +150,7 @@ static void EscapeString(StringBuilder sb, string s, bool addQuotes) { case '\t': sb.Append(@"\t"); break; case '\v': sb.Append(@"\v"); break; default: - sb.Append(string.Format(@"\u{0:X4}", (int)c)); + sb.Append($@"\u{(int)c:X4}"); break; } } diff --git a/src/DotNet/Emit/LocalList.cs b/src/DotNet/Emit/LocalList.cs index e6641ba46..d48e9285c 100644 --- a/src/DotNet/Emit/LocalList.cs +++ b/src/DotNet/Emit/LocalList.cs @@ -23,32 +23,26 @@ public sealed class LocalList : IListListener, ThreadSafe.IList { /// /// Gets the number of locals /// - public int Count { - get { return locals.Count; } - } + public int Count => locals.Count; /// /// Gets the list of locals /// - public ThreadSafe.IList Locals { - get { return locals; } - } + public ThreadSafe.IList Locals => locals; /// /// Gets the N'th local /// /// The local index public Local this[int index] { - get { return locals[index]; } - set { locals[index] = value; } + get => locals[index]; + set => locals[index] = value; } /// /// Default constructor /// - public LocalList() { - this.locals = new LazyList(this); - } + public LocalList() => locals = new LazyList(this); /// /// Constructor @@ -75,14 +69,10 @@ void IListListener.OnLazyAdd(int index, ref Local value) { } /// - void IListListener.OnAdd(int index, Local value) { - value.Index = index; - } + void IListListener.OnAdd(int index, Local value) => value.Index = index; /// - void IListListener.OnRemove(int index, Local value) { - value.Index = -1; - } + void IListListener.OnRemove(int index, Local value) => value.Index = -1; /// void IListListener.OnResize(int index) { @@ -97,128 +87,79 @@ void IListListener.OnClear() { } /// - public int IndexOf(Local item) { - return locals.IndexOf(item); - } + public int IndexOf(Local item) => locals.IndexOf(item); /// - public void Insert(int index, Local item) { - locals.Insert(index, item); - } + public void Insert(int index, Local item) => locals.Insert(index, item); /// - public void RemoveAt(int index) { - locals.RemoveAt(index); - } + public void RemoveAt(int index) => locals.RemoveAt(index); - void ICollection.Add(Local item) { - locals.Add(item); - } + void ICollection.Add(Local item) => locals.Add(item); /// - public void Clear() { - locals.Clear(); - } + public void Clear() => locals.Clear(); /// - public bool Contains(Local item) { - return locals.Contains(item); - } + public bool Contains(Local item) => locals.Contains(item); /// - public void CopyTo(Local[] array, int arrayIndex) { - locals.CopyTo(array, arrayIndex); - } + public void CopyTo(Local[] array, int arrayIndex) => locals.CopyTo(array, arrayIndex); /// - public bool IsReadOnly { - get { return false; } - } + public bool IsReadOnly => false; /// - public bool Remove(Local item) { - return locals.Remove(item); - } + public bool Remove(Local item) => locals.Remove(item); /// - public IEnumerator GetEnumerator() { - return locals.GetEnumerator(); - } + public IEnumerator GetEnumerator() => locals.GetEnumerator(); - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return ((IEnumerable)this).GetEnumerator(); - } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => ((IEnumerable)this).GetEnumerator(); #if THREAD_SAFE /// - public int IndexOf_NoLock(Local item) { - return locals.IndexOf_NoLock(item); - } + public int IndexOf_NoLock(Local item) => locals.IndexOf_NoLock(item); /// - public void Insert_NoLock(int index, Local item) { - locals.Insert_NoLock(index, item); - } + public void Insert_NoLock(int index, Local item) => locals.Insert_NoLock(index, item); /// - public void RemoveAt_NoLock(int index) { - locals.RemoveAt_NoLock(index); - } + public void RemoveAt_NoLock(int index) => locals.RemoveAt_NoLock(index); /// - public Local Get_NoLock(int index) { - return locals.Get_NoLock(index); - } + public Local Get_NoLock(int index) => locals.Get_NoLock(index); /// - public void Set_NoLock(int index, Local value) { - locals.Set_NoLock(index, value); - } + public void Set_NoLock(int index, Local value) => locals.Set_NoLock(index, value); /// - public void Add_NoLock(Local item) { - locals.Add_NoLock(item); - } + public void Add_NoLock(Local item) => locals.Add_NoLock(item); /// - public void Clear_NoLock() { - locals.Clear_NoLock(); - } + public void Clear_NoLock() => locals.Clear_NoLock(); /// - public bool Contains_NoLock(Local item) { - return locals.Contains_NoLock(item); - } + public bool Contains_NoLock(Local item) => locals.Contains_NoLock(item); /// - public void CopyTo_NoLock(Local[] array, int arrayIndex) { - locals.CopyTo_NoLock(array, arrayIndex); - } + public void CopyTo_NoLock(Local[] array, int arrayIndex) => locals.CopyTo_NoLock(array, arrayIndex); /// - public int Count_NoLock { - get { return locals.Count_NoLock; } - } + public int Count_NoLock => locals.Count_NoLock; /// - public bool IsReadOnly_NoLock { - get { return locals.IsReadOnly_NoLock; } - } + public bool IsReadOnly_NoLock => locals.IsReadOnly_NoLock; /// - public bool Remove_NoLock(Local item) { - return locals.Remove_NoLock(item); - } + public bool Remove_NoLock(Local item) => locals.Remove_NoLock(item); /// - public IEnumerator GetEnumerator_NoLock() { - return locals.GetEnumerator_NoLock(); - } + public IEnumerator GetEnumerator_NoLock() => locals.GetEnumerator_NoLock(); /// - public TRetType ExecuteLocked(TArgType arg, ExecuteLockedDelegate handler) { - return locals.ExecuteLocked(arg, (tsList, arg2) => handler(this, arg2)); - } + public TRetType ExecuteLocked(TArgType arg, ExecuteLockedDelegate handler) => + locals.ExecuteLocked(arg, (tsList, arg2) => handler(this, arg2)); #endif } @@ -235,49 +176,42 @@ public sealed class Local : IVariable { /// Gets/sets the type of the local /// public TypeSig Type { - get { return typeSig; } - set { typeSig = value; } + get => typeSig; + set => typeSig = value; } /// /// Local index /// public int Index { - get { return index; } - internal set { index = value; } + get => index; + internal set => index = value; } /// /// Gets the name. This property is obsolete, use to get/set the name stored in the PDB file. /// public string Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets the attributes. This property is obsolete, use to get/set the attributes stored in the PDB file. /// public PdbLocalAttributes Attributes { - get { return attributes; } - set { attributes = value; } + get => attributes; + set => attributes = value; } - internal void SetName(string name) { - this.name = name; - } - - internal void SetAttributes(PdbLocalAttributes attributes) { - this.attributes = attributes; - } + internal void SetName(string name) => this.name = name; + internal void SetAttributes(PdbLocalAttributes attributes) => this.attributes = attributes; /// /// Constructor /// /// The type - public Local(TypeSig typeSig) { - this.typeSig = typeSig; - } + public Local(TypeSig typeSig) => this.typeSig = typeSig; /// /// Constructor @@ -305,7 +239,7 @@ public Local(TypeSig typeSig, string name, int index) { public override string ToString() { var n = name; if (string.IsNullOrEmpty(n)) - return string.Format("V_{0}", Index); + return $"V_{Index}"; return n; } } diff --git a/src/DotNet/Emit/MethodBody.cs b/src/DotNet/Emit/MethodBody.cs index d24f5a8bc..1f8045843 100644 --- a/src/DotNet/Emit/MethodBody.cs +++ b/src/DotNet/Emit/MethodBody.cs @@ -28,8 +28,8 @@ public sealed class NativeMethodBody : MethodBody { /// Gets/sets the RVA of the native method body /// public RVA RVA { - get { return rva; } - set { rva = value; } + get => rva; + set => rva = value; } /// @@ -42,9 +42,7 @@ public NativeMethodBody() { /// Constructor /// /// RVA of method body - public NativeMethodBody(RVA rva) { - this.rva = rva; - } + public NativeMethodBody(RVA rva) => this.rva = rva; } /// @@ -69,16 +67,16 @@ public sealed class CilBody : MethodBody { /// Gets/sets a flag indicating whether the original max stack value should be used. /// public bool KeepOldMaxStack { - get { return keepOldMaxStack; } - set { keepOldMaxStack = value; } + get => keepOldMaxStack; + set => keepOldMaxStack = value; } /// /// Gets/sets the init locals flag. This is only valid if the method has any locals. /// public bool InitLocals { - get { return initLocals; } - set { initLocals = value; } + get => initLocals; + set => initLocals = value; } /// @@ -86,107 +84,89 @@ public bool InitLocals { /// the header. /// public byte HeaderSize { - get { return headerSize; } - set { headerSize = value; } + get => headerSize; + set => headerSize = value; } /// /// true if it was a small body header ( is 1) /// - public bool IsSmallHeader { - get { return headerSize == SMALL_HEADER_SIZE; } - } + public bool IsSmallHeader => headerSize == SMALL_HEADER_SIZE; /// /// true if it was a big body header /// - public bool IsBigHeader { - get { return headerSize != SMALL_HEADER_SIZE; } - } + public bool IsBigHeader => headerSize != SMALL_HEADER_SIZE; /// /// Gets/sets max stack value from the fat method header. /// public ushort MaxStack { - get { return maxStack; } - set { maxStack = value; } + get => maxStack; + set => maxStack = value; } /// /// Gets/sets the locals metadata token /// public uint LocalVarSigTok { - get { return localVarSigTok; } - set { localVarSigTok = value; } + get => localVarSigTok; + set => localVarSigTok = value; } /// /// true if is not empty /// - public bool HasInstructions { - get { return instructions.Count > 0; } - } + public bool HasInstructions => instructions.Count > 0; /// /// Gets the instructions /// - public ThreadSafe.IList Instructions { - get { return instructions; } - } + public ThreadSafe.IList Instructions => instructions; /// /// true if is not empty /// - public bool HasExceptionHandlers { - get { return exceptionHandlers.Count > 0; } - } + public bool HasExceptionHandlers => exceptionHandlers.Count > 0; /// /// Gets the exception handlers /// - public ThreadSafe.IList ExceptionHandlers { - get { return exceptionHandlers; } - } + public ThreadSafe.IList ExceptionHandlers => exceptionHandlers; /// /// true if is not empty /// - public bool HasVariables { - get { return localList.Count > 0; } - } + public bool HasVariables => localList.Count > 0; /// /// Gets the locals /// - public LocalList Variables {// Only called Variables for compat w/ older code. Locals is a better and more accurate name - get { return localList; } - } + public LocalList Variables => localList; /// /// Gets/sets the PDB method. This is null if no PDB has been loaded or if there's /// no PDB info for this method. /// public PdbMethod PdbMethod { - get { return pdbMethod; } - set { pdbMethod = value; } + get => pdbMethod; + set => pdbMethod = value; } PdbMethod pdbMethod; /// /// true if is not null /// - public bool HasPdbMethod { - get { return PdbMethod != null; } - } + public bool HasPdbMethod => PdbMethod != null; /// /// Default constructor /// public CilBody() { - this.initLocals = true; - this.instructions = ThreadSafeListCreator.Create(); - this.exceptionHandlers = ThreadSafeListCreator.Create(); - this.localList = new LocalList(); + initLocals = true; + instructions = ThreadSafeListCreator.Create(); + exceptionHandlers = ThreadSafeListCreator.Create(); + localList = new LocalList(); } /// @@ -200,7 +180,7 @@ public CilBody(bool initLocals, IList instructions, IList @@ -209,39 +189,29 @@ public CilBody(bool initLocals, IList instructions, IList /// All method parameters, including the hidden 'this' parameter /// if it's an instance method. Use . - public void SimplifyMacros(IList parameters) { - instructions.SimplifyMacros(localList, parameters); - } + public void SimplifyMacros(IList parameters) => instructions.SimplifyMacros(localList, parameters); /// /// Optimizes instructions by using the shorter form if possible. Eg. Ldc_I4 1 /// will be replaced with Ldc_I4_1. /// - public void OptimizeMacros() { - instructions.OptimizeMacros(); - } + public void OptimizeMacros() => instructions.OptimizeMacros(); /// /// Short branch instructions are converted to the long form, eg. Beq_S is /// converted to Beq. /// - public void SimplifyBranches() { - instructions.SimplifyBranches(); - } + public void SimplifyBranches() => instructions.SimplifyBranches(); /// /// Optimizes branches by using the smallest possible branch /// - public void OptimizeBranches() { - instructions.OptimizeBranches(); - } + public void OptimizeBranches() => instructions.OptimizeBranches(); /// /// Updates each instruction's offset /// /// Total size in bytes of all instructions - public uint UpdateInstructionOffsets() { - return instructions.UpdateInstructionOffsets(); - } + public uint UpdateInstructionOffsets() => instructions.UpdateInstructionOffsets(); } } diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index bb1ebf2ff..f48825a92 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -30,9 +30,8 @@ public static partial class Extensions { /// An object /// The metadata token /// A or null if is invalid - public static IMDTokenProvider ResolveToken(this IInstructionOperandResolver self, uint token) { - return self.ResolveToken(token, new GenericParamContext()); - } + public static IMDTokenProvider ResolveToken(this IInstructionOperandResolver self, uint token) => + self.ResolveToken(token, new GenericParamContext()); } /// @@ -56,9 +55,8 @@ public sealed class MethodBodyReader : MethodBodyReaderBase { /// The operand resolver /// A reader positioned at the start of a .NET method body /// Use parameters from this method - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, MethodDef method) { - return CreateCilBody(opResolver, reader, null, method.Parameters, new GenericParamContext()); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, MethodDef method) => + CreateCilBody(opResolver, reader, null, method.Parameters, new GenericParamContext()); /// /// Creates a CIL method body or returns an empty one if doesn't @@ -68,9 +66,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBin /// A reader positioned at the start of a .NET method body /// Use parameters from this method /// Generic parameter context - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, MethodDef method, GenericParamContext gpContext) { - return CreateCilBody(opResolver, reader, null, method.Parameters, gpContext); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, MethodDef method, GenericParamContext gpContext) => + CreateCilBody(opResolver, reader, null, method.Parameters, gpContext); /// /// Creates a CIL method body or returns an empty one if doesn't @@ -79,9 +76,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBin /// The operand resolver /// A reader positioned at the start of a .NET method body /// Method parameters - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, IList parameters) { - return CreateCilBody(opResolver, reader, null, parameters, new GenericParamContext()); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, IList parameters) => + CreateCilBody(opResolver, reader, null, parameters, new GenericParamContext()); /// /// Creates a CIL method body or returns an empty one if doesn't @@ -91,9 +87,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBin /// A reader positioned at the start of a .NET method body /// Method parameters /// Generic parameter context - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, IList parameters, GenericParamContext gpContext) { - return CreateCilBody(opResolver, reader, null, parameters, gpContext); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader reader, IList parameters, GenericParamContext gpContext) => + CreateCilBody(opResolver, reader, null, parameters, gpContext); /// /// Creates a CIL method body or returns an empty one if is not @@ -104,9 +99,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBin /// Exceptions or null if all exception handlers are in /// /// Method parameters - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters) { - return CreateCilBody(opResolver, MemoryImageStream.Create(code), exceptions == null ? null : MemoryImageStream.Create(exceptions), parameters, new GenericParamContext()); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters) => + CreateCilBody(opResolver, MemoryImageStream.Create(code), exceptions == null ? null : MemoryImageStream.Create(exceptions), parameters, new GenericParamContext()); /// /// Creates a CIL method body or returns an empty one if is not @@ -118,9 +112,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte /// /// Method parameters /// Generic parameter context - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, GenericParamContext gpContext) { - return CreateCilBody(opResolver, MemoryImageStream.Create(code), exceptions == null ? null : MemoryImageStream.Create(exceptions), parameters, gpContext); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, GenericParamContext gpContext) => + CreateCilBody(opResolver, MemoryImageStream.Create(code), exceptions == null ? null : MemoryImageStream.Create(exceptions), parameters, gpContext); /// /// Creates a CIL method body or returns an empty one if doesn't @@ -131,9 +124,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte /// Exception handler reader or null if exceptions aren't /// present or if contains the exception handlers /// Method parameters - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader codeReader, IBinaryReader ehReader, IList parameters) { - return CreateCilBody(opResolver, codeReader, ehReader, parameters, new GenericParamContext()); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBinaryReader codeReader, IBinaryReader ehReader, IList parameters) => + CreateCilBody(opResolver, codeReader, ehReader, parameters, new GenericParamContext()); /// /// Creates a CIL method body or returns an empty one if doesn't @@ -165,9 +157,8 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, IBin /// Max stack /// Code size /// Local variable signature token or 0 if none - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok) { - return CreateCilBody(opResolver, code, exceptions, parameters, flags, maxStack, codeSize, localVarSigTok, new GenericParamContext()); - } + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok) => + CreateCilBody(opResolver, code, exceptions, parameters, flags, maxStack, codeSize, localVarSigTok, new GenericParamContext()); /// /// Creates a CIL method body or returns an empty one if is not @@ -259,7 +250,7 @@ public MethodBodyReader(IInstructionOperandResolver opResolver, IBinaryReader co public MethodBodyReader(IInstructionOperandResolver opResolver, IBinaryReader codeReader, IBinaryReader ehReader, IList parameters, GenericParamContext gpContext) : base(codeReader, parameters) { this.opResolver = opResolver; - this.exceptionsReader = ehReader; + exceptionsReader = ehReader; this.gpContext = gpContext; } @@ -271,7 +262,7 @@ public MethodBodyReader(IInstructionOperandResolver opResolver, IBinaryReader co /// Code size /// Local variable signature token void SetHeader(ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok) { - this.hasReadHeader = true; + hasReadHeader = true; this.flags = flags; this.maxStack = maxStack; this.codeSize = codeSize; @@ -362,19 +353,13 @@ IList ReadLocals() { /// /// Reads all instructions /// - void ReadInstructions() { - ReadInstructionsNumBytes(codeSize); - } + void ReadInstructions() => ReadInstructionsNumBytes(codeSize); /// - protected override IField ReadInlineField(Instruction instr) { - return opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField; - } + protected override IField ReadInlineField(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField; /// - protected override IMethod ReadInlineMethod(Instruction instr) { - return opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod; - } + protected override IMethod ReadInlineMethod(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod; /// protected override MethodSig ReadInlineSig(Instruction instr) { @@ -388,19 +373,13 @@ protected override MethodSig ReadInlineSig(Instruction instr) { } /// - protected override string ReadInlineString(Instruction instr) { - return opResolver.ReadUserString(reader.ReadUInt32()) ?? string.Empty; - } + protected override string ReadInlineString(Instruction instr) => opResolver.ReadUserString(reader.ReadUInt32()) ?? string.Empty; /// - protected override ITokenOperand ReadInlineTok(Instruction instr) { - return opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITokenOperand; - } + protected override ITokenOperand ReadInlineTok(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITokenOperand; /// - protected override ITypeDefOrRef ReadInlineType(Instruction instr) { - return opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef; - } + protected override ITypeDefOrRef ReadInlineType(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef; /// /// Reads all exception handlers diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index ac7ececfe..8d798a550 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -29,30 +29,22 @@ public abstract class MethodBodyReaderBase { /// /// Gets all parameters /// - public IList Parameters { - get { return parameters; } - } + public IList Parameters => parameters; /// /// Gets all locals /// - public IList Locals { - get { return locals; } - } + public IList Locals => locals; /// /// Gets all instructions /// - public IList Instructions { - get { return instructions; } - } + public IList Instructions => instructions; /// /// Gets all exception handlers /// - public IList ExceptionHandlers { - get { return exceptionHandlers; } - } + public IList ExceptionHandlers => exceptionHandlers; /// /// Constructor @@ -189,7 +181,7 @@ protected Instruction GetInstructionThrow(uint offset) { var instr = GetInstruction(offset); if (instr != null) return instr; - throw new InvalidOperationException(string.Format("There's no instruction @ {0:X4}", offset)); + throw new InvalidOperationException($"There's no instruction @ {offset:X4}"); } /// @@ -255,9 +247,7 @@ object ReadOperand(Instruction instr) { /// /// The current instruction /// The operand - protected virtual uint ReadInlineBrTarget(Instruction instr) { - return instr.Offset + (uint)instr.GetSize() + reader.ReadUInt32(); - } + protected virtual uint ReadInlineBrTarget(Instruction instr) => instr.Offset + (uint)instr.GetSize() + reader.ReadUInt32(); /// /// Reads a operand @@ -271,18 +261,14 @@ protected virtual uint ReadInlineBrTarget(Instruction instr) { /// /// The current instruction /// The operand - protected virtual int ReadInlineI(Instruction instr) { - return reader.ReadInt32(); - } + protected virtual int ReadInlineI(Instruction instr) => reader.ReadInt32(); /// /// Reads a operand /// /// The current instruction /// The operand - protected virtual long ReadInlineI8(Instruction instr) { - return reader.ReadInt64(); - } + protected virtual long ReadInlineI8(Instruction instr) => reader.ReadInt64(); /// /// Reads a operand @@ -296,27 +282,21 @@ protected virtual long ReadInlineI8(Instruction instr) { /// /// The current instruction /// The operand - protected virtual object ReadInlineNone(Instruction instr) { - return null; - } + protected virtual object ReadInlineNone(Instruction instr) => null; /// /// Reads a operand /// /// The current instruction /// The operand - protected virtual object ReadInlinePhi(Instruction instr) { - return null; - } + protected virtual object ReadInlinePhi(Instruction instr) => null; /// /// Reads a operand /// /// The current instruction /// The operand - protected virtual double ReadInlineR(Instruction instr) { - return reader.ReadDouble(); - } + protected virtual double ReadInlineR(Instruction instr) => reader.ReadDouble(); /// /// Reads a operand @@ -382,27 +362,21 @@ protected virtual IVariable ReadInlineVar(Instruction instr) { /// /// The current instruction /// The operand - protected virtual Parameter ReadInlineVarArg(Instruction instr) { - return GetParameter(reader.ReadUInt16()); - } + protected virtual Parameter ReadInlineVarArg(Instruction instr) => GetParameter(reader.ReadUInt16()); /// /// Reads a (a local) operand /// /// The current instruction /// The operand - protected virtual Local ReadInlineVarLocal(Instruction instr) { - return GetLocal(reader.ReadUInt16()); - } + protected virtual Local ReadInlineVarLocal(Instruction instr) => GetLocal(reader.ReadUInt16()); /// /// Reads a operand /// /// The current instruction /// The operand - protected virtual uint ReadShortInlineBrTarget(Instruction instr) { - return instr.Offset + (uint)instr.GetSize() + (uint)reader.ReadSByte(); - } + protected virtual uint ReadShortInlineBrTarget(Instruction instr) => instr.Offset + (uint)instr.GetSize() + (uint)reader.ReadSByte(); /// /// Reads a operand @@ -420,9 +394,7 @@ protected virtual object ReadShortInlineI(Instruction instr) { /// /// The current instruction /// The operand - protected virtual float ReadShortInlineR(Instruction instr) { - return reader.ReadSingle(); - } + protected virtual float ReadShortInlineR(Instruction instr) => reader.ReadSingle(); /// /// Reads a operand @@ -440,18 +412,14 @@ protected virtual IVariable ReadShortInlineVar(Instruction instr) { /// /// The current instruction /// The operand - protected virtual Parameter ReadShortInlineVarArg(Instruction instr) { - return GetParameter(reader.ReadByte()); - } + protected virtual Parameter ReadShortInlineVarArg(Instruction instr) => GetParameter(reader.ReadByte()); /// /// Reads a (a local) operand /// /// The current instruction /// The operand - protected virtual Local ReadShortInlineVarLocal(Instruction instr) { - return GetLocal(reader.ReadByte()); - } + protected virtual Local ReadShortInlineVarLocal(Instruction instr) => GetLocal(reader.ReadByte()); /// /// Returns true if it's one of the ldarg/starg instructions that have an operand @@ -476,18 +444,14 @@ protected static bool IsArgOperandInstruction(Instruction instr) { /// /// A parameter index /// A or null if is invalid - protected Parameter GetParameter(int index) { - return parameters.Get(index, null); - } + protected Parameter GetParameter(int index) => parameters.Get(index, null); /// /// Returns a local /// /// A local index /// A or null if is invalid - protected Local GetLocal(int index) { - return locals.Get(index, null); - } + protected Local GetLocal(int index) => locals.Get(index, null); /// /// Add an exception handler if it appears valid diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index b909005f9..34067c335 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -45,11 +45,10 @@ static MethodTableToTypeConverter() { /// Address of type /// The or null public static Type Convert(IntPtr address) { - Type type; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (addrToType.TryGetValue(address, out type)) + if (addrToType.TryGetValue(address, out var type)) return type; type = GetTypeNET20(address) ?? GetTypeUsingTypeBuilder(address); @@ -81,9 +80,9 @@ static Type GetTypeUsingTypeBuilder(IntPtr address) { // .NET 4.5 and later have the documented SetMethodBody() method. static Type GetTypeNET45(TypeBuilder tb, MethodBuilder mb, IntPtr address) { - byte[] code = new byte[1] { 0x2A }; + var code = new byte[1] { 0x2A }; int maxStack = 8; - byte[] locals = GetLocalSignature(address); + var locals = GetLocalSignature(address); setMethodBodyMethodInfo.Invoke(mb, new object[5] { code, maxStack, locals, null, null }); #if NETSTANDARD2_0 var type = tb.CreateTypeInfo(); @@ -126,9 +125,7 @@ static Type GetTypeNET20(IntPtr address) { return Type.GetTypeFromHandle((RuntimeTypeHandle)th); } - static string GetNextTypeName() { - return string.Format("Type{0}", numNewTypes++); - } + static string GetNextTypeName() => "Type" + numNewTypes++.ToString(); static byte[] GetLocalSignature(IntPtr mtAddr) { ulong mtValue = (ulong)mtAddr.ToInt64(); diff --git a/src/DotNet/Emit/MethodUtils.cs b/src/DotNet/Emit/MethodUtils.cs index a02f35480..7a01e9fb8 100644 --- a/src/DotNet/Emit/MethodUtils.cs +++ b/src/DotNet/Emit/MethodUtils.cs @@ -219,8 +219,8 @@ public static void SimplifyMacros(this IList instructions, IList(IList list, int index) { if (list == null) - return default(T); - return list.Get(index, default(T)); + return default; + return list.Get(index, default); } /// diff --git a/src/DotNet/Emit/OpCode.cs b/src/DotNet/Emit/OpCode.cs index f72769ed8..547d1e35f 100644 --- a/src/DotNet/Emit/OpCode.cs +++ b/src/DotNet/Emit/OpCode.cs @@ -36,35 +36,31 @@ public sealed class OpCode { /// /// Push stack behavior /// - public readonly StackBehaviour StackBehaviourPush; // UK spelling for compatibility with Reflection + public readonly StackBehaviour StackBehaviourPush; /// /// Pop stack behavior /// - public readonly StackBehaviour StackBehaviourPop; // UK spelling for compatibility with Reflection + public readonly StackBehaviour StackBehaviourPop; /// /// Gets the value which is compatible with /// - public short Value { - get { return (short)Code; } - } + public short Value => (short)Code; /// /// Gets the size of the opcode. It's either 1 or 2 bytes. /// - public int Size { - get { return Code < (Code)0x100 || Code == Code.UNKNOWN1 ? 1 : 2; } - } + public int Size => Code < (Code)0x100 || Code == Code.UNKNOWN1 ? 1 : 2; internal OpCode(string name, Code code, OperandType operandType, FlowControl flowControl, OpCodeType opCodeType, StackBehaviour push, StackBehaviour pop) { - this.Name = name; - this.Code = code; - this.OperandType = operandType; - this.FlowControl = flowControl; - this.OpCodeType = opCodeType; - this.StackBehaviourPush = push; - this.StackBehaviourPop = pop; + Name = name; + Code = code; + OperandType = operandType; + FlowControl = flowControl; + OpCodeType = opCodeType; + StackBehaviourPush = push; + StackBehaviourPop = pop; if (((ushort)code >> 8) == 0) OpCodes.OneByteOpCodes[(byte)code] = this; else if (((ushort)code >> 8) == 0xFE) @@ -75,175 +71,135 @@ internal OpCode(string name, Code code, OperandType operandType, FlowControl flo /// Creates a new instruction with no operand /// /// A new instance - public Instruction ToInstruction() { - return Instruction.Create(this); - } + public Instruction ToInstruction() => Instruction.Create(this); /// /// Creates a new instruction with a operand /// /// The value /// A new instance - public Instruction ToInstruction(byte value) { - return Instruction.Create(this, value); - } + public Instruction ToInstruction(byte value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance - public Instruction ToInstruction(sbyte value) { - return Instruction.Create(this, value); - } + public Instruction ToInstruction(sbyte value) => Instruction.Create(this, value); /// /// Creates a new instruction with an operand /// /// The value /// A new instance - public Instruction ToInstruction(int value) { - return Instruction.Create(this, value); - } + public Instruction ToInstruction(int value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance - public Instruction ToInstruction(long value) { - return Instruction.Create(this, value); - } + public Instruction ToInstruction(long value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance - public Instruction ToInstruction(float value) { - return Instruction.Create(this, value); - } + public Instruction ToInstruction(float value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance - public Instruction ToInstruction(double value) { - return Instruction.Create(this, value); - } + public Instruction ToInstruction(double value) => Instruction.Create(this, value); /// /// Creates a new instruction with a string operand /// /// The string /// A new instance - public Instruction ToInstruction(string s) { - return Instruction.Create(this, s); - } + public Instruction ToInstruction(string s) => Instruction.Create(this, s); /// /// Creates a new instruction with an instruction target operand /// /// Target instruction /// A new instance - public Instruction ToInstruction(Instruction target) { - return Instruction.Create(this, target); - } + public Instruction ToInstruction(Instruction target) => Instruction.Create(this, target); /// /// Creates a new instruction with an instruction target list operand /// /// The targets /// A new instance - public Instruction ToInstruction(IList targets) { - return Instruction.Create(this, ThreadSafeListCreator.MakeThreadSafe(targets)); - } + public Instruction ToInstruction(IList targets) => Instruction.Create(this, ThreadSafeListCreator.MakeThreadSafe(targets)); /// /// Creates a new instruction with a type operand /// /// The type /// A new instance - public Instruction ToInstruction(ITypeDefOrRef type) { - return Instruction.Create(this, type); - } + public Instruction ToInstruction(ITypeDefOrRef type) => Instruction.Create(this, type); /// /// Creates a new instruction with a type operand /// /// The type /// A new instance - public Instruction ToInstruction(CorLibTypeSig type) { - return Instruction.Create(this, type.TypeDefOrRef); - } + public Instruction ToInstruction(CorLibTypeSig type) => Instruction.Create(this, type.TypeDefOrRef); /// /// Creates a new instruction with a method/field operand /// /// The method/field /// A new instance - public Instruction ToInstruction(MemberRef mr) { - return Instruction.Create(this, mr); - } + public Instruction ToInstruction(MemberRef mr) => Instruction.Create(this, mr); /// /// Creates a new instruction with a field operand /// /// The field /// A new instance - public Instruction ToInstruction(IField field) { - return Instruction.Create(this, field); - } + public Instruction ToInstruction(IField field) => Instruction.Create(this, field); /// /// Creates a new instruction with a method operand /// /// The method /// A new instance - public Instruction ToInstruction(IMethod method) { - return Instruction.Create(this, method); - } + public Instruction ToInstruction(IMethod method) => Instruction.Create(this, method); /// /// Creates a new instruction with a token operand /// /// The token /// A new instance - public Instruction ToInstruction(ITokenOperand token) { - return Instruction.Create(this, token); - } + public Instruction ToInstruction(ITokenOperand token) => Instruction.Create(this, token); /// /// Creates a new instruction with a method signature operand /// /// The method signature /// A new instance - public Instruction ToInstruction(MethodSig methodSig) { - return Instruction.Create(this, methodSig); - } + public Instruction ToInstruction(MethodSig methodSig) => Instruction.Create(this, methodSig); /// /// Creates a new instruction with a method parameter operand /// /// The method parameter /// A new instance - public Instruction ToInstruction(Parameter parameter) { - return Instruction.Create(this, parameter); - } + public Instruction ToInstruction(Parameter parameter) => Instruction.Create(this, parameter); /// /// Creates a new instruction with a method local operand /// /// The method local /// A new instance - public Instruction ToInstruction(Local local) { - return Instruction.Create(this, local); - } + public Instruction ToInstruction(Local local) => Instruction.Create(this, local); /// - public override string ToString() { - return Name; - } + public override string ToString() => Name; } } diff --git a/src/DotNet/EventDef.cs b/src/DotNet/EventDef.cs index 7bc631641..c1fbe7763 100644 --- a/src/DotNet/EventDef.cs +++ b/src/DotNet/EventDef.cs @@ -27,32 +27,26 @@ public abstract class EventDef : IHasCustomAttribute, IHasSemantic, IHasCustomDe #endif /// - public MDToken MDToken { - get { return new MDToken(Table.Event, rid); } - } + public MDToken MDToken => new MDToken(Table.Event, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 10; } - } + public int HasCustomAttributeTag => 10; /// - public int HasSemanticTag { - get { return 0; } - } + public int HasSemanticTag => 0; /// /// From column Event.EventFlags /// public EventAttributes Attributes { - get { return (EventAttributes)attributes; } - set { attributes = (int)value; } + get => (EventAttributes)attributes; + set => attributes = (int)value; } /// protected int attributes; @@ -61,8 +55,8 @@ public EventAttributes Attributes { /// From column Event.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -71,8 +65,8 @@ public UTF8String Name { /// From column Event.EventType /// public ITypeDefOrRef EventType { - get { return eventType; } - set { eventType = value; } + get => eventType; + set => eventType = value; } /// protected ITypeDefOrRef eventType; @@ -90,19 +84,14 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public int HasCustomDebugInformationTag { - get { return 10; } - } + public int HasCustomDebugInformationTag => 10; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -117,9 +106,8 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Gets/sets the adder method @@ -195,9 +183,8 @@ void InitializeEventMethods() { /// Initializes , , /// and . /// - protected virtual void InitializeEventMethods_NoLock() { + protected virtual void InitializeEventMethods_NoLock() => otherMethods = ThreadSafeListCreator.Create(); - } /// protected MethodDef addMethod; @@ -209,40 +196,31 @@ protected virtual void InitializeEventMethods_NoLock() { protected ThreadSafe.IList otherMethods; /// Reset , , , - protected void ResetMethods() { - otherMethods = null; - } + protected void ResetMethods() => otherMethods = null; /// /// true if there are no methods attached to this event /// - public bool IsEmpty { - get { - // The first property access initializes the other fields we access here - return AddMethod == null && - removeMethod == null && - invokeMethod == null && - otherMethods.Count == 0; - } - } + public bool IsEmpty => + // The first property access initializes the other fields we access here + AddMethod == null && + removeMethod == null && + invokeMethod == null && + otherMethods.Count == 0; /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// /// true if is not empty /// - public bool HasOtherMethods { - get { return OtherMethods.Count > 0; } - } + public bool HasOtherMethods => OtherMethods.Count > 0; /// /// Gets/sets the declaring type (owner type) /// public TypeDef DeclaringType { - get { return declaringType2; } + get => declaringType2; set { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) @@ -255,9 +233,7 @@ public TypeDef DeclaringType { } /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return declaringType2; } - } + ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; /// /// Called by and should normally not be called by any user @@ -265,81 +241,33 @@ ITypeDefOrRef IMemberRef.DeclaringType { /// declaring type without inserting it in the declaring type's method list. /// public TypeDef DeclaringType2 { - get { return declaringType2; } - set { declaringType2 = value; } + get => declaringType2; + set => declaringType2 = value; } /// protected TypeDef declaringType2; /// - public ModuleDef Module { - get { - var dt = declaringType2; - return dt == null ? null : dt.Module; - } - } + public ModuleDef Module => declaringType2?.Module; /// /// Gets the full name of the event /// - public string FullName { - get { - var dt = declaringType2; - return FullNameCreator.EventFullName(dt == null ? null : dt.FullName, name, eventType, null, null); - } - } - - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return true; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + public string FullName => FullNameCreator.EventFullName(declaringType2?.FullName, name, eventType, null, null); + + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => true; + bool IMemberRef.IsGenericParam => false; /// /// Set or clear flags in @@ -369,22 +297,20 @@ void ModifyAttributes(bool set, EventAttributes flags) { /// Gets/sets the bit /// public bool IsSpecialName { - get { return ((EventAttributes)attributes & EventAttributes.SpecialName) != 0; } - set { ModifyAttributes(value, EventAttributes.SpecialName); } + get => ((EventAttributes)attributes & EventAttributes.SpecialName) != 0; + set => ModifyAttributes(value, EventAttributes.SpecialName); } /// /// Gets/sets the bit /// public bool IsRuntimeSpecialName { - get { return ((EventAttributes)attributes & EventAttributes.RTSpecialName) != 0; } - set { ModifyAttributes(value, EventAttributes.RTSpecialName); } + get => ((EventAttributes)attributes & EventAttributes.RTSpecialName) != 0; + set => ModifyAttributes(value, EventAttributes.RTSpecialName); } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -422,8 +348,8 @@ public EventDefUser(UTF8String name, ITypeDefOrRef type) /// Flags public EventDefUser(UTF8String name, ITypeDefOrRef type, EventAttributes flags) { this.name = name; - this.eventType = type; - this.attributes = (int)flags; + eventType = type; + attributes = (int)flags; } } @@ -437,9 +363,7 @@ sealed class EventDefMD : EventDef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -467,15 +391,14 @@ public EventDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.EventTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Event rid {0} does not exist", rid)); + throw new BadImageFormatException($"Event rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint eventType = readerModule.TablesStream.ReadEventRow(origRid, out this.attributes, out name); + uint eventType = readerModule.TablesStream.ReadEventRow(origRid, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); - this.declaringType2 = readerModule.GetOwnerType(this); + declaringType2 = readerModule.GetOwnerType(this); this.eventType = readerModule.ResolveTypeDefOrRef(eventType, new GenericParamContext(declaringType2)); } diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 54e8b7b16..45ffc1e44 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -32,25 +32,19 @@ public abstract class ExportedType : IHasCustomAttribute, IImplementation, IHasC protected ModuleDef module; /// - public MDToken MDToken { - get { return new MDToken(Table.ExportedType, rid); } - } + public MDToken MDToken => new MDToken(Table.ExportedType, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 17; } - } + public int HasCustomAttributeTag => 17; /// - public int ImplementationTag { - get { return 2; } - } + public int ImplementationTag => 2; /// /// Gets all custom attributes @@ -65,24 +59,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 17; } - } + public int HasCustomDebugInformationTag => 17; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -97,9 +84,8 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// public bool IsValueType { @@ -110,100 +96,68 @@ public bool IsValueType { } /// - public bool IsPrimitive { - get { return this.IsPrimitive(); } - } + public bool IsPrimitive => this.IsPrimitive(); /// - string IType.TypeName { - get { return FullNameCreator.Name(this, false, null); } - } + string IType.TypeName => FullNameCreator.Name(this, false, null); /// public UTF8String Name { - get { return typeName; } - set { typeName = value; } + get => typeName; + set => typeName = value; } /// - public string ReflectionName { - get { return FullNameCreator.Name(this, true, null); } - } + public string ReflectionName => FullNameCreator.Name(this, true, null); /// - public string Namespace { - get { return FullNameCreator.Namespace(this, false, null); } - } + public string Namespace => FullNameCreator.Namespace(this, false, null); /// - public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true, null); } - } + public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); /// - public string FullName { - get { return FullNameCreator.FullName(this, false, null, null); } - } + public string FullName => FullNameCreator.FullName(this, false, null, null); /// - public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true, null, null); } - } + public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); /// - public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } - } + public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly { - get { return FullNameCreator.DefinitionAssembly(this); } - } + public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); /// - public IScope Scope { - get { return FullNameCreator.Scope(this); } - } + public IScope Scope => FullNameCreator.Scope(this); /// - public ITypeDefOrRef ScopeType { - get { return FullNameCreator.ScopeType(this); } - } + public ITypeDefOrRef ScopeType => FullNameCreator.ScopeType(this); /// /// Always returns false since a does not contain any /// or . /// - public bool ContainsGenericParameter { - get { return false; } - } + public bool ContainsGenericParameter => false; /// - public ModuleDef Module { - get { return module; } - } + public ModuleDef Module => module; /// - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } + bool IIsTypeOrMethod.IsMethod => false; /// - bool IIsTypeOrMethod.IsType { - get { return true; } - } + bool IIsTypeOrMethod.IsType => true; /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { return 0; } - } + int IGenericParameterProvider.NumberOfGenericParameters => 0; /// /// From column ExportedType.Flags /// public TypeAttributes Attributes { - get { return (TypeAttributes)attributes; } - set { attributes = (int)value; } + get => (TypeAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -212,8 +166,8 @@ public TypeAttributes Attributes { /// From column ExportedType.TypeDefId /// public uint TypeDefId { - get { return typeDefId; } - set { typeDefId = value; } + get => typeDefId; + set => typeDefId = value; } /// protected uint typeDefId; @@ -222,8 +176,8 @@ public uint TypeDefId { /// From column ExportedType.TypeName /// public UTF8String TypeName { - get { return typeName; } - set { typeName = value; } + get => typeName; + set => typeName = value; } /// protected UTF8String typeName; @@ -232,8 +186,8 @@ public UTF8String TypeName { /// From column ExportedType.TypeNamespace /// public UTF8String TypeNamespace { - get { return typeNamespace; } - set { typeNamespace = value; } + get => typeNamespace; + set => typeNamespace = value; } /// protected UTF8String typeNamespace; @@ -277,16 +231,12 @@ void InitializeImplementation() { } /// Called to initialize - protected virtual IImplementation GetImplementation_NoLock() { - return null; - } + protected virtual IImplementation GetImplementation_NoLock() => null; /// /// true if it's nested within another /// - public bool IsNested { - get { return DeclaringType != null; } - } + public bool IsNested => DeclaringType != null; /// /// Gets the declaring type, if any @@ -345,225 +295,195 @@ void ModifyAttributes(bool set, TypeAttributes flags) { /// Gets/sets the visibility /// public TypeAttributes Visibility { - get { return (TypeAttributes)attributes & TypeAttributes.VisibilityMask; } - set { ModifyAttributes(~TypeAttributes.VisibilityMask, value & TypeAttributes.VisibilityMask); } + get => (TypeAttributes)attributes & TypeAttributes.VisibilityMask; + set => ModifyAttributes(~TypeAttributes.VisibilityMask, value & TypeAttributes.VisibilityMask); } /// /// true if is set /// - public bool IsNotPublic { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; } - } + public bool IsNotPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; /// /// true if is set /// - public bool IsPublic { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; } - } + public bool IsPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; /// /// true if is set /// - public bool IsNestedPublic { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; } - } + public bool IsNestedPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; /// /// true if is set /// - public bool IsNestedPrivate { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; } - } + public bool IsNestedPrivate => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; /// /// true if is set /// - public bool IsNestedFamily { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; } - } + public bool IsNestedFamily => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; /// /// true if is set /// - public bool IsNestedAssembly { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; } - } + public bool IsNestedAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; /// /// true if is set /// - public bool IsNestedFamilyAndAssembly { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; } - } + public bool IsNestedFamilyAndAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; /// /// true if is set /// - public bool IsNestedFamilyOrAssembly { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; } - } + public bool IsNestedFamilyOrAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; /// /// Gets/sets the layout /// public TypeAttributes Layout { - get { return (TypeAttributes)attributes & TypeAttributes.LayoutMask; } - set { ModifyAttributes(~TypeAttributes.LayoutMask, value & TypeAttributes.LayoutMask); } + get => (TypeAttributes)attributes & TypeAttributes.LayoutMask; + set => ModifyAttributes(~TypeAttributes.LayoutMask, value & TypeAttributes.LayoutMask); } /// /// true if is set /// - public bool IsAutoLayout { - get { return ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; } - } + public bool IsAutoLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; /// /// true if is set /// - public bool IsSequentialLayout { - get { return ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; } - } + public bool IsSequentialLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; /// /// true if is set /// - public bool IsExplicitLayout { - get { return ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; } - } + public bool IsExplicitLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; /// /// Gets/sets the bit /// public bool IsInterface { - get { return ((TypeAttributes)attributes & TypeAttributes.Interface) != 0; } - set { ModifyAttributes(value, TypeAttributes.Interface); } + get => ((TypeAttributes)attributes & TypeAttributes.Interface) != 0; + set => ModifyAttributes(value, TypeAttributes.Interface); } /// /// Gets/sets the bit /// public bool IsClass { - get { return ((TypeAttributes)attributes & TypeAttributes.Interface) == 0; } - set { ModifyAttributes(!value, TypeAttributes.Interface); } + get => ((TypeAttributes)attributes & TypeAttributes.Interface) == 0; + set => ModifyAttributes(!value, TypeAttributes.Interface); } /// /// Gets/sets the bit /// public bool IsAbstract { - get { return ((TypeAttributes)attributes & TypeAttributes.Abstract) != 0; } - set { ModifyAttributes(value, TypeAttributes.Abstract); } + get => ((TypeAttributes)attributes & TypeAttributes.Abstract) != 0; + set => ModifyAttributes(value, TypeAttributes.Abstract); } /// /// Gets/sets the bit /// public bool IsSealed { - get { return ((TypeAttributes)attributes & TypeAttributes.Sealed) != 0; } - set { ModifyAttributes(value, TypeAttributes.Sealed); } + get => ((TypeAttributes)attributes & TypeAttributes.Sealed) != 0; + set => ModifyAttributes(value, TypeAttributes.Sealed); } /// /// Gets/sets the bit /// public bool IsSpecialName { - get { return ((TypeAttributes)attributes & TypeAttributes.SpecialName) != 0; } - set { ModifyAttributes(value, TypeAttributes.SpecialName); } + get => ((TypeAttributes)attributes & TypeAttributes.SpecialName) != 0; + set => ModifyAttributes(value, TypeAttributes.SpecialName); } /// /// Gets/sets the bit /// public bool IsImport { - get { return ((TypeAttributes)attributes & TypeAttributes.Import) != 0; } - set { ModifyAttributes(value, TypeAttributes.Import); } + get => ((TypeAttributes)attributes & TypeAttributes.Import) != 0; + set => ModifyAttributes(value, TypeAttributes.Import); } /// /// Gets/sets the bit /// public bool IsSerializable { - get { return ((TypeAttributes)attributes & TypeAttributes.Serializable) != 0; } - set { ModifyAttributes(value, TypeAttributes.Serializable); } + get => ((TypeAttributes)attributes & TypeAttributes.Serializable) != 0; + set => ModifyAttributes(value, TypeAttributes.Serializable); } /// /// Gets/sets the bit /// public bool IsWindowsRuntime { - get { return ((TypeAttributes)attributes & TypeAttributes.WindowsRuntime) != 0; } - set { ModifyAttributes(value, TypeAttributes.WindowsRuntime); } + get => ((TypeAttributes)attributes & TypeAttributes.WindowsRuntime) != 0; + set => ModifyAttributes(value, TypeAttributes.WindowsRuntime); } /// /// Gets/sets the string format /// public TypeAttributes StringFormat { - get { return (TypeAttributes)attributes & TypeAttributes.StringFormatMask; } - set { ModifyAttributes(~TypeAttributes.StringFormatMask, value & TypeAttributes.StringFormatMask); } + get => (TypeAttributes)attributes & TypeAttributes.StringFormatMask; + set => ModifyAttributes(~TypeAttributes.StringFormatMask, value & TypeAttributes.StringFormatMask); } /// /// true if is set /// - public bool IsAnsiClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; } - } + public bool IsAnsiClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; /// /// true if is set /// - public bool IsUnicodeClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; } - } + public bool IsUnicodeClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; /// /// true if is set /// - public bool IsAutoClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; } - } + public bool IsAutoClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; /// /// true if is set /// - public bool IsCustomFormatClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.CustomFormatClass; } - } + public bool IsCustomFormatClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.CustomFormatClass; /// /// Gets/sets the bit /// public bool IsBeforeFieldInit { - get { return ((TypeAttributes)attributes & TypeAttributes.BeforeFieldInit) != 0; } - set { ModifyAttributes(value, TypeAttributes.BeforeFieldInit); } + get => ((TypeAttributes)attributes & TypeAttributes.BeforeFieldInit) != 0; + set => ModifyAttributes(value, TypeAttributes.BeforeFieldInit); } /// /// Gets/sets the bit. See also /// public bool IsForwarder { - get { return ((TypeAttributes)attributes & TypeAttributes.Forwarder) != 0; } - set { ModifyAttributes(value, TypeAttributes.Forwarder); } + get => ((TypeAttributes)attributes & TypeAttributes.Forwarder) != 0; + set => ModifyAttributes(value, TypeAttributes.Forwarder); } /// /// Gets/sets the bit /// public bool IsRuntimeSpecialName { - get { return ((TypeAttributes)attributes & TypeAttributes.RTSpecialName) != 0; } - set { ModifyAttributes(value, TypeAttributes.RTSpecialName); } + get => ((TypeAttributes)attributes & TypeAttributes.RTSpecialName) != 0; + set => ModifyAttributes(value, TypeAttributes.RTSpecialName); } /// /// Gets/sets the bit /// public bool HasSecurity { - get { return ((TypeAttributes)attributes & TypeAttributes.HasSecurity) != 0; } - set { ModifyAttributes(value, TypeAttributes.HasSecurity); } + get => ((TypeAttributes)attributes & TypeAttributes.HasSecurity) != 0; + set => ModifyAttributes(value, TypeAttributes.HasSecurity); } const int MAX_LOOP_ITERS = 50; @@ -573,7 +493,7 @@ public bool HasSecurity { /// public bool MovedToAnotherAssembly { get { - ExportedType et = this; + var et = this; for (int i = 0; i < MAX_LOOP_ITERS; i++) { var impl = et.Implementation; if (impl is AssemblyRef) @@ -591,9 +511,7 @@ public bool MovedToAnotherAssembly { /// Resolves the type /// /// A instance or null if it couldn't be resolved - public TypeDef Resolve() { - return Resolve(null); - } + public TypeDef Resolve() => Resolve(null); /// /// Resolves the type @@ -645,7 +563,7 @@ public TypeDef ResolveThrow() { var type = Resolve(); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not resolve type: {0} ({1})", this, DefinitionAssembly)); + throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); } /// @@ -657,8 +575,7 @@ public TypeRef ToTypeRef() { var mod = module; IImplementation impl = this; for (int i = 0; i < MAX_LOOP_ITERS && impl != null; i++) { - var et = impl as ExportedType; - if (et != null) { + if (impl is ExportedType et) { var newTr = mod.UpdateRowId(new TypeRefUser(mod, et.TypeNamespace, et.TypeName)); if (result == null) result = newTr; @@ -670,15 +587,13 @@ public TypeRef ToTypeRef() { continue; } - var asmRef = impl as AssemblyRef; - if (asmRef != null) { + if (impl is AssemblyRef asmRef) { // prev is never null when we're here prev.ResolutionScope = asmRef; return result; } - var file = impl as FileDef; - if (file != null) { + if (impl is FileDef file) { // prev is never null when we're here prev.ResolutionScope = FindModule(mod, file); return result; @@ -701,9 +616,7 @@ static ModuleDef FindModule(ModuleDef module, FileDef file) { } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -714,9 +627,7 @@ public class ExportedTypeUser : ExportedType { /// Constructor /// /// Owner module - public ExportedTypeUser(ModuleDef module) { - this.module = module; - } + public ExportedTypeUser(ModuleDef module) => this.module = module; /// /// Constructor @@ -732,9 +643,9 @@ public ExportedTypeUser(ModuleDef module, uint typeDefId, UTF8String typeNamespa this.typeDefId = typeDefId; this.typeName = typeName; this.typeNamespace = typeNamespace; - this.attributes = (int)flags; + attributes = (int)flags; this.implementation = implementation; - this.implementation_isInitialized = true; + implementation_isInitialized = true; } } @@ -749,9 +660,7 @@ sealed class ExportedTypeMD : ExportedType, IMDTokenProviderMD { readonly uint implementationRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -768,9 +677,8 @@ protected override void InitializeCustomDebugInfos() { } /// - protected override IImplementation GetImplementation_NoLock() { - return readerModule.ResolveImplementation(implementationRid); - } + protected override IImplementation GetImplementation_NoLock() => + readerModule.ResolveImplementation(implementationRid); /// /// Constructor @@ -784,16 +692,15 @@ public ExportedTypeMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ExportedTypeTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("ExportedType rid {0} does not exist", rid)); + throw new BadImageFormatException($"ExportedType rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - this.module = readerModule; - uint name, @namespace; - this.implementationRid = readerModule.TablesStream.ReadExportedTypeRow(origRid, out this.attributes, out this.typeDefId, out name, out @namespace); - this.typeName = readerModule.StringsStream.ReadNoNull(name); - this.typeNamespace = readerModule.StringsStream.ReadNoNull(@namespace); + module = readerModule; + implementationRid = readerModule.TablesStream.ReadExportedTypeRow(origRid, out attributes, out typeDefId, out uint name, out uint @namespace); + typeName = readerModule.StringsStream.ReadNoNull(name); + typeNamespace = readerModule.StringsStream.ReadNoNull(@namespace); } } } diff --git a/src/DotNet/FieldDef.cs b/src/DotNet/FieldDef.cs index de899bb4b..f4fa76aae 100644 --- a/src/DotNet/FieldDef.cs +++ b/src/DotNet/FieldDef.cs @@ -28,35 +28,25 @@ public abstract class FieldDef : IHasConstant, IHasCustomAttribute, IHasFieldMar #endif /// - public MDToken MDToken { - get { return new MDToken(Table.Field, rid); } - } + public MDToken MDToken => new MDToken(Table.Field, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasConstantTag { - get { return 0; } - } + public int HasConstantTag => 0; /// - public int HasCustomAttributeTag { - get { return 1; } - } + public int HasCustomAttributeTag => 1; /// - public int HasFieldMarshalTag { - get { return 0; } - } + public int HasFieldMarshalTag => 0; /// - public int MemberForwardedTag { - get { return 0; } - } + public int MemberForwardedTag => 0; /// /// Gets all custom attributes @@ -71,19 +61,14 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public int HasCustomDebugInformationTag { - get { return 1; } - } + public int HasCustomDebugInformationTag => 1; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -98,16 +83,15 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// From column Field.Flags /// public FieldAttributes Attributes { - get { return (FieldAttributes)attributes; } - set { attributes = (int)value; } + get => (FieldAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -116,8 +100,8 @@ public FieldAttributes Attributes { /// From column Field.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -126,8 +110,8 @@ public UTF8String Name { /// From column Field.Signature /// public CallingConventionSig Signature { - get { return signature; } - set { signature = value; } + get => signature; + set => signature = value; } /// protected CallingConventionSig signature; @@ -171,9 +155,7 @@ void InitializeFieldOffset() { } /// Called to initialize - protected virtual uint? GetFieldOffset_NoLock() { - return null; - } + protected virtual uint? GetFieldOffset_NoLock() => null; /// public MarshalType MarshalType { @@ -212,14 +194,11 @@ void InitializeMarshalType() { } /// Called to initialize - protected virtual MarshalType GetMarshalType_NoLock() { - return null; - } + protected virtual MarshalType GetMarshalType_NoLock() => null; /// Reset - protected void ResetMarshalType() { + protected void ResetMarshalType() => marshalType_isInitialized = false; - } /// /// Gets/sets the field RVA @@ -260,14 +239,10 @@ void InitializeRVA() { } /// Called to initialize - protected virtual RVA GetRVA_NoLock() { - return 0; - } + protected virtual RVA GetRVA_NoLock() => 0; /// Reset - protected void ResetRVA() { - rva_isInitialized = false; - } + protected void ResetRVA() => rva_isInitialized = false; /// /// Gets/sets the initial value. Be sure to set to true if @@ -309,14 +284,10 @@ void InitializeInitialValue() { } /// Called to initialize - protected virtual byte[] GetInitialValue_NoLock() { - return null; - } + protected virtual byte[] GetInitialValue_NoLock() => null; /// Reset - protected void ResetInitialValue() { - initialValue_isInitialized = false; - } + protected void ResetInitialValue() => initialValue_isInitialized = false; /// public ImplMap ImplMap { @@ -355,9 +326,7 @@ void InitializeImplMap() { } /// Called to initialize - protected virtual ImplMap GetImplMap_NoLock() { - return null; - } + protected virtual ImplMap GetImplMap_NoLock() => null; /// public Constant Constant { @@ -396,30 +365,22 @@ void InitializeConstant() { } /// Called to initialize - protected virtual Constant GetConstant_NoLock() { - return null; - } + protected virtual Constant GetConstant_NoLock() => null; /// Reset - protected void ResetConstant() { - constant_isInitialized = false; - } + protected void ResetConstant() => constant_isInitialized = false; /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public bool HasImplMap { - get { return ImplMap != null; } - } + public bool HasImplMap => ImplMap != null; /// /// Gets/sets the declaring type (owner type) /// public TypeDef DeclaringType { - get { return declaringType2; } + get => declaringType2; set { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) @@ -432,9 +393,7 @@ public TypeDef DeclaringType { } /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return declaringType2; } - } + ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; /// /// Called by and should normally not be called by any user @@ -442,8 +401,8 @@ ITypeDefOrRef IMemberRef.DeclaringType { /// declaring type without inserting it in the declaring type's method list. /// public TypeDef DeclaringType2 { - get { return declaringType2; } - set { declaringType2 = value; } + get => declaringType2; + set => declaringType2 = value; } /// protected TypeDef declaringType2; @@ -452,83 +411,36 @@ public TypeDef DeclaringType2 { /// Gets/sets the /// public FieldSig FieldSig { - get { return signature as FieldSig; } - set { signature = value; } + get => signature as FieldSig; + set => signature = value; } /// - public ModuleDef Module { - get { - var dt = declaringType2; - return dt == null ? null : dt.Module; - } - } - - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return true; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return true; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + public ModuleDef Module => declaringType2?.Module; + + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => true; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => true; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// /// true if is not null /// - public bool HasLayoutInfo { - get { return FieldOffset != null; } - } + public bool HasLayoutInfo => FieldOffset != null; /// /// true if is not null /// - public bool HasConstant { - get { return Constant != null; } - } + public bool HasConstant => Constant != null; /// /// Gets the constant element type or if there's no constant @@ -543,15 +455,13 @@ public ElementType ElementType { /// /// true if is not null /// - public bool HasMarshalType { - get { return MarshalType != null; } - } + public bool HasMarshalType => MarshalType != null; /// /// Gets/sets the field type /// public TypeSig FieldType { - get { return FieldSig.GetFieldType(); } + get => FieldSig.GetFieldType(); set { var sig = FieldSig; if (sig != null) @@ -605,162 +515,140 @@ void ModifyAttributes(bool set, FieldAttributes flags) { /// Gets/sets the field access /// public FieldAttributes Access { - get { return (FieldAttributes)attributes & FieldAttributes.FieldAccessMask; } - set { ModifyAttributes(~FieldAttributes.FieldAccessMask, value & FieldAttributes.FieldAccessMask); } + get => (FieldAttributes)attributes & FieldAttributes.FieldAccessMask; + set => ModifyAttributes(~FieldAttributes.FieldAccessMask, value & FieldAttributes.FieldAccessMask); } /// /// true if is set /// - public bool IsCompilerControlled { - get { return IsPrivateScope; } - } + public bool IsCompilerControlled => IsPrivateScope; /// /// true if is set /// - public bool IsPrivateScope { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.PrivateScope; } - } + public bool IsPrivateScope => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.PrivateScope; /// /// true if is set /// - public bool IsPrivate { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; } - } + public bool IsPrivate => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; /// /// true if is set /// - public bool IsFamilyAndAssembly { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; } - } + public bool IsFamilyAndAssembly => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; /// /// true if is set /// - public bool IsAssembly { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; } - } + public bool IsAssembly => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; /// /// true if is set /// - public bool IsFamily { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; } - } + public bool IsFamily => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; /// /// true if is set /// - public bool IsFamilyOrAssembly { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; } - } + public bool IsFamilyOrAssembly => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; /// /// true if is set /// - public bool IsPublic { - get { return ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; } - } + public bool IsPublic => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; /// /// Gets/sets the bit /// public bool IsStatic { - get { return ((FieldAttributes)attributes & FieldAttributes.Static) != 0; } - set { ModifyAttributes(value, FieldAttributes.Static); } + get => ((FieldAttributes)attributes & FieldAttributes.Static) != 0; + set => ModifyAttributes(value, FieldAttributes.Static); } /// /// Gets/sets the bit /// public bool IsInitOnly { - get { return ((FieldAttributes)attributes & FieldAttributes.InitOnly) != 0; } - set { ModifyAttributes(value, FieldAttributes.InitOnly); } + get => ((FieldAttributes)attributes & FieldAttributes.InitOnly) != 0; + set => ModifyAttributes(value, FieldAttributes.InitOnly); } /// /// Gets/sets the bit /// public bool IsLiteral { - get { return ((FieldAttributes)attributes & FieldAttributes.Literal) != 0; } - set { ModifyAttributes(value, FieldAttributes.Literal); } + get => ((FieldAttributes)attributes & FieldAttributes.Literal) != 0; + set => ModifyAttributes(value, FieldAttributes.Literal); } /// /// Gets/sets the bit /// public bool IsNotSerialized { - get { return ((FieldAttributes)attributes & FieldAttributes.NotSerialized) != 0; } - set { ModifyAttributes(value, FieldAttributes.NotSerialized); } + get => ((FieldAttributes)attributes & FieldAttributes.NotSerialized) != 0; + set => ModifyAttributes(value, FieldAttributes.NotSerialized); } /// /// Gets/sets the bit /// public bool IsSpecialName { - get { return ((FieldAttributes)attributes & FieldAttributes.SpecialName) != 0; } - set { ModifyAttributes(value, FieldAttributes.SpecialName); } + get => ((FieldAttributes)attributes & FieldAttributes.SpecialName) != 0; + set => ModifyAttributes(value, FieldAttributes.SpecialName); } /// /// Gets/sets the bit /// public bool IsPinvokeImpl { - get { return ((FieldAttributes)attributes & FieldAttributes.PinvokeImpl) != 0; } - set { ModifyAttributes(value, FieldAttributes.PinvokeImpl); } + get => ((FieldAttributes)attributes & FieldAttributes.PinvokeImpl) != 0; + set => ModifyAttributes(value, FieldAttributes.PinvokeImpl); } /// /// Gets/sets the bit /// public bool IsRuntimeSpecialName { - get { return ((FieldAttributes)attributes & FieldAttributes.RTSpecialName) != 0; } - set { ModifyAttributes(value, FieldAttributes.RTSpecialName); } + get => ((FieldAttributes)attributes & FieldAttributes.RTSpecialName) != 0; + set => ModifyAttributes(value, FieldAttributes.RTSpecialName); } /// /// Gets/sets the bit /// public bool HasFieldMarshal { - get { return ((FieldAttributes)attributes & FieldAttributes.HasFieldMarshal) != 0; } - set { ModifyAttributes(value, FieldAttributes.HasFieldMarshal); } + get => ((FieldAttributes)attributes & FieldAttributes.HasFieldMarshal) != 0; + set => ModifyAttributes(value, FieldAttributes.HasFieldMarshal); } /// /// Gets/sets the bit /// public bool HasDefault { - get { return ((FieldAttributes)attributes & FieldAttributes.HasDefault) != 0; } - set { ModifyAttributes(value, FieldAttributes.HasDefault); } + get => ((FieldAttributes)attributes & FieldAttributes.HasDefault) != 0; + set => ModifyAttributes(value, FieldAttributes.HasDefault); } /// /// Gets/sets the bit /// public bool HasFieldRVA { - get { return ((FieldAttributes)attributes & FieldAttributes.HasFieldRVA) != 0; } - set { ModifyAttributes(value, FieldAttributes.HasFieldRVA); } + get => ((FieldAttributes)attributes & FieldAttributes.HasFieldRVA) != 0; + set => ModifyAttributes(value, FieldAttributes.HasFieldRVA); } /// /// Returns the full name of this field /// - public string FullName { - get { - var dt = declaringType2; - return FullNameCreator.FieldFullName(dt == null ? null : dt.FullName, name, FieldSig, null, null); - } - } + public string FullName => FullNameCreator.FieldFullName(declaringType2?.FullName, name, FieldSig, null, null); /// /// Gets the size of this field in bytes or 0 if unknown. /// public uint GetFieldSize() { - uint size; - if (!GetFieldSize(out size)) + if (!GetFieldSize(out uint size)) return 0; return size; } @@ -770,9 +658,7 @@ public uint GetFieldSize() { /// /// Updated with size /// true if is valid, false otherwise - public bool GetFieldSize(out uint size) { - return GetFieldSize(declaringType2, FieldSig, out size); - } + public bool GetFieldSize(out uint size) => GetFieldSize(declaringType2, FieldSig, out size); /// /// Gets the size of this field in bytes or 0 if unknown. @@ -781,9 +667,7 @@ public bool GetFieldSize(out uint size) { /// The field signature of this /// Updated with size /// true if is valid, false otherwise - protected bool GetFieldSize(TypeDef declaringType, FieldSig fieldSig, out uint size) { - return GetFieldSize(declaringType, fieldSig, GetPointerSize(declaringType), out size); - } + protected bool GetFieldSize(TypeDef declaringType, FieldSig fieldSig, out uint size) => GetFieldSize(declaringType, fieldSig, GetPointerSize(declaringType), out size); /// /// Gets the size of this field in bytes or 0 if unknown. @@ -837,9 +721,7 @@ int GetPointerSize(TypeDef declaringType) { } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -893,9 +775,7 @@ sealed class FieldDefMD : FieldDef, IMDTokenProviderMD { readonly FieldAttributes origAttributes; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -912,39 +792,33 @@ protected override void InitializeCustomDebugInfos() { } /// - protected override uint? GetFieldOffset_NoLock() { - return readerModule.TablesStream.ReadFieldLayoutRow2(readerModule.MetaData.GetFieldLayoutRid(origRid)); - } + protected override uint? GetFieldOffset_NoLock() => + readerModule.TablesStream.ReadFieldLayoutRow2(readerModule.MetaData.GetFieldLayoutRid(origRid)); /// - protected override MarshalType GetMarshalType_NoLock() { - return readerModule.ReadMarshalType(Table.Field, origRid, new GenericParamContext(declaringType2)); - } + protected override MarshalType GetMarshalType_NoLock() => + readerModule.ReadMarshalType(Table.Field, origRid, new GenericParamContext(declaringType2)); /// protected override RVA GetRVA_NoLock() { - RVA rva2; - GetFieldRVA_NoLock(out rva2); + GetFieldRVA_NoLock(out var rva2); return rva2; } /// protected override byte[] GetInitialValue_NoLock() { - RVA rva2; - if (!GetFieldRVA_NoLock(out rva2)) + if (!GetFieldRVA_NoLock(out var rva2)) return null; return ReadInitialValue_NoLock(rva2); } /// - protected override ImplMap GetImplMap_NoLock() { - return readerModule.ResolveImplMap(readerModule.MetaData.GetImplMapRid(Table.Field, origRid)); - } + protected override ImplMap GetImplMap_NoLock() => + readerModule.ResolveImplMap(readerModule.MetaData.GetImplMapRid(Table.Field, origRid)); /// - protected override Constant GetConstant_NoLock() { - return readerModule.ResolveConstant(readerModule.MetaData.GetConstantRid(Table.Field, origRid)); - } + protected override Constant GetConstant_NoLock() => + readerModule.ResolveConstant(readerModule.MetaData.GetConstantRid(Table.Field, origRid)); /// /// Constructor @@ -958,16 +832,15 @@ public FieldDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.FieldTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Field rid {0} does not exist", rid)); + throw new BadImageFormatException($"Field rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint signature = readerModule.TablesStream.ReadFieldRow(origRid, out this.attributes, out name); + uint signature = readerModule.TablesStream.ReadFieldRow(origRid, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); - this.origAttributes = (FieldAttributes)attributes; - this.declaringType2 = readerModule.GetOwnerType(this); + origAttributes = (FieldAttributes)attributes; + declaringType2 = readerModule.GetOwnerType(this); this.signature = readerModule.ReadSignature(signature, new GenericParamContext(declaringType2)); } @@ -995,8 +868,7 @@ bool GetFieldRVA_NoLock(out RVA rva) { } byte[] ReadInitialValue_NoLock(RVA rva) { - uint size; - if (!GetFieldSize(declaringType2, signature as FieldSig, out size)) + if (!GetFieldSize(declaringType2, signature as FieldSig, out uint size)) return null; if (size >= int.MaxValue) return null; diff --git a/src/DotNet/FileDef.cs b/src/DotNet/FileDef.cs index aa1cf1d08..0204f5ea2 100644 --- a/src/DotNet/FileDef.cs +++ b/src/DotNet/FileDef.cs @@ -23,32 +23,26 @@ public abstract class FileDef : IHasCustomAttribute, IImplementation, IHasCustom protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.File, rid); } - } + public MDToken MDToken => new MDToken(Table.File, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 16; } - } + public int HasCustomAttributeTag => 16; /// - public int ImplementationTag { - get { return 0; } - } + public int ImplementationTag => 0; /// /// From column File.Flags /// public FileAttributes Flags { - get { return (FileAttributes)attributes; } - set { attributes = (int)value; } + get => (FileAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -57,8 +51,8 @@ public FileAttributes Flags { /// From column File.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -67,8 +61,8 @@ public UTF8String Name { /// From column File.HashValue /// public byte[] HashValue { - get { return hashValue; } - set { hashValue = value; } + get => hashValue; + set => hashValue = value; } /// protected byte[] hashValue; @@ -86,24 +80,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 16; } - } + public int HasCustomDebugInformationTag => 16; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -118,9 +105,8 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Set or clear flags in @@ -150,27 +136,23 @@ void ModifyAttributes(bool set, FileAttributes flags) { /// Gets/sets the bit /// public bool ContainsMetaData { - get { return ((FileAttributes)attributes & FileAttributes.ContainsNoMetaData) == 0; } - set { ModifyAttributes(!value, FileAttributes.ContainsNoMetaData); } + get => ((FileAttributes)attributes & FileAttributes.ContainsNoMetaData) == 0; + set => ModifyAttributes(!value, FileAttributes.ContainsNoMetaData); } /// /// Gets/sets the bit /// public bool ContainsNoMetaData { - get { return ((FileAttributes)attributes & FileAttributes.ContainsNoMetaData) != 0; } - set { ModifyAttributes(value, FileAttributes.ContainsNoMetaData); } + get => ((FileAttributes)attributes & FileAttributes.ContainsNoMetaData) != 0; + set => ModifyAttributes(value, FileAttributes.ContainsNoMetaData); } /// - public string FullName { - get { return UTF8String.ToSystemStringOrEmpty(name); } - } + public string FullName => UTF8String.ToSystemStringOrEmpty(name); /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -191,7 +173,7 @@ public FileDefUser() { /// File hash public FileDefUser(UTF8String name, FileAttributes flags, byte[] hashValue) { this.name = name; - this.attributes = (int)flags; + attributes = (int)flags; this.hashValue = hashValue; } } @@ -206,9 +188,7 @@ sealed class FileDefMD : FileDef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -236,13 +216,12 @@ public FileDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.FileTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("File rid {0} does not exist", rid)); + throw new BadImageFormatException($"File rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint hashValue = readerModule.TablesStream.ReadFileRow(origRid, out this.attributes, out name); + uint hashValue = readerModule.TablesStream.ReadFileRow(origRid, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); this.hashValue = readerModule.BlobStream.Read(hashValue); } diff --git a/src/DotNet/FrameworkRedirect.cs b/src/DotNet/FrameworkRedirect.cs index 602214b38..616504aff 100644 --- a/src/DotNet/FrameworkRedirect.cs +++ b/src/DotNet/FrameworkRedirect.cs @@ -11,7 +11,7 @@ public static class FrameworkRedirect { static readonly Dictionary frmRedir2; static readonly Dictionary frmRedir4; - struct FrameworkRedirectInfo { + readonly struct FrameworkRedirectInfo { public readonly PublicKeyToken publicKeyToken; public readonly Version redirectVersion; @@ -308,8 +308,7 @@ public static void ApplyFrameworkRedirect(ref IAssembly assembly, ModuleDef sour if (!sourceModule.IsClr20 && !sourceModule.IsClr40) return; - FrameworkRedirectInfo redirect; - if (!(sourceModule.IsClr20 ? frmRedir2 : frmRedir4).TryGetValue(assembly.Name, out redirect)) + if (!(sourceModule.IsClr20 ? frmRedir2 : frmRedir4).TryGetValue(assembly.Name, out var redirect)) return; if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) return; diff --git a/src/DotNet/FullNameCreator.cs b/src/DotNet/FullNameCreator.cs index e5b12fbc0..c5cc4942f 100644 --- a/src/DotNet/FullNameCreator.cs +++ b/src/DotNet/FullNameCreator.cs @@ -42,8 +42,7 @@ public struct FullNameCreator { /// or null /// true if the assembly name must be included, false otherwise public static bool MustUseAssemblyName(ModuleDef module, IType type) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return td.Module != module; var tr = type as TypeRef; @@ -66,9 +65,8 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type) { /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { - return FullNameSB(type, isReflection, helper, sb).ToString(); - } + public static string FullName(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) => + FullNameSB(type, isReflection, helper, sb).ToString(); /// /// Returns the full name of a @@ -79,20 +77,15 @@ public static string FullName(IType type, bool isReflection, IFullNameCreatorHel /// String builder to use or null /// The full name public static StringBuilder FullNameSB(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return FullNameSB(td, isReflection, helper, sb); - var tr = type as TypeRef; - if (tr != null) + if (type is TypeRef tr) return FullNameSB(tr, isReflection, helper, sb); - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return FullNameSB(ts, isReflection, helper, sb); - var sig = type as TypeSig; - if (sig != null) + if (type is TypeSig sig) return FullNameSB(sig, isReflection, helper, null, null, sb); - var et = type as ExportedType; - if (et != null) + if (type is ExportedType et) return FullNameSB(et, isReflection, helper, sb); return sb ?? new StringBuilder(); } @@ -104,9 +97,8 @@ public static StringBuilder FullNameSB(IType type, bool isReflection, IFullNameC /// Set if output should be compatible with reflection /// String builder to use or null /// The full name - public static string Name(IType type, bool isReflection, StringBuilder sb) { - return NameSB(type, isReflection, sb).ToString(); - } + public static string Name(IType type, bool isReflection, StringBuilder sb) => + NameSB(type, isReflection, sb).ToString(); /// /// Returns the name of a @@ -116,20 +108,15 @@ public static string Name(IType type, bool isReflection, StringBuilder sb) { /// String builder to use or null /// The full name public static StringBuilder NameSB(IType type, bool isReflection, StringBuilder sb) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return NameSB(td, isReflection, sb); - var tr = type as TypeRef; - if (tr != null) + if (type is TypeRef tr) return NameSB(tr, isReflection, sb); - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return NameSB(ts, isReflection, sb); - var sig = type as TypeSig; - if (sig != null) + if (type is TypeSig sig) return NameSB(sig, false, sb); - var et = type as ExportedType; - if (et != null) + if (type is ExportedType et) return NameSB(et, isReflection, sb); return sb ?? new StringBuilder(); } @@ -141,9 +128,8 @@ public static StringBuilder NameSB(IType type, bool isReflection, StringBuilder /// Set if output should be compatible with reflection /// String builder to use or null /// The full name - public static string Namespace(IType type, bool isReflection, StringBuilder sb) { - return NamespaceSB(type, isReflection, sb).ToString(); - } + public static string Namespace(IType type, bool isReflection, StringBuilder sb) => + NamespaceSB(type, isReflection, sb).ToString(); /// /// Returns the namespace of a @@ -153,20 +139,15 @@ public static string Namespace(IType type, bool isReflection, StringBuilder sb) /// String builder to use or null /// The full name public static StringBuilder NamespaceSB(IType type, bool isReflection, StringBuilder sb) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return NamespaceSB(td, isReflection, sb); - var tr = type as TypeRef; - if (tr != null) + if (type is TypeRef tr) return NamespaceSB(tr, isReflection, sb); - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return NamespaceSB(ts, isReflection, sb); - var sig = type as TypeSig; - if (sig != null) + if (type is TypeSig sig) return NamespaceSB(sig, false, sb); - var et = type as ExportedType; - if (et != null) + if (type is ExportedType et) return NamespaceSB(et, isReflection, sb); return sb ?? new StringBuilder(); } @@ -178,9 +159,8 @@ public static StringBuilder NamespaceSB(IType type, bool isReflection, StringBui /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return AssemblyQualifiedNameSB(type, helper, sb).ToString(); - } + public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + AssemblyQualifiedNameSB(type, helper, sb).ToString(); /// /// Returns the assembly qualified full name of a @@ -190,24 +170,19 @@ public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper he /// String builder to use or null /// The assembly qualified full name public static StringBuilder AssemblyQualifiedNameSB(IType type, IFullNameCreatorHelper helper, StringBuilder sb) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return AssemblyQualifiedNameSB(td, helper, sb); - var tr = type as TypeRef; - if (tr != null) + if (type is TypeRef tr) return AssemblyQualifiedNameSB(tr, helper, sb); - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return AssemblyQualifiedNameSB(ts, helper, sb); - var sig = type as TypeSig; - if (sig != null) + if (type is TypeSig sig) return AssemblyQualifiedNameSB(sig, helper, sb); - var et = type as ExportedType; - if (et != null) + if (type is ExportedType et) return AssemblyQualifiedNameSB(et, helper, sb); return sb ?? new StringBuilder(); @@ -222,9 +197,8 @@ public static StringBuilder AssemblyQualifiedNameSB(IType type, IFullNameCreator /// Type generic arguments or null if none /// String builder to use or null /// Property full name - public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs = null, StringBuilder sb = null) { - return PropertyFullNameSB(declaringType, name, propertySig, typeGenArgs, sb).ToString(); - } + public static string PropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs = null, StringBuilder sb = null) => + PropertyFullNameSB(declaringType, name, propertySig, typeGenArgs, sb).ToString(); /// /// Returns the full name of a property @@ -255,9 +229,8 @@ public static StringBuilder PropertyFullNameSB(string declaringType, UTF8String /// Type generic arguments or null if none /// String builder to use or null /// Property full name - public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs = null, StringBuilder sb = null) { - return EventFullNameSB(declaringType, name, typeDefOrRef, typeGenArgs, sb).ToString(); - } + public static string EventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs = null, StringBuilder sb = null) => + EventFullNameSB(declaringType, name, typeDefOrRef, typeGenArgs, sb).ToString(); /// /// Returns the full name of a property @@ -288,9 +261,8 @@ public static StringBuilder EventFullNameSB(string declaringType, UTF8String nam /// Type generic arguments or null if none /// String builder to use or null /// Field full name - public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs = null, StringBuilder sb = null) { - return FieldFullNameSB(declaringType, name, fieldSig, typeGenArgs, sb).ToString(); - } + public static string FieldFullName(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs = null, StringBuilder sb = null) => + FieldFullNameSB(declaringType, name, fieldSig, typeGenArgs, sb).ToString(); /// /// Returns the full name of a field @@ -323,9 +295,8 @@ public static StringBuilder FieldFullNameSB(string declaringType, string name, F /// Generic parameter owner method or null /// String builder to use or null /// Method full name - public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs = null, IList methodGenArgs = null, MethodDef gppMethod = null, StringBuilder sb = null) { - return MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, gppMethod, sb).ToString(); - } + public static string MethodFullName(string declaringType, string name, MethodSig methodSig, IList typeGenArgs = null, IList methodGenArgs = null, MethodDef gppMethod = null, StringBuilder sb = null) => + MethodFullNameSB(declaringType, name, methodSig, typeGenArgs, methodGenArgs, gppMethod, sb).ToString(); /// /// Returns the full name of a method @@ -356,9 +327,8 @@ public static StringBuilder MethodFullNameSB(string declaringType, string name, /// Property sig /// String builder to use or null /// Property sig full name - public static string MethodBaseSigFullName(MethodBaseSig sig, StringBuilder sb = null) { - return MethodBaseSigFullNameSB(sig, sb).ToString(); - } + public static string MethodBaseSigFullName(MethodBaseSig sig, StringBuilder sb = null) => + MethodBaseSigFullNameSB(sig, sb).ToString(); /// /// Returns the full name of a property sig @@ -381,9 +351,8 @@ public static StringBuilder MethodBaseSigFullNameSB(MethodBaseSig sig, StringBui /// Owner method or null /// String builder to use or null /// Sig full name - public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb = null) { - return MethodBaseSigFullNameSB(declType, name, sig, gppMethod, sb).ToString(); - } + public static string MethodBaseSigFullName(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb = null) => + MethodBaseSigFullNameSB(declType, name, sig, gppMethod, sb).ToString(); /// /// Returns the full name of a sig @@ -407,9 +376,8 @@ public static StringBuilder MethodBaseSigFullNameSB(string declType, string name /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder sb = null) { - return NamespaceSB(typeRef, isReflection, sb).ToString(); - } + public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder sb = null) => + NamespaceSB(typeRef, isReflection, sb).ToString(); /// /// Returns the namespace of a @@ -431,9 +399,8 @@ public static StringBuilder NamespaceSB(TypeRef typeRef, bool isReflection, Stri /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb = null) { - return NameSB(typeRef, isReflection, sb).ToString(); - } + public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb = null) => + NameSB(typeRef, isReflection, sb).ToString(); /// /// Returns the name of a @@ -456,9 +423,8 @@ public static StringBuilder NameSB(TypeRef typeRef, bool isReflection, StringBui /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return FullNameSB(typeRef, isReflection, helper, sb).ToString(); - } + public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + FullNameSB(typeRef, isReflection, helper, sb).ToString(); /// /// Returns the full name of a @@ -481,9 +447,8 @@ public static StringBuilder FullNameSB(TypeRef typeRef, bool isReflection, IFull /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return AssemblyQualifiedNameSB(typeRef, helper, sb).ToString(); - } + public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + AssemblyQualifiedNameSB(typeRef, helper, sb).ToString(); /// /// Returns the assembly qualified full name of a @@ -503,27 +468,24 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeRef typeRef, IFullNameCr /// /// The TypeRef /// A or null if none found - public static IAssembly DefinitionAssembly(TypeRef typeRef) { - return new FullNameCreator().GetDefinitionAssembly(typeRef); - } + public static IAssembly DefinitionAssembly(TypeRef typeRef) => + new FullNameCreator().GetDefinitionAssembly(typeRef); /// /// Gets the scope /// /// The TypeRef /// The or null if none found - public static IScope Scope(TypeRef typeRef) { - return new FullNameCreator().GetScope(typeRef); - } + public static IScope Scope(TypeRef typeRef) => + new FullNameCreator().GetScope(typeRef); /// /// Returns the owner module. The type was created from metadata in this module. /// /// The TypeRef /// A or null if none found - public static ModuleDef OwnerModule(TypeRef typeRef) { - return new FullNameCreator().GetOwnerModule(typeRef); - } + public static ModuleDef OwnerModule(TypeRef typeRef) => + new FullNameCreator().GetOwnerModule(typeRef); /// /// Returns the namespace of a @@ -532,9 +494,8 @@ public static ModuleDef OwnerModule(TypeRef typeRef) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder sb = null) { - return NamespaceSB(typeDef, isReflection, sb).ToString(); - } + public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder sb = null) => + NamespaceSB(typeDef, isReflection, sb).ToString(); /// /// Returns the namespace of a @@ -556,9 +517,8 @@ public static StringBuilder NamespaceSB(TypeDef typeDef, bool isReflection, Stri /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeDef typeDef, bool isReflection, StringBuilder sb = null) { - return NameSB(typeDef, isReflection, sb).ToString(); - } + public static string Name(TypeDef typeDef, bool isReflection, StringBuilder sb = null) => + NameSB(typeDef, isReflection, sb).ToString(); /// /// Returns the name of a @@ -581,9 +541,8 @@ public static StringBuilder NameSB(TypeDef typeDef, bool isReflection, StringBui /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return FullNameSB(typeDef, isReflection, helper, sb).ToString(); - } + public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + FullNameSB(typeDef, isReflection, helper, sb).ToString(); /// /// Returns the full name of a @@ -606,9 +565,8 @@ public static StringBuilder FullNameSB(TypeDef typeDef, bool isReflection, IFull /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return AssemblyQualifiedNameSB(typeDef, helper, sb).ToString(); - } + public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + AssemblyQualifiedNameSB(typeDef, helper, sb).ToString(); /// /// Returns the assembly qualified full name of a @@ -628,18 +586,16 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeDef typeDef, IFullNameCr /// /// The TypeDef /// A or null if none found - public static IAssembly DefinitionAssembly(TypeDef typeDef) { - return new FullNameCreator().GetDefinitionAssembly(typeDef); - } + public static IAssembly DefinitionAssembly(TypeDef typeDef) => + new FullNameCreator().GetDefinitionAssembly(typeDef); /// /// Returns the owner module. The type was created from metadata in this module. /// /// The TypeDef /// A or null if none found - public static ModuleDef OwnerModule(TypeDef typeDef) { - return new FullNameCreator().GetOwnerModule(typeDef); - } + public static ModuleDef OwnerModule(TypeDef typeDef) => + new FullNameCreator().GetOwnerModule(typeDef); /// /// Returns the namespace of a @@ -648,9 +604,8 @@ public static ModuleDef OwnerModule(TypeDef typeDef) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuilder sb = null) { - return NamespaceSB(typeSpec, isReflection, sb).ToString(); - } + public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuilder sb = null) => + NamespaceSB(typeSpec, isReflection, sb).ToString(); /// /// Returns the namespace of a @@ -672,9 +627,8 @@ public static StringBuilder NamespaceSB(TypeSpec typeSpec, bool isReflection, St /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeSpec typeSpec, bool isReflection, StringBuilder sb = null) { - return NameSB(typeSpec, isReflection, sb).ToString(); - } + public static string Name(TypeSpec typeSpec, bool isReflection, StringBuilder sb = null) => + NameSB(typeSpec, isReflection, sb).ToString(); /// /// Returns the name of a @@ -697,9 +651,8 @@ public static StringBuilder NameSB(TypeSpec typeSpec, bool isReflection, StringB /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return FullNameSB(typeSpec, isReflection, helper, sb).ToString(); - } + public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + FullNameSB(typeSpec, isReflection, helper, sb).ToString(); /// /// Returns the full name of a @@ -722,9 +675,8 @@ public static StringBuilder FullNameSB(TypeSpec typeSpec, bool isReflection, IFu /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return AssemblyQualifiedNameSB(typeSpec, helper, sb).ToString(); - } + public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + AssemblyQualifiedNameSB(typeSpec, helper, sb).ToString(); /// /// Returns the assembly qualified full name of a @@ -744,36 +696,32 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeSpec typeSpec, IFullName /// /// The TypeSpec /// A or null if none found - public static IAssembly DefinitionAssembly(TypeSpec typeSpec) { - return new FullNameCreator().GetDefinitionAssembly(typeSpec); - } + public static IAssembly DefinitionAssembly(TypeSpec typeSpec) => + new FullNameCreator().GetDefinitionAssembly(typeSpec); /// /// Gets the scope type /// /// The TypeSpec /// The scope type or null if none found - public static ITypeDefOrRef ScopeType(TypeSpec typeSpec) { - return new FullNameCreator().GetScopeType(typeSpec); - } + public static ITypeDefOrRef ScopeType(TypeSpec typeSpec) => + new FullNameCreator().GetScopeType(typeSpec); /// /// Gets the scope /// /// The TypeSpec /// The or null if none found - public static IScope Scope(TypeSpec typeSpec) { - return new FullNameCreator().GetScope(typeSpec); - } + public static IScope Scope(TypeSpec typeSpec) => + new FullNameCreator().GetScope(typeSpec); /// /// Returns the owner module. The type was created from metadata in this module. /// /// The TypeSpec /// A or null if none found - public static ModuleDef OwnerModule(TypeSpec typeSpec) { - return new FullNameCreator().GetOwnerModule(typeSpec); - } + public static ModuleDef OwnerModule(TypeSpec typeSpec) => + new FullNameCreator().GetOwnerModule(typeSpec); /// /// Returns the namespace of a @@ -782,9 +730,8 @@ public static ModuleDef OwnerModule(TypeSpec typeSpec) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder sb = null) { - return NamespaceSB(typeSig, isReflection, sb).ToString(); - } + public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder sb = null) => + NamespaceSB(typeSig, isReflection, sb).ToString(); /// /// Returns the namespace of a @@ -806,9 +753,8 @@ public static StringBuilder NamespaceSB(TypeSig typeSig, bool isReflection, Stri /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(TypeSig typeSig, bool isReflection, StringBuilder sb = null) { - return NameSB(typeSig, isReflection, sb).ToString(); - } + public static string Name(TypeSig typeSig, bool isReflection, StringBuilder sb = null) => + NameSB(typeSig, isReflection, sb).ToString(); /// /// Returns the name of a @@ -833,9 +779,8 @@ public static StringBuilder NameSB(TypeSig typeSig, bool isReflection, StringBui /// Method generic args or null if none /// String builder to use or null /// The full name - public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper = null, IList typeGenArgs = null, IList methodGenArgs = null, StringBuilder sb = null) { - return FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, sb).ToString(); - } + public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper = null, IList typeGenArgs = null, IList methodGenArgs = null, StringBuilder sb = null) => + FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, sb).ToString(); /// /// Returns the full name of a @@ -866,9 +811,8 @@ public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFull /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return AssemblyQualifiedNameSB(typeSig, helper, sb).ToString(); - } + public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + AssemblyQualifiedNameSB(typeSig, helper, sb).ToString(); /// /// Returns the assembly qualified full name of a @@ -888,36 +832,32 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeSig typeSig, IFullNameCr /// /// The TypeSig /// A or null if none found - public static IAssembly DefinitionAssembly(TypeSig typeSig) { - return new FullNameCreator().GetDefinitionAssembly(typeSig); - } + public static IAssembly DefinitionAssembly(TypeSig typeSig) => + new FullNameCreator().GetDefinitionAssembly(typeSig); /// /// Gets the scope /// /// The TypeSig /// The or null if none found - public static IScope Scope(TypeSig typeSig) { - return new FullNameCreator().GetScope(typeSig); - } + public static IScope Scope(TypeSig typeSig) => + new FullNameCreator().GetScope(typeSig); /// /// Gets the scope type /// /// The TypeSig /// The scope type or null if none found - public static ITypeDefOrRef ScopeType(TypeSig typeSig) { - return new FullNameCreator().GetScopeType(typeSig); - } + public static ITypeDefOrRef ScopeType(TypeSig typeSig) => + new FullNameCreator().GetScopeType(typeSig); /// /// Returns the owner module. The type was created from metadata in this module. /// /// The TypeSig /// A or null if none found - public static ModuleDef OwnerModule(TypeSig typeSig) { - return new FullNameCreator().GetOwnerModule(typeSig); - } + public static ModuleDef OwnerModule(TypeSig typeSig) => + new FullNameCreator().GetOwnerModule(typeSig); /// /// Returns the namespace of a @@ -926,9 +866,8 @@ public static ModuleDef OwnerModule(TypeSig typeSig) { /// Set if output should be compatible with reflection /// String builder to use or null /// The namespace - public static string Namespace(ExportedType exportedType, bool isReflection, StringBuilder sb = null) { - return NamespaceSB(exportedType, isReflection, sb).ToString(); - } + public static string Namespace(ExportedType exportedType, bool isReflection, StringBuilder sb = null) => + NamespaceSB(exportedType, isReflection, sb).ToString(); /// /// Returns the namespace of a @@ -950,9 +889,8 @@ public static StringBuilder NamespaceSB(ExportedType exportedType, bool isReflec /// Set if output should be compatible with reflection /// String builder to use or null /// The name - public static string Name(ExportedType exportedType, bool isReflection, StringBuilder sb = null) { - return NameSB(exportedType, isReflection, sb).ToString(); - } + public static string Name(ExportedType exportedType, bool isReflection, StringBuilder sb = null) => + NameSB(exportedType, isReflection, sb).ToString(); /// /// Returns the name of a @@ -975,9 +913,8 @@ public static StringBuilder NameSB(ExportedType exportedType, bool isReflection, /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return FullNameSB(exportedType, isReflection, helper, sb).ToString(); - } + public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + FullNameSB(exportedType, isReflection, helper, sb).ToString(); /// /// Returns the full name of a @@ -1000,9 +937,8 @@ public static StringBuilder FullNameSB(ExportedType exportedType, bool isReflect /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper = null, StringBuilder sb = null) { - return AssemblyQualifiedNameSB(exportedType, helper, sb).ToString(); - } + public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + AssemblyQualifiedNameSB(exportedType, helper, sb).ToString(); /// /// Returns the assembly qualified full name of a @@ -1022,47 +958,41 @@ public static StringBuilder AssemblyQualifiedNameSB(ExportedType exportedType, I /// /// The ExportedType /// A or null if none found - public static IAssembly DefinitionAssembly(ExportedType exportedType) { - return new FullNameCreator().GetDefinitionAssembly(exportedType); - } + public static IAssembly DefinitionAssembly(ExportedType exportedType) => + new FullNameCreator().GetDefinitionAssembly(exportedType); /// /// Gets the scope type /// /// The ExportedType /// The scope type or null if none found - public static ITypeDefOrRef ScopeType(ExportedType exportedType) { - return new FullNameCreator().GetScopeType(exportedType); - } + public static ITypeDefOrRef ScopeType(ExportedType exportedType) => + new FullNameCreator().GetScopeType(exportedType); /// /// Gets the scope /// /// The ExportedType /// The or null if none found - public static IScope Scope(ExportedType exportedType) { - return new FullNameCreator().GetScope(exportedType); - } + public static IScope Scope(ExportedType exportedType) => + new FullNameCreator().GetScope(exportedType); /// /// Returns the owner module. The type was created from metadata in this module. /// /// The ExportedType /// A or null if none found - public static ModuleDef OwnerModule(ExportedType exportedType) { - return new FullNameCreator().GetOwnerModule(exportedType); - } + public static ModuleDef OwnerModule(ExportedType exportedType) => + new FullNameCreator().GetOwnerModule(exportedType); - string Result { - get { return sb == null ? null : sb.ToString(); } - } + string Result => sb?.ToString(); FullNameCreator(bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { this.sb = sb ?? new StringBuilder(); this.isReflection = isReflection; this.helper = helper; - this.genericArguments = null; - this.recursionCounter = new RecursionCounter(); + genericArguments = null; + recursionCounter = new RecursionCounter(); } bool MustUseAssemblyName(IType type) { @@ -1075,15 +1005,12 @@ IType GetDefinitionType(IType type) { if (!recursionCounter.Increment()) return type; - TypeSpec ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) type = ts.TypeSig; - TypeSig sig = type as TypeSig; - if (sig != null) { - TypeDefOrRefSig tdr; + if (type is TypeSig sig) { GenericInstSig gis; - if ((tdr = sig as TypeDefOrRefSig) != null) + if (sig is TypeDefOrRefSig tdr) type = GetDefinitionType(tdr.TypeDefOrRef); else if ((gis = sig as GenericInstSig) != null) type = GetDefinitionType(gis.GenericType); @@ -1166,8 +1093,7 @@ void CreateFullName(TypeRef typeRef) { return; } - var declaringTypeRef = typeRef.ResolutionScope as TypeRef; - if (declaringTypeRef != null) { + if (typeRef.ResolutionScope is TypeRef declaringTypeRef) { CreateFullName(declaringTypeRef); AddNestedTypeSeparator(); } @@ -1301,17 +1227,9 @@ void CreateAssemblyQualifiedName(TypeSig typeSig) { recursionCounter.Decrement(); } - void CreateFullName(TypeSig typeSig) { - CreateTypeSigName(typeSig, TYPESIG_NAMESPACE | TYPESIG_NAME); - } - - void CreateNamespace(TypeSig typeSig) { - CreateTypeSigName(typeSig, TYPESIG_NAMESPACE); - } - - void CreateName(TypeSig typeSig) { - CreateTypeSigName(typeSig, TYPESIG_NAME); - } + void CreateFullName(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAMESPACE | TYPESIG_NAME); + void CreateNamespace(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAMESPACE); + void CreateName(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAME); TypeSig ReplaceGenericArg(TypeSig typeSig) { if (genericArguments == null) @@ -1573,8 +1491,7 @@ void CreateFullName(ExportedType exportedType) { return; } - var declaringExportedType = exportedType.Implementation as ExportedType; - if (declaringExportedType != null) { + if (exportedType.Implementation is ExportedType declaringExportedType) { CreateFullName(declaringExportedType); AddNestedTypeSeparator(); } @@ -1609,9 +1526,8 @@ static string GetAssemblyName(IAssembly assembly) { return Utils.GetAssemblyNameString(EscapeAssemblyName(assembly.Name), assembly.Version, assembly.Culture, pk, assembly.Attributes); } - static string EscapeAssemblyName(UTF8String asmSimplName) { - return EscapeAssemblyName(UTF8String.ToSystemString(asmSimplName)); - } + static string EscapeAssemblyName(UTF8String asmSimplName) => + EscapeAssemblyName(UTF8String.ToSystemString(asmSimplName)); static string EscapeAssemblyName(string asmSimplName) { var sb = new StringBuilder(asmSimplName.Length); @@ -1679,64 +1595,52 @@ void AddIdentifier(string id) { } IAssembly GetDefinitionAssembly(ITypeDefOrRef typeDefOrRef) { - var tr = typeDefOrRef as TypeRef; - if (tr != null) + if (typeDefOrRef is TypeRef tr) return GetDefinitionAssembly(tr); - var td = typeDefOrRef as TypeDef; - if (td != null) + if (typeDefOrRef is TypeDef td) return GetDefinitionAssembly(td); - var ts = typeDefOrRef as TypeSpec; - if (ts != null) + if (typeDefOrRef is TypeSpec ts) return GetDefinitionAssembly(ts); return null; } IScope GetScope(ITypeDefOrRef typeDefOrRef) { - var tr = typeDefOrRef as TypeRef; - if (tr != null) + if (typeDefOrRef is TypeRef tr) return GetScope(tr); - var td = typeDefOrRef as TypeDef; - if (td != null) + if (typeDefOrRef is TypeDef td) return td.Scope; - var ts = typeDefOrRef as TypeSpec; - if (ts != null) + if (typeDefOrRef is TypeSpec ts) return GetScope(ts); return null; } ITypeDefOrRef GetScopeType(ITypeDefOrRef typeDefOrRef) { - var tr = typeDefOrRef as TypeRef; - if (tr != null) + if (typeDefOrRef is TypeRef tr) return tr; - var td = typeDefOrRef as TypeDef; - if (td != null) + if (typeDefOrRef is TypeDef td) return td; - var ts = typeDefOrRef as TypeSpec; - if (ts != null) + if (typeDefOrRef is TypeSpec ts) return GetScopeType(ts); return null; } ModuleDef GetOwnerModule(ITypeDefOrRef typeDefOrRef) { - var tr = typeDefOrRef as TypeRef; - if (tr != null) + if (typeDefOrRef is TypeRef tr) return GetOwnerModule(tr); - var td = typeDefOrRef as TypeDef; - if (td != null) + if (typeDefOrRef is TypeDef td) return GetOwnerModule(td); - var ts = typeDefOrRef as TypeSpec; - if (ts != null) + if (typeDefOrRef is TypeSpec ts) return GetOwnerModule(ts); return null; @@ -1758,7 +1662,7 @@ IAssembly GetDefinitionAssembly(TypeRef typeRef) { result = (AssemblyRef)scope; else if (scope is ModuleRef) { var ownerModule = GetOwnerModule(typeRef); - result = ownerModule == null ? null : ownerModule.Assembly; + result = ownerModule?.Assembly; } else if (scope is ModuleDef) result = ((ModuleDef)scope).Assembly; @@ -1804,10 +1708,7 @@ ModuleDef GetOwnerModule(TypeRef typeRef) { return typeRef.Module; } - IAssembly GetDefinitionAssembly(TypeDef typeDef) { - var ownerModule = GetOwnerModule(typeDef); - return ownerModule == null ? null : ownerModule.Assembly; - } + IAssembly GetDefinitionAssembly(TypeDef typeDef) => GetOwnerModule(typeDef)?.Assembly; ModuleDef GetOwnerModule(TypeDef typeDef) { if (typeDef == null) @@ -1899,7 +1800,7 @@ IAssembly GetDefinitionAssembly(TypeSig typeSig) { case ElementType.GenericInst: var genericInstSig = (GenericInstSig)typeSig; var genericType = genericInstSig.GenericType; - result = GetDefinitionAssembly(genericType == null ? null : genericType.TypeDefOrRef); + result = GetDefinitionAssembly(genericType?.TypeDefOrRef); break; case ElementType.Var: @@ -1966,9 +1867,7 @@ ITypeDefOrRef GetScopeType(TypeSig typeSig) { break; case ElementType.GenericInst: - var genericInstSig = (GenericInstSig)typeSig; - var genericType = genericInstSig.GenericType; - result = GetScopeType(genericType == null ? null : genericType.TypeDefOrRef); + result = GetScopeType(((GenericInstSig)typeSig).GenericType?.TypeDefOrRef); break; case ElementType.Var: @@ -2035,9 +1934,7 @@ IScope GetScope(TypeSig typeSig) { break; case ElementType.GenericInst: - var genericInstSig = (GenericInstSig)typeSig; - var genericType = genericInstSig.GenericType; - result = GetScope(genericType == null ? null : genericType.TypeDefOrRef); + result = GetScope(((GenericInstSig)typeSig).GenericType?.TypeDefOrRef); break; case ElementType.Var: @@ -2104,9 +2001,7 @@ ModuleDef GetOwnerModule(TypeSig typeSig) { break; case ElementType.GenericInst: - var genericInstSig = (GenericInstSig)typeSig; - var genericType = genericInstSig.GenericType; - result = GetOwnerModule(genericType == null ? null : genericType.TypeDefOrRef); + result = GetOwnerModule(((GenericInstSig)typeSig).GenericType?.TypeDefOrRef); break; case ElementType.Var: @@ -2132,17 +2027,16 @@ IAssembly GetDefinitionAssembly(ExportedType exportedType) { if (!recursionCounter.Increment()) return null; IAssembly result; - ExportedType et; AssemblyRef asmRef; var scope = exportedType.Implementation; - if ((et = scope as ExportedType) != null) + if (scope is ExportedType et) result = GetDefinitionAssembly(et); else if ((asmRef = scope as AssemblyRef) != null) result = asmRef; else if (scope is FileDef) { var ownerModule = GetOwnerModule(exportedType); - result = ownerModule == null ? null : ownerModule.Assembly; + result = ownerModule?.Assembly; } else result = null; @@ -2151,9 +2045,7 @@ IAssembly GetDefinitionAssembly(ExportedType exportedType) { return result; } - ITypeDefOrRef GetScopeType(ExportedType exportedType) { - return null; - } + ITypeDefOrRef GetScopeType(ExportedType exportedType) => null; IScope GetScope(ExportedType exportedType) { if (exportedType == null) @@ -2161,12 +2053,11 @@ IScope GetScope(ExportedType exportedType) { if (!recursionCounter.Increment()) return null; IScope result; - ExportedType et; AssemblyRef asmRef; FileDef file; var scope = exportedType.Implementation; - if ((et = scope as ExportedType) != null) + if (scope is ExportedType et) result = GetScope(et); else if ((asmRef = scope as AssemblyRef) != null) result = asmRef; @@ -2192,7 +2083,7 @@ ModuleDef GetOwnerModule(ExportedType exportedType) { } void CreateFieldFullName(string declaringType, string name, FieldSig fieldSig) { - CreateFullName(fieldSig == null ? null : fieldSig.Type); + CreateFullName(fieldSig?.Type); sb.Append(' '); if (declaringType != null) { @@ -2254,9 +2145,8 @@ int PrintMethodArgList(IEnumerable args, bool hasPrintedArgs, bool isAf return count; } - void CreatePropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig) { + void CreatePropertyFullName(string declaringType, UTF8String name, CallingConventionSig propertySig) => CreateMethodFullName(declaringType, UTF8String.ToSystemString(name), propertySig as MethodBaseSig, null); - } void CreateEventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef) { CreateFullName(typeDefOrRef); @@ -2270,8 +2160,6 @@ void CreateEventFullName(string declaringType, UTF8String name, ITypeDefOrRef ty } /// - public override string ToString() { - return Result; - } + public override string ToString() => Result; } } diff --git a/src/DotNet/GenericArguments.cs b/src/DotNet/GenericArguments.cs index 92a76c7f3..d71295095 100644 --- a/src/DotNet/GenericArguments.cs +++ b/src/DotNet/GenericArguments.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace dnlib.DotNet { - struct GenericArgumentsStack { + readonly struct GenericArgumentsStack { readonly List> argsStack; readonly bool isTypeVar; @@ -12,7 +12,7 @@ struct GenericArgumentsStack { /// /// true if it's for generic types, false if generic methods public GenericArgumentsStack(bool isTypeVar) { - this.argsStack = new List>(); + argsStack = new List>(); this.isTypeVar = isTypeVar; } @@ -20,9 +20,7 @@ public GenericArgumentsStack(bool isTypeVar) { /// Pushes generic arguments /// /// The generic arguments - public void Push(IList args) { - argsStack.Add(args); - } + public void Push(IList args) => argsStack.Add(args); /// /// Pops generic arguments @@ -68,33 +66,25 @@ public sealed class GenericArguments { /// Pushes generic arguments /// /// The generic arguments - public void PushTypeArgs(IList typeArgs) { - typeArgsStack.Push(typeArgs); - } + public void PushTypeArgs(IList typeArgs) => typeArgsStack.Push(typeArgs); /// /// Pops generic arguments /// /// The popped generic arguments - public IList PopTypeArgs() { - return typeArgsStack.Pop(); - } + public IList PopTypeArgs() => typeArgsStack.Pop(); /// /// Pushes generic arguments /// /// The generic arguments - public void PushMethodArgs(IList methodArgs) { - methodArgsStack.Push(methodArgs); - } + public void PushMethodArgs(IList methodArgs) => methodArgsStack.Push(methodArgs); /// /// Pops generic arguments /// /// The popped generic arguments - public IList PopMethodArgs() { - return methodArgsStack.Pop(); - } + public IList PopMethodArgs() => methodArgsStack.Pop(); /// /// Replaces a generic type/method var with its generic argument (if any). If @@ -110,16 +100,14 @@ public TypeSig Resolve(TypeSig typeSig) { var sig = typeSig; - var genericMVar = sig as GenericMVar; - if (genericMVar != null) { + if (sig is GenericMVar genericMVar) { var newSig = methodArgsStack.Resolve(genericMVar.Number); if (newSig == null || newSig == sig) return sig; return newSig; } - var genericVar = sig as GenericVar; - if (genericVar != null) { + if (sig is GenericVar genericVar) { var newSig = typeArgsStack.Resolve(genericVar.Number); if (newSig == null || newSig == sig) return sig; diff --git a/src/DotNet/GenericParam.cs b/src/DotNet/GenericParam.cs index 69b1a0b54..b1ee3d2de 100644 --- a/src/DotNet/GenericParam.cs +++ b/src/DotNet/GenericParam.cs @@ -26,27 +26,23 @@ public abstract class GenericParam : IHasCustomAttribute, IHasCustomDebugInforma protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.GenericParam, rid); } - } + public MDToken MDToken => new MDToken(Table.GenericParam, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 19; } - } + public int HasCustomAttributeTag => 19; /// /// Gets the owner type/method /// public ITypeOrMethodDef Owner { - get { return owner; } - internal set { owner = value; } + get => owner; + internal set => owner = value; } /// protected ITypeOrMethodDef owner; @@ -55,29 +51,23 @@ public ITypeOrMethodDef Owner { /// Gets the declaring type or null if none or if is /// not a /// - public TypeDef DeclaringType { - get { return owner as TypeDef; } - } + public TypeDef DeclaringType => owner as TypeDef; /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return owner as TypeDef; } - } + ITypeDefOrRef IMemberRef.DeclaringType => owner as TypeDef; /// /// Gets the declaring method or null if none or if is /// not a /// - public MethodDef DeclaringMethod { - get { return owner as MethodDef; } - } + public MethodDef DeclaringMethod => owner as MethodDef; /// /// From column GenericParam.Number /// public ushort Number { - get { return number; } - set { number = value; } + get => number; + set => number = value; } /// protected ushort number; @@ -86,8 +76,8 @@ public ushort Number { /// From column GenericParam.Flags /// public GenericParamAttributes Flags { - get { return (GenericParamAttributes)attributes; } - set { attributes = (int)value; } + get => (GenericParamAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -96,8 +86,8 @@ public GenericParamAttributes Flags { /// From column GenericParam.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -106,8 +96,8 @@ public UTF8String Name { /// From column GenericParam.Kind (v1.1 only) /// public ITypeDefOrRef Kind { - get { return kind; } - set { kind = value; } + get => kind; + set => kind = value; } /// protected ITypeDefOrRef kind; @@ -125,9 +115,8 @@ public ThreadSafe.IList GenericParamConstraints { /// protected LazyList genericParamConstraints; /// Initializes - protected virtual void InitializeGenericParamConstraints() { + protected virtual void InitializeGenericParamConstraints() => Interlocked.CompareExchange(ref genericParamConstraints, new LazyList(this), null); - } /// /// Gets all custom attributes @@ -142,24 +131,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 19; } - } + public int HasCustomDebugInformationTag => 19; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -174,81 +156,33 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// true if is not empty /// - public bool HasGenericParamConstraints { - get { return GenericParamConstraints.Count > 0; } - } + public bool HasGenericParamConstraints => GenericParamConstraints.Count > 0; /// - public ModuleDef Module { - get { - var dt = owner; - return dt == null ? null : dt.Module; - } - } + public ModuleDef Module => owner?.Module; /// - public string FullName { - get { return UTF8String.ToSystemStringOrEmpty(name); } - } - - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return true; } - } + public string FullName => UTF8String.ToSystemStringOrEmpty(name); + + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => true; /// /// Modify property: = @@ -296,74 +230,64 @@ void ModifyAttributes(bool set, GenericParamAttributes flags) { /// Gets/sets variance (non, contra, co) /// public GenericParamAttributes Variance { - get { return (GenericParamAttributes)attributes & GenericParamAttributes.VarianceMask; } - set { ModifyAttributes(~GenericParamAttributes.VarianceMask, value & GenericParamAttributes.VarianceMask); } + get => (GenericParamAttributes)attributes & GenericParamAttributes.VarianceMask; + set => ModifyAttributes(~GenericParamAttributes.VarianceMask, value & GenericParamAttributes.VarianceMask); } /// /// true if is set /// - public bool IsNonVariant { - get { return Variance == GenericParamAttributes.NonVariant; } - } + public bool IsNonVariant => Variance == GenericParamAttributes.NonVariant; /// /// true if is set /// - public bool IsCovariant { - get { return Variance == GenericParamAttributes.Covariant; } - } + public bool IsCovariant => Variance == GenericParamAttributes.Covariant; /// /// true if is set /// - public bool IsContravariant { - get { return Variance == GenericParamAttributes.Contravariant; } - } + public bool IsContravariant => Variance == GenericParamAttributes.Contravariant; /// /// Gets/sets the special constraint /// public GenericParamAttributes SpecialConstraint { - get { return (GenericParamAttributes)attributes & GenericParamAttributes.SpecialConstraintMask; } - set { ModifyAttributes(~GenericParamAttributes.SpecialConstraintMask, value & GenericParamAttributes.SpecialConstraintMask); } + get => (GenericParamAttributes)attributes & GenericParamAttributes.SpecialConstraintMask; + set => ModifyAttributes(~GenericParamAttributes.SpecialConstraintMask, value & GenericParamAttributes.SpecialConstraintMask); } /// /// true if there are no special constraints /// - public bool HasNoSpecialConstraint { - get { return ((GenericParamAttributes)attributes & GenericParamAttributes.SpecialConstraintMask) == GenericParamAttributes.NoSpecialConstraint; } - } + public bool HasNoSpecialConstraint => ((GenericParamAttributes)attributes & GenericParamAttributes.SpecialConstraintMask) == GenericParamAttributes.NoSpecialConstraint; /// /// Gets/sets the bit /// public bool HasReferenceTypeConstraint { - get { return ((GenericParamAttributes)attributes & GenericParamAttributes.ReferenceTypeConstraint) != 0; } - set { ModifyAttributes(value, GenericParamAttributes.ReferenceTypeConstraint); } + get => ((GenericParamAttributes)attributes & GenericParamAttributes.ReferenceTypeConstraint) != 0; + set => ModifyAttributes(value, GenericParamAttributes.ReferenceTypeConstraint); } /// /// Gets/sets the bit /// public bool HasNotNullableValueTypeConstraint { - get { return ((GenericParamAttributes)attributes & GenericParamAttributes.NotNullableValueTypeConstraint) != 0; } - set { ModifyAttributes(value, GenericParamAttributes.NotNullableValueTypeConstraint); } + get => ((GenericParamAttributes)attributes & GenericParamAttributes.NotNullableValueTypeConstraint) != 0; + set => ModifyAttributes(value, GenericParamAttributes.NotNullableValueTypeConstraint); } /// /// Gets/sets the bit /// public bool HasDefaultConstructorConstraint { - get { return ((GenericParamAttributes)attributes & GenericParamAttributes.DefaultConstructorConstraint) != 0; } - set { ModifyAttributes(value, GenericParamAttributes.DefaultConstructorConstraint); } + get => ((GenericParamAttributes)attributes & GenericParamAttributes.DefaultConstructorConstraint) != 0; + set => ModifyAttributes(value, GenericParamAttributes.DefaultConstructorConstraint); } /// - void IListListener.OnLazyAdd(int index, ref GenericParamConstraint value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref GenericParamConstraint value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref GenericParamConstraint value) { #if DEBUG @@ -380,9 +304,7 @@ void IListListener.OnAdd(int index, GenericParamConstrai } /// - void IListListener.OnRemove(int index, GenericParamConstraint value) { - value.Owner = null; - } + void IListListener.OnRemove(int index, GenericParamConstraint value) => value.Owner = null; /// void IListListener.OnResize(int index) { @@ -398,10 +320,10 @@ void IListListener.OnClear() { public override string ToString() { var o = owner; if (o is TypeDef) - return string.Format("!{0}", number); + return $"!{number}"; if (o is MethodDef) - return string.Format("!!{0}", number); - return string.Format("??{0}", number); + return $"!!{number}"; + return $"??{number}"; } } @@ -439,9 +361,9 @@ public GenericParamUser(ushort number, GenericParamAttributes flags) /// Flags /// Name public GenericParamUser(ushort number, GenericParamAttributes flags, UTF8String name) { - this.genericParamConstraints = new LazyList(this); + genericParamConstraints = new LazyList(this); this.number = number; - this.attributes = (int)flags; + attributes = (int)flags; this.name = name; } } @@ -456,9 +378,7 @@ sealed class GenericParamMD : GenericParam, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -482,8 +402,7 @@ protected override void InitializeGenericParamConstraints() { } static GenericParamContext GetGenericParamContext(ITypeOrMethodDef tmOwner) { - var md = tmOwner as MethodDef; - if (md != null) + if (tmOwner is MethodDef md) return GenericParamContext.Create(md); return new GenericParamContext(tmOwner as TypeDef); } @@ -500,15 +419,14 @@ public GenericParamMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.GenericParamTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("GenericParam rid {0} does not exist", rid)); + throw new BadImageFormatException($"GenericParam rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint kind = readerModule.TablesStream.ReadGenericParamRow(origRid, out this.number, out this.attributes, out name); + uint kind = readerModule.TablesStream.ReadGenericParamRow(origRid, out number, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); - this.owner = readerModule.GetOwner(this); + owner = readerModule.GetOwner(this); if (kind != 0) this.kind = readerModule.ResolveTypeDefOrRef(kind, GetGenericParamContext(owner)); } diff --git a/src/DotNet/GenericParamConstraint.cs b/src/DotNet/GenericParamConstraint.cs index 9e5d50ec3..e2ab468e5 100644 --- a/src/DotNet/GenericParamConstraint.cs +++ b/src/DotNet/GenericParamConstraint.cs @@ -23,27 +23,23 @@ public abstract class GenericParamConstraint : IHasCustomAttribute, IHasCustomDe protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.GenericParamConstraint, rid); } - } + public MDToken MDToken => new MDToken(Table.GenericParamConstraint, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 20; } - } + public int HasCustomAttributeTag => 20; /// /// Gets the owner generic param /// public GenericParam Owner { - get { return owner; } - internal set { owner = value; } + get => owner; + internal set => owner = value; } /// protected GenericParam owner; @@ -52,8 +48,8 @@ public GenericParam Owner { /// From column GenericParamConstraint.Constraint /// public ITypeDefOrRef Constraint { - get { return constraint; } - set { constraint = value; } + get => constraint; + set => constraint = value; } /// protected ITypeDefOrRef constraint; @@ -71,24 +67,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 20; } - } + public int HasCustomDebugInformationTag => 20; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -103,13 +92,10 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } - bool IContainsGenericParameter.ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); } /// @@ -126,9 +112,7 @@ public GenericParamConstraintUser() { /// Constructor /// /// The constraint - public GenericParamConstraintUser(ITypeDefOrRef constraint) { - this.constraint = constraint; - } + public GenericParamConstraintUser(ITypeDefOrRef constraint) => this.constraint = constraint; } /// @@ -142,9 +126,7 @@ sealed class GenericParamConstraintMD : GenericParamConstraint, IMDTokenProvider readonly GenericParamContext gpContext; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -173,15 +155,15 @@ public GenericParamConstraintMD(ModuleDefMD readerModule, uint rid, GenericParam if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.GenericParamConstraintTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("GenericParamConstraint rid {0} does not exist", rid)); + throw new BadImageFormatException($"GenericParamConstraint rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; this.gpContext = gpContext; uint constraint = readerModule.TablesStream.ReadGenericParamConstraintRow2(origRid); this.constraint = readerModule.ResolveTypeDefOrRef(constraint, gpContext); - this.owner = readerModule.GetOwner(this); + owner = readerModule.GetOwner(this); } internal GenericParamConstraintMD InitializeAll() { diff --git a/src/DotNet/GenericParamContext.cs b/src/DotNet/GenericParamContext.cs index 7f2e35f59..f6d6d87a9 100644 --- a/src/DotNet/GenericParamContext.cs +++ b/src/DotNet/GenericParamContext.cs @@ -4,7 +4,7 @@ namespace dnlib.DotNet { /// /// Generic parameter context /// - public struct GenericParamContext { + public readonly struct GenericParamContext { /// /// Type context /// @@ -18,9 +18,7 @@ public struct GenericParamContext { /// /// true if and are both null /// - public bool IsEmpty { - get { return Type == null && Method == null; } - } + public bool IsEmpty => Type == null && Method == null; /// /// Creates a new instance and initializes the @@ -42,17 +40,15 @@ public static GenericParamContext Create(MethodDef method) { /// /// Type /// A new instance - public static GenericParamContext Create(TypeDef type) { - return new GenericParamContext(type); - } + public static GenericParamContext Create(TypeDef type) => new GenericParamContext(type); /// /// Constructor /// /// Type context public GenericParamContext(TypeDef type) { - this.Type = type; - this.Method = null; + Type = type; + Method = null; } /// @@ -62,8 +58,8 @@ public GenericParamContext(TypeDef type) { /// /// Method context public GenericParamContext(MethodDef method) { - this.Type = null; - this.Method = method; + Type = null; + Method = method; } /// @@ -72,8 +68,8 @@ public GenericParamContext(MethodDef method) { /// Type context /// Method context public GenericParamContext(TypeDef type, MethodDef method) { - this.Type = type; - this.Method = method; + Type = type; + Method = method; } } } diff --git a/src/DotNet/IAssemblyResolver.cs b/src/DotNet/IAssemblyResolver.cs index 2824e6e77..b523a7fe8 100644 --- a/src/DotNet/IAssemblyResolver.cs +++ b/src/DotNet/IAssemblyResolver.cs @@ -52,9 +52,7 @@ public static partial class Extensions { /// true if 's assembly is cached, false /// if it's not cached because some other assembly with the exact same full name has /// already been cached or if or its assembly is null. - public static bool AddToCache(this IAssemblyResolver self, ModuleDef module) { - return module != null && self.AddToCache(module.Assembly); - } + public static bool AddToCache(this IAssemblyResolver self, ModuleDef module) => module != null && self.AddToCache(module.Assembly); /// /// Removes a module's assembly from the cache @@ -64,9 +62,7 @@ public static bool AddToCache(this IAssemblyResolver self, ModuleDef module) { /// true if its assembly was removed, false if it wasn't removed /// since it wasn't in the cache, it has no assembly, or was /// null - public static bool Remove(this IAssemblyResolver self, ModuleDef module) { - return module != null && self.Remove(module.Assembly); - } + public static bool Remove(this IAssemblyResolver self, ModuleDef module) => module != null && self.Remove(module.Assembly); /// /// Finds and returns an @@ -110,7 +106,7 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, IAssembly as var asm = self.Resolve(assembly, sourceModule); if (asm != null) return asm; - throw new AssemblyResolveException(string.Format("Could not resolve assembly: {0}", assembly)); + throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); } /// @@ -127,7 +123,7 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, AssemblyName var asm = self.Resolve(new AssemblyNameInfo(assembly), sourceModule); if (asm != null) return asm; - throw new AssemblyResolveException(string.Format("Could not resolve assembly: {0}", assembly)); + throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); } /// @@ -144,7 +140,7 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, string asmFu var asm = self.Resolve(new AssemblyNameInfo(asmFullName), sourceModule); if (asm != null) return asm; - throw new AssemblyResolveException(string.Format("Could not resolve assembly: {0}", asmFullName)); + throw new AssemblyResolveException($"Could not resolve assembly: {asmFullName}"); } } } diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index ff463fc64..eb1cd14fa 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -166,8 +166,7 @@ public static partial class Extensions { /// /// The assembly public static bool IsCorLib(this IAssembly asm) { - var asmDef = asm as AssemblyDef; - if (asmDef != null) { + if (asm is AssemblyDef asmDef) { var manifestModule = asmDef.ManifestModule; if (manifestModule != null) { var isCorModule = manifestModule.IsCoreLibraryModule; @@ -222,15 +221,13 @@ public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType = t if (td != null) return CreateClassOrValueType(type, checkValueType ? td.IsValueType : false); - var tr = type as TypeRef; - if (tr != null) { + if (type is TypeRef tr) { if (checkValueType) td = tr.Resolve(); return CreateClassOrValueType(type, td == null ? false : td.IsValueType); } - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return ts.TypeSig; return null; @@ -380,9 +377,7 @@ public static SZArraySig TryGetSZArraySig(this ITypeDefOrRef type) { /// /// The type /// The base type or null if there's no base type - public static ITypeDefOrRef GetBaseTypeThrow(this ITypeDefOrRef tdr) { - return tdr.GetBaseType(true); - } + public static ITypeDefOrRef GetBaseTypeThrow(this ITypeDefOrRef tdr) => tdr.GetBaseType(true); /// /// Returns the base type of @@ -395,14 +390,12 @@ public static ITypeDefOrRef GetBaseTypeThrow(this ITypeDefOrRef tdr) { /// is true and we couldn't resolve /// a public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnResolveFailure = false) { - var td = tdr as TypeDef; - if (td != null) + if (tdr is TypeDef td) return td.BaseType; - var tr = tdr as TypeRef; - if (tr != null) { + if (tdr is TypeRef tr) { td = throwOnResolveFailure ? tr.ResolveThrow() : tr.Resolve(); - return td == null ? null : td.BaseType; + return td?.BaseType; } var ts = tdr as TypeSpec; @@ -410,14 +403,10 @@ public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnReso return null; var git = ts.TypeSig.ToGenericInstSig(); - if (git != null) { - var genType = git.GenericType; - tdr = genType == null ? null : genType.TypeDefOrRef; - } - else { - var sig = ts.TypeSig.ToTypeDefOrRefSig(); - tdr = sig == null ? null : sig.TypeDefOrRef; - } + if (git != null) + tdr = git.GenericType?.TypeDefOrRef; + else + tdr = ts.TypeSig.ToTypeDefOrRefSig()?.TypeDefOrRef; td = tdr as TypeDef; if (td != null) @@ -426,7 +415,7 @@ public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnReso tr = tdr as TypeRef; if (tr != null) { td = throwOnResolveFailure ? tr.ResolveThrow() : tr.Resolve(); - return td == null ? null : td.BaseType; + return td?.BaseType; } return null; @@ -439,12 +428,10 @@ public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnReso /// A or null if input was null or if we /// couldn't resolve the reference. public static TypeDef ResolveTypeDef(this ITypeDefOrRef tdr) { - var td = tdr as TypeDef; - if (td != null) + if (tdr is TypeDef td) return td; - var tr = tdr as TypeRef; - if (tr != null) + if (tdr is TypeRef tr) return tr.Resolve(); if (tdr == null) @@ -469,12 +456,10 @@ public static TypeDef ResolveTypeDef(this ITypeDefOrRef tdr) { /// A instance. /// If the type couldn't be resolved public static TypeDef ResolveTypeDefThrow(this ITypeDefOrRef tdr) { - var td = tdr as TypeDef; - if (td != null) + if (tdr is TypeDef td) return td; - var tr = tdr as TypeRef; - if (tr != null) + if (tdr is TypeRef tr) return tr.ResolveThrow(); if (tdr == null) @@ -489,7 +474,7 @@ public static TypeDef ResolveTypeDefThrow(this ITypeDefOrRef tdr) { if (tr != null) return tr.ResolveThrow(); - throw new TypeResolveException(string.Format("Could not resolve type: {0} ({1})", tdr, tdr == null ? null : tdr.DefinitionAssembly)); + throw new TypeResolveException($"Could not resolve type: {tdr} ({tdr?.DefinitionAssembly})"); } /// @@ -501,12 +486,10 @@ public static TypeDef ResolveTypeDefThrow(this ITypeDefOrRef tdr) { /// null or if it wasn't possible to resolve it (the field doesn't exist or its /// assembly couldn't be loaded) public static FieldDef ResolveFieldDef(this IField field) { - var fd = field as FieldDef; - if (fd != null) + if (field is FieldDef fd) return fd; - var mr = field as MemberRef; - if (mr != null) + if (field is MemberRef mr) return mr.ResolveField(); return null; @@ -519,15 +502,13 @@ public static FieldDef ResolveFieldDef(this IField field) { /// Field to resolve /// The public static FieldDef ResolveFieldDefThrow(this IField field) { - var fd = field as FieldDef; - if (fd != null) + if (field is FieldDef fd) return fd; - var mr = field as MemberRef; - if (mr != null) + if (field is MemberRef mr) return mr.ResolveFieldThrow(); - throw new MemberRefResolveException(string.Format("Could not resolve field: {0}", field)); + throw new MemberRefResolveException($"Could not resolve field: {field}"); } /// @@ -541,16 +522,13 @@ public static FieldDef ResolveFieldDefThrow(this IField field) { /// null or if it wasn't possible to resolve it (the method doesn't exist or its /// assembly couldn't be loaded) public static MethodDef ResolveMethodDef(this IMethod method) { - var md = method as MethodDef; - if (md != null) + if (method is MethodDef md) return md; - var mr = method as MemberRef; - if (mr != null) + if (method is MemberRef mr) return mr.ResolveMethod(); - var ms = method as MethodSpec; - if (ms != null) { + if (method is MethodSpec ms) { md = ms.Method as MethodDef; if (md != null) return md; @@ -572,16 +550,13 @@ public static MethodDef ResolveMethodDef(this IMethod method) { /// Method to resolve /// The public static MethodDef ResolveMethodDefThrow(this IMethod method) { - var md = method as MethodDef; - if (md != null) + if (method is MethodDef md) return md; - var mr = method as MemberRef; - if (mr != null) + if (method is MemberRef mr) return mr.ResolveMethodThrow(); - var ms = method as MethodSpec; - if (ms != null) { + if (method is MethodSpec ms) { md = ms.Method as MethodDef; if (md != null) return md; @@ -591,7 +566,7 @@ public static MethodDef ResolveMethodDefThrow(this IMethod method) { return mr.ResolveMethodThrow(); } - throw new MemberRefResolveException(string.Format("Could not resolve method: {0}", method)); + throw new MemberRefResolveException($"Could not resolve method: {method}"); } /// @@ -604,20 +579,14 @@ static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { return null; var parent = mr.Class; - var tdr = parent as ITypeDefOrRef; - if (tdr != null) + if (parent is ITypeDefOrRef tdr) return tdr.DefinitionAssembly; - if (parent is ModuleRef) { - var mod = mr.Module; - return mod == null ? null : mod.Assembly; - } + if (parent is ModuleRef) + return mr.Module?.Assembly; - var md = parent as MethodDef; - if (md != null) { - var declType = md.DeclaringType; - return declType == null ? null : declType.DefinitionAssembly; - } + if (parent is MethodDef md) + return md.DeclaringType?.DefinitionAssembly; return null; } @@ -1053,8 +1022,7 @@ public static partial class Extensions { public static ITypeDefOrRef ToTypeDefOrRef(this TypeSig sig) { if (sig == null) return null; - var tdrSig = sig as TypeDefOrRefSig; - if (tdrSig != null) + if (sig is TypeDefOrRefSig tdrSig) return tdrSig.TypeDefOrRef; var module = sig.Module; if (module == null) diff --git a/src/DotNet/ICorLibTypes.cs b/src/DotNet/ICorLibTypes.cs index a69739041..65dbb5f46 100644 --- a/src/DotNet/ICorLibTypes.cs +++ b/src/DotNet/ICorLibTypes.cs @@ -119,15 +119,13 @@ public static partial class Extensions { public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, ITypeDefOrRef type) { CorLibTypeSig corLibType; - TypeDef td; - if ((td = type as TypeDef) != null && + if (type is TypeDef td && td.DeclaringType == null && (corLibType = self.GetCorLibTypeSig(td.Namespace, td.Name, td.DefinitionAssembly)) != null) { return corLibType; } - TypeRef tr; - if ((tr = type as TypeRef) != null && + if (type is TypeRef tr && !(tr.ResolutionScope is TypeRef) && (corLibType = self.GetCorLibTypeSig(tr.Namespace, tr.Name, tr.DefinitionAssembly)) != null) { return corLibType; @@ -145,9 +143,8 @@ public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, ITypeDefOrR /// Name /// Definition assembly /// A or null if it didn't match any primitive type - public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, UTF8String @namespace, UTF8String name, IAssembly defAsm) { - return self.GetCorLibTypeSig(UTF8String.ToSystemStringOrEmpty(@namespace), UTF8String.ToSystemStringOrEmpty(name), defAsm); - } + public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, UTF8String @namespace, UTF8String name, IAssembly defAsm) => + self.GetCorLibTypeSig(UTF8String.ToSystemStringOrEmpty(@namespace), UTF8String.ToSystemStringOrEmpty(name), defAsm); /// /// Gets a if and diff --git a/src/DotNet/ILogger.cs b/src/DotNet/ILogger.cs index 6ab6b32bb..96d4263a6 100644 --- a/src/DotNet/ILogger.cs +++ b/src/DotNet/ILogger.cs @@ -65,9 +65,8 @@ public static partial class Extensions { /// this /// Sender or null /// Message - public static void Error(this ILogger logger, object sender, string message) { + public static void Error(this ILogger logger, object sender, string message) => logger.Log(sender, LoggerEvent.Error, "{0}", message); - } /// /// Log an error message @@ -76,9 +75,8 @@ public static void Error(this ILogger logger, object sender, string message) { /// Sender or null /// Message /// Message arg #1 - public static void Error(this ILogger logger, object sender, string message, object arg1) { + public static void Error(this ILogger logger, object sender, string message, object arg1) => logger.Log(sender, LoggerEvent.Error, message, arg1); - } /// /// Log an error message @@ -88,9 +86,8 @@ public static void Error(this ILogger logger, object sender, string message, obj /// Message /// Message arg #1 /// Message arg #2 - public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2) { + public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2) => logger.Log(sender, LoggerEvent.Error, message, arg1, arg2); - } /// /// Log an error message @@ -101,9 +98,8 @@ public static void Error(this ILogger logger, object sender, string message, obj /// Message arg #1 /// Message arg #2 /// Message arg #3 - public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) { + public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) => logger.Log(sender, LoggerEvent.Error, message, arg1, arg2, arg3); - } /// /// Log an error message @@ -115,9 +111,8 @@ public static void Error(this ILogger logger, object sender, string message, obj /// Message arg #2 /// Message arg #3 /// Message arg #4 - public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) { + public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) => logger.Log(sender, LoggerEvent.Error, message, arg1, arg2, arg3, arg4); - } /// /// Log an error message @@ -126,9 +121,8 @@ public static void Error(this ILogger logger, object sender, string message, obj /// Sender or null /// Message /// Message arguments - public static void Error(this ILogger logger, object sender, string message, params object[] args) { + public static void Error(this ILogger logger, object sender, string message, params object[] args) => logger.Log(sender, LoggerEvent.Error, message, args); - } /// /// Log a warning message @@ -136,9 +130,8 @@ public static void Error(this ILogger logger, object sender, string message, par /// this /// Sender or null /// Message - public static void Warning(this ILogger logger, object sender, string message) { + public static void Warning(this ILogger logger, object sender, string message) => logger.Log(sender, LoggerEvent.Warning, "{0}", message); - } /// /// Log a warning message @@ -147,9 +140,8 @@ public static void Warning(this ILogger logger, object sender, string message) { /// Sender or null /// Message /// Message arg #1 - public static void Warning(this ILogger logger, object sender, string message, object arg1) { + public static void Warning(this ILogger logger, object sender, string message, object arg1) => logger.Log(sender, LoggerEvent.Warning, message, arg1); - } /// /// Log a warning message @@ -159,9 +151,8 @@ public static void Warning(this ILogger logger, object sender, string message, o /// Message /// Message arg #1 /// Message arg #2 - public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2) { + public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2) => logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2); - } /// /// Log a warning message @@ -172,9 +163,7 @@ public static void Warning(this ILogger logger, object sender, string message, o /// Message arg #1 /// Message arg #2 /// Message arg #3 - public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) { - logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2, arg3); - } + public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) => logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2, arg3); /// /// Log a warning message @@ -186,9 +175,8 @@ public static void Warning(this ILogger logger, object sender, string message, o /// Message arg #2 /// Message arg #3 /// Message arg #4 - public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) { + public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) => logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2, arg3, arg4); - } /// /// Log a warning message @@ -197,9 +185,8 @@ public static void Warning(this ILogger logger, object sender, string message, o /// Sender or null /// Message /// Message arguments - public static void Warning(this ILogger logger, object sender, string message, params object[] args) { + public static void Warning(this ILogger logger, object sender, string message, params object[] args) => logger.Log(sender, LoggerEvent.Warning, message, args); - } /// /// Log an info message @@ -207,9 +194,8 @@ public static void Warning(this ILogger logger, object sender, string message, p /// this /// Sender or null /// Message - public static void Info(this ILogger logger, object sender, string message) { + public static void Info(this ILogger logger, object sender, string message) => logger.Log(sender, LoggerEvent.Info, "{0}", message); - } /// /// Log an info message @@ -218,9 +204,8 @@ public static void Info(this ILogger logger, object sender, string message) { /// Sender or null /// Message /// Message arg #1 - public static void Info(this ILogger logger, object sender, string message, object arg1) { + public static void Info(this ILogger logger, object sender, string message, object arg1) => logger.Log(sender, LoggerEvent.Info, message, arg1); - } /// /// Log an info message @@ -230,9 +215,8 @@ public static void Info(this ILogger logger, object sender, string message, obje /// Message /// Message arg #1 /// Message arg #2 - public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2) { + public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2) => logger.Log(sender, LoggerEvent.Info, message, arg1, arg2); - } /// /// Log an info message @@ -243,9 +227,8 @@ public static void Info(this ILogger logger, object sender, string message, obje /// Message arg #1 /// Message arg #2 /// Message arg #3 - public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) { + public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) => logger.Log(sender, LoggerEvent.Info, message, arg1, arg2, arg3); - } /// /// Log an info message @@ -257,9 +240,8 @@ public static void Info(this ILogger logger, object sender, string message, obje /// Message arg #2 /// Message arg #3 /// Message arg #4 - public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) { + public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) => logger.Log(sender, LoggerEvent.Info, message, arg1, arg2, arg3, arg4); - } /// /// Log an info message @@ -268,9 +250,8 @@ public static void Info(this ILogger logger, object sender, string message, obje /// Sender or null /// Message /// Message arguments - public static void Info(this ILogger logger, object sender, string message, params object[] args) { + public static void Info(this ILogger logger, object sender, string message, params object[] args) => logger.Log(sender, LoggerEvent.Info, message, args); - } /// /// Log a verbose message @@ -278,9 +259,8 @@ public static void Info(this ILogger logger, object sender, string message, para /// this /// Sender or null /// Message - public static void Verbose(this ILogger logger, object sender, string message) { + public static void Verbose(this ILogger logger, object sender, string message) => logger.Log(sender, LoggerEvent.Verbose, "{0}", message); - } /// /// Log a verbose message @@ -289,9 +269,8 @@ public static void Verbose(this ILogger logger, object sender, string message) { /// Sender or null /// Message /// Message arg #1 - public static void Verbose(this ILogger logger, object sender, string message, object arg1) { + public static void Verbose(this ILogger logger, object sender, string message, object arg1) => logger.Log(sender, LoggerEvent.Verbose, message, arg1); - } /// /// Log a verbose message @@ -301,9 +280,8 @@ public static void Verbose(this ILogger logger, object sender, string message, o /// Message /// Message arg #1 /// Message arg #2 - public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2) { + public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2) => logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2); - } /// /// Log a verbose message @@ -314,9 +292,8 @@ public static void Verbose(this ILogger logger, object sender, string message, o /// Message arg #1 /// Message arg #2 /// Message arg #3 - public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) { + public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) => logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2, arg3); - } /// /// Log a verbose message @@ -328,9 +305,8 @@ public static void Verbose(this ILogger logger, object sender, string message, o /// Message arg #2 /// Message arg #3 /// Message arg #4 - public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) { + public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) => logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2, arg3, arg4); - } /// /// Log a verbose message @@ -339,9 +315,8 @@ public static void Verbose(this ILogger logger, object sender, string message, o /// Sender or null /// Message /// Message arguments - public static void Verbose(this ILogger logger, object sender, string message, params object[] args) { + public static void Verbose(this ILogger logger, object sender, string message, params object[] args) => logger.Log(sender, LoggerEvent.Verbose, message, args); - } /// /// Log a very verbose message @@ -349,9 +324,8 @@ public static void Verbose(this ILogger logger, object sender, string message, p /// this /// Sender or null /// Message - public static void VeryVerbose(this ILogger logger, object sender, string message) { + public static void VeryVerbose(this ILogger logger, object sender, string message) => logger.Log(sender, LoggerEvent.VeryVerbose, "{0}", message); - } /// /// Log a very verbose message @@ -360,9 +334,8 @@ public static void VeryVerbose(this ILogger logger, object sender, string messag /// Sender or null /// Message /// Message arg #1 - public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1) { + public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1) => logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1); - } /// /// Log a very verbose message @@ -372,9 +345,8 @@ public static void VeryVerbose(this ILogger logger, object sender, string messag /// Message /// Message arg #1 /// Message arg #2 - public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2) { + public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2) => logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2); - } /// /// Log a very verbose message @@ -385,9 +357,8 @@ public static void VeryVerbose(this ILogger logger, object sender, string messag /// Message arg #1 /// Message arg #2 /// Message arg #3 - public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) { + public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) => logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2, arg3); - } /// /// Log a very verbose message @@ -399,9 +370,8 @@ public static void VeryVerbose(this ILogger logger, object sender, string messag /// Message arg #2 /// Message arg #3 /// Message arg #4 - public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) { + public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) => logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2, arg3, arg4); - } /// /// Log a very verbose message @@ -410,9 +380,8 @@ public static void VeryVerbose(this ILogger logger, object sender, string messag /// Sender or null /// Message /// Message arguments - public static void VeryVerbose(this ILogger logger, object sender, string message, params object[] args) { + public static void VeryVerbose(this ILogger logger, object sender, string message, params object[] args) => logger.Log(sender, LoggerEvent.VeryVerbose, message, args); - } } /// @@ -443,10 +412,10 @@ public sealed class DummyLogger : ILogger { public DummyLogger(Type exceptionToThrow) { if (exceptionToThrow != null) { if (!exceptionToThrow.IsSubclassOf(typeof(Exception))) - throw new ArgumentException(string.Format("Not a System.Exception sub class: {0}", exceptionToThrow.GetType())); + throw new ArgumentException($"Not a System.Exception sub class: {exceptionToThrow.GetType()}"); ctor = exceptionToThrow.GetConstructor(new Type[] { typeof(string) }); if (ctor == null) - throw new ArgumentException(string.Format("Exception type {0} doesn't have a public constructor that takes a string as the only argument", exceptionToThrow.GetType())); + throw new ArgumentException($"Exception type {exceptionToThrow.GetType()} doesn't have a public constructor that takes a string as the only argument"); } } diff --git a/src/DotNet/IResolver.cs b/src/DotNet/IResolver.cs index 89e986446..067d221d4 100644 --- a/src/DotNet/IResolver.cs +++ b/src/DotNet/IResolver.cs @@ -40,9 +40,7 @@ public static partial class Extensions { /// this /// The type /// A instance or null if it couldn't be resolved - public static TypeDef Resolve(this ITypeResolver self, TypeRef typeRef) { - return self.Resolve(typeRef, null); - } + public static TypeDef Resolve(this ITypeResolver self, TypeRef typeRef) => self.Resolve(typeRef, null); /// /// Resolves a type @@ -51,9 +49,7 @@ public static TypeDef Resolve(this ITypeResolver self, TypeRef typeRef) { /// The type /// A instance /// If the type couldn't be resolved - public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef) { - return self.ResolveThrow(typeRef, null); - } + public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef) => self.ResolveThrow(typeRef, null); /// /// Resolves a type @@ -67,7 +63,7 @@ public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef, Mod var type = self.Resolve(typeRef, sourceModule); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not resolve type: {0} ({1})", typeRef, typeRef == null ? null : typeRef.DefinitionAssembly)); + throw new TypeResolveException($"Could not resolve type: {typeRef} ({typeRef?.DefinitionAssembly})"); } /// @@ -81,7 +77,7 @@ public static IMemberForwarded ResolveThrow(this IMemberRefResolver self, Member var memberDef = self.Resolve(memberRef); if (memberDef != null) return memberDef; - throw new MemberRefResolveException(string.Format("Could not resolve method/field: {0} ({1})", memberRef, memberRef == null ? null : memberRef.GetDefinitionAssembly())); + throw new MemberRefResolveException($"Could not resolve method/field: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); } /// @@ -90,9 +86,7 @@ public static IMemberForwarded ResolveThrow(this IMemberRefResolver self, Member /// this /// A field reference /// A instance or null if it couldn't be resolved. - public static FieldDef ResolveField(this IMemberRefResolver self, MemberRef memberRef) { - return self.Resolve(memberRef) as FieldDef; - } + public static FieldDef ResolveField(this IMemberRefResolver self, MemberRef memberRef) => self.Resolve(memberRef) as FieldDef; /// /// Resolves a field @@ -102,10 +96,9 @@ public static FieldDef ResolveField(this IMemberRefResolver self, MemberRef memb /// A instance or null if it couldn't be resolved. /// If the field couldn't be resolved public static FieldDef ResolveFieldThrow(this IMemberRefResolver self, MemberRef memberRef) { - var field = self.Resolve(memberRef) as FieldDef; - if (field != null) + if (self.Resolve(memberRef) is FieldDef field) return field; - throw new MemberRefResolveException(string.Format("Could not resolve field: {0} ({1})", memberRef, memberRef == null ? null : memberRef.GetDefinitionAssembly())); + throw new MemberRefResolveException($"Could not resolve field: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); } /// @@ -114,9 +107,7 @@ public static FieldDef ResolveFieldThrow(this IMemberRefResolver self, MemberRef /// this /// A method reference /// A instance or null if it couldn't be resolved. - public static MethodDef ResolveMethod(this IMemberRefResolver self, MemberRef memberRef) { - return self.Resolve(memberRef) as MethodDef; - } + public static MethodDef ResolveMethod(this IMemberRefResolver self, MemberRef memberRef) => self.Resolve(memberRef) as MethodDef; /// /// Resolves a method @@ -126,10 +117,9 @@ public static MethodDef ResolveMethod(this IMemberRefResolver self, MemberRef me /// A instance or null if it couldn't be resolved. /// If the method couldn't be resolved public static MethodDef ResolveMethodThrow(this IMemberRefResolver self, MemberRef memberRef) { - var method = self.Resolve(memberRef) as MethodDef; - if (method != null) + if (self.Resolve(memberRef) is MethodDef method) return method; - throw new MemberRefResolveException(string.Format("Could not resolve method: {0} ({1})", memberRef, memberRef == null ? null : memberRef.GetDefinitionAssembly())); + throw new MemberRefResolveException($"Could not resolve method: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); } } } diff --git a/src/DotNet/ITokenResolver.cs b/src/DotNet/ITokenResolver.cs index 2d3e0c834..0fab0a59a 100644 --- a/src/DotNet/ITokenResolver.cs +++ b/src/DotNet/ITokenResolver.cs @@ -21,8 +21,6 @@ public static partial class Extensions { /// This /// The metadata token /// A or null if is invalid - public static IMDTokenProvider ResolveToken(this ITokenResolver self, uint token) { - return self.ResolveToken(token, new GenericParamContext()); - } + public static IMDTokenProvider ResolveToken(this ITokenResolver self, uint token) => self.ResolveToken(token, new GenericParamContext()); } } diff --git a/src/DotNet/ITypeDefFinder.cs b/src/DotNet/ITypeDefFinder.cs index 0a232b1a6..52d654b90 100644 --- a/src/DotNet/ITypeDefFinder.cs +++ b/src/DotNet/ITypeDefFinder.cs @@ -37,7 +37,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, TypeRef typeRef) { var type = self.Find(typeRef); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not find type: {0}", typeRef)); + throw new TypeResolveException($"Could not find type: {typeRef}"); } /// @@ -54,7 +54,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, string fullName, bool var type = self.Find(fullName, isReflectionName); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not find type: {0}", fullName)); + throw new TypeResolveException($"Could not find type: {fullName}"); } /// @@ -63,9 +63,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, string fullName, bool /// this /// Full name of the type (no assembly information). Nested types are separated by / /// An existing or null if it wasn't found. - public static TypeDef FindNormal(this ITypeDefFinder self, string fullName) { - return self.Find(fullName, false); - } + public static TypeDef FindNormal(this ITypeDefFinder self, string fullName) => self.Find(fullName, false); /// /// Finds a @@ -78,7 +76,7 @@ public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) var type = self.Find(fullName, false); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not find type: {0}", fullName)); + throw new TypeResolveException($"Could not find type: {fullName}"); } /// @@ -87,9 +85,7 @@ public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) /// this /// Full name of the type (no assembly information). Nested types are separated by + /// An existing or null if it wasn't found. - public static TypeDef FindReflection(this ITypeDefFinder self, string fullName) { - return self.Find(fullName, true); - } + public static TypeDef FindReflection(this ITypeDefFinder self, string fullName) => self.Find(fullName, true); /// /// Finds a @@ -102,7 +98,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN var type = self.Find(fullName, true); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not find type: {0}", fullName)); + throw new TypeResolveException($"Could not find type: {fullName}"); } /// @@ -112,9 +108,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// The type ref /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) { - return self.Find(typeRef) != null; - } + public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) => self.Find(typeRef) != null; /// /// Checks whether a exists @@ -125,9 +119,7 @@ public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) { /// type names are separated by a + character. If false, nested type names /// are separated by a / character. /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, string fullName, bool isReflectionName) { - return self.Find(fullName, isReflectionName) != null; - } + public static bool TypeExists(this ITypeDefFinder self, string fullName, bool isReflectionName) => self.Find(fullName, isReflectionName) != null; /// /// Checks whether a exists @@ -135,9 +127,7 @@ public static bool TypeExists(this ITypeDefFinder self, string fullName, bool is /// this /// Full name of the type (no assembly information). Nested types are separated by / /// true if the exists, false otherwise - public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) { - return self.Find(fullName, false) != null; - } + public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) => self.Find(fullName, false) != null; /// /// Checks whether a exists @@ -145,8 +135,6 @@ public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) { /// this /// Full name of the type (no assembly information). Nested types are separated by + /// true if the exists, false otherwise - public static bool TypeExistsReflection(this ITypeDefFinder self, string fullName) { - return self.Find(fullName, true) != null; - } + public static bool TypeExistsReflection(this ITypeDefFinder self, string fullName) => self.Find(fullName, true) != null; } } diff --git a/src/DotNet/ImplMap.cs b/src/DotNet/ImplMap.cs index b296c0d58..4271a58cd 100644 --- a/src/DotNet/ImplMap.cs +++ b/src/DotNet/ImplMap.cs @@ -17,22 +17,20 @@ public abstract class ImplMap : IMDTokenProvider { protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.ImplMap, rid); } - } + public MDToken MDToken => new MDToken(Table.ImplMap, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// /// From column ImplMap.MappingFlags /// public PInvokeAttributes Attributes { - get { return (PInvokeAttributes)attributes; } - set { attributes = (int)value; } + get => (PInvokeAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -41,8 +39,8 @@ public PInvokeAttributes Attributes { /// From column ImplMap.ImportName /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -51,8 +49,8 @@ public UTF8String Name { /// From column ImplMap.ImportScope /// public ModuleRef Module { - get { return module; } - set { module = value; } + get => module; + set => module = value; } /// protected ModuleRef module; @@ -103,154 +101,124 @@ void ModifyAttributes(bool set, PInvokeAttributes flags) { /// Gets/sets the bit /// public bool IsNoMangle { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.NoMangle) != 0; } - set { ModifyAttributes(value, PInvokeAttributes.NoMangle); } + get => ((PInvokeAttributes)attributes & PInvokeAttributes.NoMangle) != 0; + set => ModifyAttributes(value, PInvokeAttributes.NoMangle); } /// /// Gets/sets the char set /// public PInvokeAttributes CharSet { - get { return (PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask; } - set { ModifyAttributes(~PInvokeAttributes.CharSetMask, value & PInvokeAttributes.CharSetMask); } + get => (PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask; + set => ModifyAttributes(~PInvokeAttributes.CharSetMask, value & PInvokeAttributes.CharSetMask); } /// /// true if is set /// - public bool IsCharSetNotSpec { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetNotSpec; } - } + public bool IsCharSetNotSpec => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetNotSpec; /// /// true if is set /// - public bool IsCharSetAnsi { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetAnsi; } - } + public bool IsCharSetAnsi => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetAnsi; /// /// true if is set /// - public bool IsCharSetUnicode { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetUnicode; } - } + public bool IsCharSetUnicode => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetUnicode; /// /// true if is set /// - public bool IsCharSetAuto { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetAuto; } - } + public bool IsCharSetAuto => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetAuto; /// /// Gets/sets best fit /// public PInvokeAttributes BestFit { - get { return (PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask; } - set { ModifyAttributes(~PInvokeAttributes.BestFitMask, value & PInvokeAttributes.BestFitMask); } + get => (PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask; + set => ModifyAttributes(~PInvokeAttributes.BestFitMask, value & PInvokeAttributes.BestFitMask); } /// /// true if is set /// - public bool IsBestFitUseAssem { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitUseAssem; } - } + public bool IsBestFitUseAssem => ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitUseAssem; /// /// true if is set /// - public bool IsBestFitEnabled { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled; } - } + public bool IsBestFitEnabled => ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled; /// /// true if is set /// - public bool IsBestFitDisabled { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitDisabled; } - } + public bool IsBestFitDisabled => ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitDisabled; /// /// Gets/sets throw on unmappable char /// public PInvokeAttributes ThrowOnUnmappableChar { - get { return (PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask; } - set { ModifyAttributes(~PInvokeAttributes.ThrowOnUnmappableCharMask, value & PInvokeAttributes.ThrowOnUnmappableCharMask); } + get => (PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask; + set => ModifyAttributes(~PInvokeAttributes.ThrowOnUnmappableCharMask, value & PInvokeAttributes.ThrowOnUnmappableCharMask); } /// /// true if is set /// - public bool IsThrowOnUnmappableCharUseAssem { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharUseAssem; } - } + public bool IsThrowOnUnmappableCharUseAssem => ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharUseAssem; /// /// true if is set /// - public bool IsThrowOnUnmappableCharEnabled { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled; } - } + public bool IsThrowOnUnmappableCharEnabled => ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled; /// /// true if is set /// - public bool IsThrowOnUnmappableCharDisabled { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharDisabled; } - } + public bool IsThrowOnUnmappableCharDisabled => ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharDisabled; /// /// Gets/sets the bit /// public bool SupportsLastError { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.SupportsLastError) != 0; } - set { ModifyAttributes(value, PInvokeAttributes.SupportsLastError); } + get => ((PInvokeAttributes)attributes & PInvokeAttributes.SupportsLastError) != 0; + set => ModifyAttributes(value, PInvokeAttributes.SupportsLastError); } /// /// Gets/sets calling convention /// public PInvokeAttributes CallConv { - get { return (PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask; } - set { ModifyAttributes(~PInvokeAttributes.CallConvMask, value & PInvokeAttributes.CallConvMask); } + get => (PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask; + set => ModifyAttributes(~PInvokeAttributes.CallConvMask, value & PInvokeAttributes.CallConvMask); } /// /// true if is set /// - public bool IsCallConvWinapi { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvWinapi; } - } + public bool IsCallConvWinapi => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvWinapi; /// /// true if is set /// - public bool IsCallConvCdecl { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvCdecl; } - } + public bool IsCallConvCdecl => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvCdecl; /// /// true if is set /// - public bool IsCallConvStdcall { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvStdcall; } - } + public bool IsCallConvStdcall => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvStdcall; /// /// true if is set /// - public bool IsCallConvThiscall { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvThiscall; } - } + public bool IsCallConvThiscall => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvThiscall; /// /// true if is set /// - public bool IsCallConvFastcall { - get { return ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvFastcall; } - } + public bool IsCallConvFastcall => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvFastcall; /// /// Checks whether this is a certain P/Invoke method @@ -291,9 +259,9 @@ public ImplMapUser() { /// Name /// Flags public ImplMapUser(ModuleRef scope, UTF8String name, PInvokeAttributes flags) { - this.module = scope; + module = scope; this.name = name; - this.attributes = (int)flags; + attributes = (int)flags; } } @@ -304,9 +272,7 @@ sealed class ImplMapMD : ImplMap, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// /// Constructor @@ -320,14 +286,13 @@ public ImplMapMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ImplMapTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("ImplMap rid {0} does not exist", rid)); + throw new BadImageFormatException($"ImplMap rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; - uint name; - uint scope = readerModule.TablesStream.ReadImplMapRow(origRid, out this.attributes, out name); + uint scope = readerModule.TablesStream.ReadImplMapRow(origRid, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); - this.module = readerModule.ResolveModuleRef(scope); + module = readerModule.ResolveModuleRef(scope); } } } diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 671dd5ce3..e50208a19 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -54,20 +54,12 @@ public struct Importer { RecursionCounter recursionCounter; ImporterOptions options; - bool TryToUseTypeDefs { - get { return (options & ImporterOptions.TryToUseTypeDefs) != 0; } - } - - bool TryToUseMethodDefs { - get { return (options & ImporterOptions.TryToUseMethodDefs) != 0; } - } - - bool TryToUseFieldDefs { - get { return (options & ImporterOptions.TryToUseFieldDefs) != 0; } - } + bool TryToUseTypeDefs => (options & ImporterOptions.TryToUseTypeDefs) != 0; + bool TryToUseMethodDefs => (options & ImporterOptions.TryToUseMethodDefs) != 0; + bool TryToUseFieldDefs => (options & ImporterOptions.TryToUseFieldDefs) != 0; bool FixSignature { - get { return (options & ImporterOptions.FixSignature) != 0; } + get => (options & ImporterOptions.FixSignature) != 0; set { if (value) options |= ImporterOptions.FixSignature; @@ -110,7 +102,7 @@ public Importer(ModuleDef module, ImporterOptions options) /// Generic parameter context public Importer(ModuleDef module, ImporterOptions options, GenericParamContext gpContext) { this.module = module; - this.recursionCounter = new RecursionCounter(); + recursionCounter = new RecursionCounter(); this.options = options; this.gpContext = gpContext; } @@ -120,9 +112,7 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g /// /// The type /// The imported type or null if is invalid - public ITypeDefOrRef Import(Type type) { - return module.UpdateRowId(ImportAsTypeSig(type).ToTypeDefOrRef()); - } + public ITypeDefOrRef Import(Type type) => module.UpdateRowId(ImportAsTypeSig(type).ToTypeDefOrRef()); /// /// Imports a as a @@ -131,18 +121,15 @@ public ITypeDefOrRef Import(Type type) { /// A list of all required modifiers or null /// A list of all optional modifiers or null /// The imported type or null if is invalid - public ITypeDefOrRef Import(Type type, IList requiredModifiers, IList optionalModifiers) { - return module.UpdateRowId(ImportAsTypeSig(type, requiredModifiers, optionalModifiers).ToTypeDefOrRef()); - } + public ITypeDefOrRef Import(Type type, IList requiredModifiers, IList optionalModifiers) => + module.UpdateRowId(ImportAsTypeSig(type, requiredModifiers, optionalModifiers).ToTypeDefOrRef()); /// /// Imports a as a /// /// The type /// The imported type or null if is invalid - public TypeSig ImportAsTypeSig(Type type) { - return ImportAsTypeSig(type, false); - } + public TypeSig ImportAsTypeSig(Type type) => ImportAsTypeSig(type, false); TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { if (type == null) @@ -251,8 +238,7 @@ TypeDef GetDeclaringType(MemberRef mr) { if (mr == null) return null; - var td = mr.Class as TypeDef; - if (td != null) + if (mr.Class is TypeDef td) return td; td = TryResolve(mr.Class as TypeRef) as TypeDef; @@ -276,19 +262,17 @@ bool IsThisModule(TypeRef tr) { if (module == scopeType.ResolutionScope) return true; - var modRef = scopeType.ResolutionScope as ModuleRef; - if (modRef != null) + if (scopeType.ResolutionScope is ModuleRef modRef) return IsThisModule(modRef); var asmRef = scopeType.ResolutionScope as AssemblyRef; return Equals(module.Assembly, asmRef); } - bool IsThisModule(ModuleRef modRef) { - return modRef != null && - module.Name == modRef.Name && - Equals(module.Assembly, modRef.DefinitionAssembly); - } + bool IsThisModule(ModuleRef modRef) => + modRef != null && + module.Name == modRef.Name && + Equals(module.Assembly, modRef.DefinitionAssembly); static bool Equals(IAssembly a, IAssembly b) { if (a == b) @@ -301,9 +285,7 @@ static bool Equals(IAssembly a, IAssembly b) { UTF8String.CaseInsensitiveEquals(a.Culture, b.Culture); } - ITypeDefOrRef CreateTypeRef(Type type) { - return TryResolve(CreateTypeRef2(type)); - } + ITypeDefOrRef CreateTypeRef(Type type) => TryResolve(CreateTypeRef2(type)); TypeRef CreateTypeRef2(Type type) { if (!type.IsNested) @@ -336,9 +318,8 @@ IResolutionScope CreateScopeReference(Type type) { /// A list of all required modifiers or null /// A list of all optional modifiers or null /// The imported type or null if is invalid - public TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers) { - return ImportAsTypeSig(type, requiredModifiers, optionalModifiers, false); - } + public TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers) => + ImportAsTypeSig(type, requiredModifiers, optionalModifiers, false); TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers, bool treatAsGenericInst) { if (type == null) @@ -366,9 +347,7 @@ TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList op return ts; } - static bool IsEmpty(IList list) { - return list == null || list.Count == 0; - } + static bool IsEmpty(IList list) => list == null || list.Count == 0; /// /// Imports a as a . This will be either @@ -377,9 +356,7 @@ static bool IsEmpty(IList list) { /// The method /// The imported method or null if is invalid /// or if we failed to import the method - public IMethod Import(MethodBase methodBase) { - return Import(methodBase, false); - } + public IMethod Import(MethodBase methodBase) => Import(methodBase, false); /// /// Imports a as a . This will be either @@ -395,9 +372,7 @@ public IMethod Import(MethodBase methodBase, bool forceFixSignature) { return ImportInternal(methodBase, forceFixSignature); } - IMethod ImportInternal(MethodBase methodBase) { - return ImportInternal(methodBase, false); - } + IMethod ImportInternal(MethodBase methodBase) => ImportInternal(methodBase, false); IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { if (methodBase == null) @@ -462,8 +437,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { MethodSig CreateMethodSig(MethodBase mb) { var sig = new MethodSig(GetCallingConvention(mb)); - var mi = mb as MethodInfo; - if (mi != null) + if (mb is MethodInfo mi) sig.RetType = ImportAsTypeSig(mi.ReturnParameter, mb.DeclaringType); else sig.RetType = module.CorLibTypes.Void; @@ -477,9 +451,8 @@ MethodSig CreateMethodSig(MethodBase mb) { return sig; } - TypeSig ImportAsTypeSig(ParameterInfo p, Type declaringType) { - return ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType.MustTreatTypeAsGenericInstType(p.ParameterType)); - } + TypeSig ImportAsTypeSig(ParameterInfo p, Type declaringType) => + ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType.MustTreatTypeAsGenericInstType(p.ParameterType)); CallingConvention GetCallingConvention(MethodBase mb) { CallingConvention cc = 0; @@ -535,9 +508,7 @@ IMemberRefParent GetModuleParent(Module module2) { /// The field /// The imported field or null if is invalid /// or if we failed to import the field - public IField Import(FieldInfo fieldInfo) { - return Import(fieldInfo, false); - } + public IField Import(FieldInfo fieldInfo) => Import(fieldInfo, false); /// /// Imports a as a @@ -687,9 +658,7 @@ IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { /// /// The type /// The imported type or null - public ITypeDefOrRef Import(TypeRef type) { - return TryResolve(Import2(type)); - } + public ITypeDefOrRef Import(TypeRef type) => TryResolve(Import2(type)); TypeRef Import2(TypeRef type) { if (type == null) @@ -792,9 +761,7 @@ public TypeSig Import(TypeSig type) { return result; } - ITypeDefOrRef Import(ITypeDefOrRef type) { - return (ITypeDefOrRef)Import((IType)type); - } + ITypeDefOrRef Import(ITypeDefOrRef type) => (ITypeDefOrRef)Import((IType)type); TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); @@ -864,7 +831,7 @@ public MethodSig Import(MethodSig sig) { if (!recursionCounter.Increment()) return null; - MethodSig result = Import(new MethodSig(sig.GetCallingConvention()), sig); + var result = Import(new MethodSig(sig.GetCallingConvention()), sig); recursionCounter.Decrement(); return result; @@ -894,7 +861,7 @@ public PropertySig Import(PropertySig sig) { if (!recursionCounter.Increment()) return null; - PropertySig result = Import(new PropertySig(sig.GetCallingConvention()), sig); + var result = Import(new PropertySig(sig.GetCallingConvention()), sig); recursionCounter.Decrement(); return result; @@ -911,7 +878,7 @@ public LocalSig Import(LocalSig sig) { if (!recursionCounter.Increment()) return null; - LocalSig result = new LocalSig(sig.GetCallingConvention(), (uint)sig.Locals.Count); + var result = new LocalSig(sig.GetCallingConvention(), (uint)sig.Locals.Count); foreach (var l in sig.Locals.GetSafeEnumerable()) result.Locals.Add(Import(l)); @@ -930,7 +897,7 @@ public GenericInstMethodSig Import(GenericInstMethodSig sig) { if (!recursionCounter.Increment()) return null; - GenericInstMethodSig result = new GenericInstMethodSig(sig.GetCallingConvention(), (uint)sig.GenericArguments.Count); + var result = new GenericInstMethodSig(sig.GetCallingConvention(), (uint)sig.GenericArguments.Count); foreach (var l in sig.GenericArguments.GetSafeEnumerable()) result.GenericArguments.Add(Import(l)); @@ -1017,10 +984,8 @@ public IField Import(FieldDef field) { IMemberRefParent ImportParent(TypeDef type) { if (type == null) return null; - if (type.IsGlobalModuleType) { - var om = type.Module; - return module.UpdateRowId(new ModuleRefUser(module, om == null ? null : om.Name)); - } + if (type.IsGlobalModuleType) + return module.UpdateRowId(new ModuleRefUser(module, type.Module?.Name)); return Import(type); } @@ -1085,22 +1050,16 @@ public MemberRef Import(MemberRef memberRef) { } IMemberRefParent Import(IMemberRefParent parent) { - var tdr = parent as ITypeDefOrRef; - if (tdr != null) { - var td = tdr as TypeDef; - if (td != null && td.IsGlobalModuleType) { - var om = td.Module; - return module.UpdateRowId(new ModuleRefUser(module, om == null ? null : om.Name)); - } + if (parent is ITypeDefOrRef tdr) { + if (tdr is TypeDef td && td.IsGlobalModuleType) + return module.UpdateRowId(new ModuleRefUser(module, td.Module?.Name)); return Import(tdr); } - var modRef = parent as ModuleRef; - if (modRef != null) + if (parent is ModuleRef modRef) return module.UpdateRowId(new ModuleRefUser(module, modRef.Name)); - var method = parent as MethodDef; - if (method != null) { + if (parent is MethodDef method) { var dt = method.DeclaringType; return dt == null || dt.Module != module ? null : method; } diff --git a/src/DotNet/InterfaceImpl.cs b/src/DotNet/InterfaceImpl.cs index 416ef1f2c..7b64d7bea 100644 --- a/src/DotNet/InterfaceImpl.cs +++ b/src/DotNet/InterfaceImpl.cs @@ -25,27 +25,23 @@ public abstract class InterfaceImpl : IHasCustomAttribute, IContainsGenericParam protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.InterfaceImpl, rid); } - } + public MDToken MDToken => new MDToken(Table.InterfaceImpl, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 5; } - } + public int HasCustomAttributeTag => 5; /// /// From column InterfaceImpl.Interface /// public ITypeDefOrRef Interface { - get { return @interface; } - set { @interface = value; } + get => @interface; + set => @interface = value; } /// protected ITypeDefOrRef @interface; @@ -63,24 +59,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 5; } - } + public int HasCustomDebugInformationTag => 5; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -95,13 +84,10 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } - bool IContainsGenericParameter.ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); } /// @@ -118,9 +104,7 @@ public InterfaceImplUser() { /// Constructor /// /// The interface the type implements - public InterfaceImplUser(ITypeDefOrRef @interface) { - this.@interface = @interface; - } + public InterfaceImplUser(ITypeDefOrRef @interface) => this.@interface = @interface; } /// @@ -134,9 +118,7 @@ sealed class InterfaceImplMD : InterfaceImpl, IMDTokenProviderMD { readonly GenericParamContext gpContext; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -165,9 +147,9 @@ public InterfaceImplMD(ModuleDefMD readerModule, uint rid, GenericParamContext g if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.InterfaceImplTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("InterfaceImpl rid {0} does not exist", rid)); + throw new BadImageFormatException($"InterfaceImpl rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; this.gpContext = gpContext; diff --git a/src/DotNet/MD/BlobStream.cs b/src/DotNet/MD/BlobStream.cs index 1d324d605..a679765d9 100644 --- a/src/DotNet/MD/BlobStream.cs +++ b/src/DotNet/MD/BlobStream.cs @@ -31,8 +31,7 @@ public byte[] Read(uint offset) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - IImageStream reader; - int size = GetReader_NoLock(offset, out reader); + int size = GetReader_NoLock(offset, out var reader); if (size < 0) return null; return reader.ReadBytes(size); @@ -47,9 +46,7 @@ public byte[] Read(uint offset) { /// /// Offset of data /// The data - public byte[] ReadNoNull(uint offset) { - return Read(offset) ?? noData; - } + public byte[] ReadNoNull(uint offset) => Read(offset) ?? noData; /// /// Creates a new sub stream of the #Blob stream that can access one blob @@ -60,8 +57,7 @@ public IImageStream CreateStream(uint offset) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - IImageStream reader; - int size = GetReader_NoLock(offset, out reader); + int size = GetReader_NoLock(offset, out var reader); if (size < 0) return MemoryImageStream.CreateEmpty(); return reader.Create((FileOffset)reader.Position, size); @@ -75,8 +71,7 @@ int GetReader_NoLock(uint offset, out IImageStream reader) { if (!IsValidOffset(offset)) return -1; reader = GetReader_NoLock(offset); - uint length; - if (!reader.ReadCompressedUInt32(out length)) + if (!reader.ReadCompressedUInt32(out uint length)) return -1; if (reader.Position + length < length || reader.Position + length > reader.Length) return -1; diff --git a/src/DotNet/MD/CodedToken.cs b/src/DotNet/MD/CodedToken.cs index 6731fee14..ad1aff2eb 100644 --- a/src/DotNet/MD/CodedToken.cs +++ b/src/DotNet/MD/CodedToken.cs @@ -96,16 +96,12 @@ public sealed class CodedToken { /// /// Returns all types of tables /// - public Table[] TableTypes { - get { return tableTypes; } - } + public Table[] TableTypes => tableTypes; /// /// Returns the number of bits that is used to encode table type /// - public int Bits { - get { return bits; } - } + public int Bits => bits; /// /// Constructor @@ -114,7 +110,7 @@ public int Bits { /// All table types internal CodedToken(int bits, Table[] tableTypes) { this.bits = bits; - this.mask = (1 << bits) - 1; + mask = (1 << bits) - 1; this.tableTypes = tableTypes; } @@ -124,9 +120,7 @@ internal CodedToken(int bits, Table[] tableTypes) { /// The token /// Coded token /// - public uint Encode(MDToken token) { - return Encode(token.Raw); - } + public uint Encode(MDToken token) => Encode(token.Raw); /// /// Encodes a token @@ -135,8 +129,7 @@ public uint Encode(MDToken token) { /// Coded token /// public uint Encode(uint token) { - uint codedToken; - Encode(token, out codedToken); + Encode(token, out uint codedToken); return codedToken; } @@ -146,9 +139,7 @@ public uint Encode(uint token) { /// The token /// Coded token /// true if successful - public bool Encode(MDToken token, out uint codedToken) { - return Encode(token.Raw, out codedToken); - } + public bool Encode(MDToken token, out uint codedToken) => Encode(token.Raw, out codedToken); /// /// Encodes a token @@ -175,8 +166,7 @@ public bool Encode(uint token, out uint codedToken) { /// Decoded token or 0 on failure /// public MDToken Decode2(uint codedToken) { - uint token; - Decode(codedToken, out token); + Decode(codedToken, out uint token); return new MDToken(token); } @@ -187,8 +177,7 @@ public MDToken Decode2(uint codedToken) { /// Decoded token or 0 on failure /// public uint Decode(uint codedToken) { - uint token; - Decode(codedToken, out token); + Decode(codedToken, out uint token); return token; } @@ -199,8 +188,7 @@ public uint Decode(uint codedToken) { /// Decoded token /// true if successful public bool Decode(uint codedToken, out MDToken token) { - uint decodedToken; - bool result = Decode(codedToken, out decodedToken); + bool result = Decode(codedToken, out uint decodedToken); token = new MDToken(decodedToken); return result; } diff --git a/src/DotNet/MD/ColumnInfo.cs b/src/DotNet/MD/ColumnInfo.cs index cab756e4d..5bbafed09 100644 --- a/src/DotNet/MD/ColumnInfo.cs +++ b/src/DotNet/MD/ColumnInfo.cs @@ -20,39 +20,33 @@ public sealed class ColumnInfo { /// /// Gets the column index /// - public int Index { - get { return index; } - } + public int Index => index; /// /// Returns the column offset within the table row /// public int Offset { - get { return offset; } - internal set { offset = (byte)value; } + get => offset; + internal set => offset = (byte)value; } /// /// Returns the column size /// public int Size { - get { return size; } - internal set { size = (byte)value; } + get => size; + internal set => size = (byte)value; } /// /// Returns the column name /// - public string Name { - get { return name; } - } + public string Name => name; /// /// Returns the ColumnSize enum value /// - public ColumnSize ColumnSize { - get { return columnSize; } - } + public ColumnSize ColumnSize => columnSize; /// /// Constructor diff --git a/src/DotNet/MD/CompressedMetaData.cs b/src/DotNet/MD/CompressedMetaData.cs index 022cea8ed..452aff002 100644 --- a/src/DotNet/MD/CompressedMetaData.cs +++ b/src/DotNet/MD/CompressedMetaData.cs @@ -14,9 +14,7 @@ namespace dnlib.DotNet.MD { /// sealed class CompressedMetaData : MetaData { /// - public override bool IsCompressed { - get { return true; } - } + public override bool IsCompressed => true; /// public CompressedMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeader mdHeader) @@ -248,29 +246,19 @@ void InitializeHotStreams(IList hotStreams) { } /// - public override RidList GetFieldRidList(uint typeDefRid) { - return GetRidList(tablesStream.TypeDefTable, typeDefRid, 4, tablesStream.FieldTable); - } + public override RidList GetFieldRidList(uint typeDefRid) => GetRidList(tablesStream.TypeDefTable, typeDefRid, 4, tablesStream.FieldTable); /// - public override RidList GetMethodRidList(uint typeDefRid) { - return GetRidList(tablesStream.TypeDefTable, typeDefRid, 5, tablesStream.MethodTable); - } + public override RidList GetMethodRidList(uint typeDefRid) => GetRidList(tablesStream.TypeDefTable, typeDefRid, 5, tablesStream.MethodTable); /// - public override RidList GetParamRidList(uint methodRid) { - return GetRidList(tablesStream.MethodTable, methodRid, 5, tablesStream.ParamTable); - } + public override RidList GetParamRidList(uint methodRid) => GetRidList(tablesStream.MethodTable, methodRid, 5, tablesStream.ParamTable); /// - public override RidList GetEventRidList(uint eventMapRid) { - return GetRidList(tablesStream.EventMapTable, eventMapRid, 1, tablesStream.EventTable); - } + public override RidList GetEventRidList(uint eventMapRid) => GetRidList(tablesStream.EventMapTable, eventMapRid, 1, tablesStream.EventTable); /// - public override RidList GetPropertyRidList(uint propertyMapRid) { - return GetRidList(tablesStream.PropertyMapTable, propertyMapRid, 1, tablesStream.PropertyTable); - } + public override RidList GetPropertyRidList(uint propertyMapRid) => GetRidList(tablesStream.PropertyMapTable, propertyMapRid, 1, tablesStream.PropertyTable); /// /// Gets a rid list (eg. field list) @@ -310,8 +298,7 @@ protected override uint BinarySearch_NoLock(MDTable tableSource, int keyColIndex uint ridLo = 1, ridHi = tableSource.Rows; while (ridLo <= ridHi) { uint rid = (ridLo + ridHi) / 2; - uint key2; - if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out key2)) + if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out uint key2)) break; // Never happens since rid is valid if (key == key2) return rid; diff --git a/src/DotNet/MD/DotNetStream.cs b/src/DotNet/MD/DotNetStream.cs index 83c753716..43179028f 100644 --- a/src/DotNet/MD/DotNetStream.cs +++ b/src/DotNet/MD/DotNetStream.cs @@ -22,50 +22,38 @@ public class DotNetStream : IFileSection, IDisposable { StreamHeader streamHeader; /// - public FileOffset StartOffset { - get { return imageStream.FileOffset; } - } + public FileOffset StartOffset => imageStream.FileOffset; /// - public FileOffset EndOffset { - get { return imageStream.FileOffset + imageStream.Length; } - } + public FileOffset EndOffset => imageStream.FileOffset + imageStream.Length; /// /// Gets the length of the internal .NET blob stream /// - public long ImageStreamLength { - get { return imageStream.Length; } - } + public long ImageStreamLength => imageStream.Length; /// /// Gets the stream header /// - public StreamHeader StreamHeader { - get { return streamHeader; } - } + public StreamHeader StreamHeader => streamHeader; /// /// Gets the name of the stream /// - public string Name { - get { return streamHeader == null ? string.Empty : streamHeader.Name; } - } + public string Name => streamHeader == null ? string.Empty : streamHeader.Name; /// /// Returns a cloned of the internal .NET blob stream. /// /// A new instance - public IImageStream GetClonedImageStream() { - return imageStream.Clone(); - } + public IImageStream GetClonedImageStream() => imageStream.Clone(); /// /// Default constructor /// public DotNetStream() { - this.imageStream = MemoryImageStream.CreateEmpty(); - this.streamHeader = null; + imageStream = MemoryImageStream.CreateEmpty(); + streamHeader = null; } /// @@ -103,18 +91,14 @@ protected virtual void Dispose(bool disposing) { /// /// The index /// true if the index is valid - public virtual bool IsValidIndex(uint index) { - return IsValidOffset(index); - } + public virtual bool IsValidIndex(uint index) => IsValidOffset(index); /// /// Check whether an offset is within the stream /// /// Stream offset /// true if the offset is valid - public bool IsValidOffset(uint offset) { - return offset == 0 || offset < imageStream.Length; - } + public bool IsValidOffset(uint offset) => offset == 0 || offset < imageStream.Length; /// /// Check whether an offset is within the stream @@ -142,7 +126,7 @@ public abstract class HeapStream : DotNetStream { /// Gets/sets the instance /// internal HotHeapStream HotHeapStream { - set { hotHeapStream = value; } + set => hotHeapStream = value; } /// @@ -161,7 +145,7 @@ protected HeapStream(IImageStream imageStream, StreamHeader streamHeader) /// be the offset of the GUID, not its index /// The heap reader protected IImageStream GetReader_NoLock(uint offset) { - var stream = hotHeapStream == null ? null : hotHeapStream.GetBlobReader(offset); + var stream = hotHeapStream?.GetBlobReader(offset); if (stream == null) { stream = imageStream; stream.Position = offset; diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index d3877fd88..82fe5778e 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -13,9 +13,7 @@ public sealed class DotNetTableSizes { bool bigBlob; TableInfo[] tableInfos; - internal static bool IsSystemTable(Table table) { - return table < Table.Document; - } + internal static bool IsSystemTable(Table table) => table < Table.Document; /// /// Initializes the table sizes @@ -65,7 +63,7 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { case ColumnSize.ResolutionScope: info = CodedToken.ResolutionScope; break; case ColumnSize.TypeOrMethodDef: info = CodedToken.TypeOrMethodDef; break; case ColumnSize.HasCustomDebugInformation:info = CodedToken.HasCustomDebugInformation; break; - default: throw new InvalidOperationException(string.Format("Invalid ColumnSize: {0}", columnSize)); + default: throw new InvalidOperationException($"Invalid ColumnSize: {columnSize}"); } uint maxRows = 0; foreach (var tableType in info.TableTypes) { @@ -90,7 +88,7 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { case ColumnSize.Blob: return bigBlob ? 4 : 2; } } - throw new InvalidOperationException(string.Format("Invalid ColumnSize: {0}", columnSize)); + throw new InvalidOperationException($"Invalid ColumnSize: {columnSize}"); } /// @@ -99,10 +97,8 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { /// Major table version /// Minor table version /// All table infos (not completely initialized) - public TableInfo[] CreateTables(byte majorVersion, byte minorVersion) { - int maxPresentTables; - return CreateTables(majorVersion, minorVersion, out maxPresentTables); - } + public TableInfo[] CreateTables(byte majorVersion, byte minorVersion) => + CreateTables(majorVersion, minorVersion, out int maxPresentTables); internal const int normalMaxTables = (int)Table.CustomDebugInformation + 1; diff --git a/src/DotNet/MD/ENCMetaData.cs b/src/DotNet/MD/ENCMetaData.cs index 95783b99d..8f43de3e2 100644 --- a/src/DotNet/MD/ENCMetaData.cs +++ b/src/DotNet/MD/ENCMetaData.cs @@ -21,9 +21,7 @@ sealed class ENCMetaData : MetaData { #endif /// - public override bool IsCompressed { - get { return false; } - } + public override bool IsCompressed => false; /// public ENCMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeader mdHeader) @@ -190,8 +188,7 @@ public override RidList GetExportedTypeRidList() { uint ToFieldRid(uint listRid) { if (!hasFieldPtr) return listRid; - uint listValue; - return tablesStream.ReadColumn(tablesStream.FieldPtrTable, listRid, 0, out listValue) ? listValue : 0; + return tablesStream.ReadColumn(tablesStream.FieldPtrTable, listRid, 0, out uint listValue) ? listValue : 0; } /// @@ -202,8 +199,7 @@ uint ToFieldRid(uint listRid) { uint ToMethodRid(uint listRid) { if (!hasMethodPtr) return listRid; - uint listValue; - return tablesStream.ReadColumn(tablesStream.MethodPtrTable, listRid, 0, out listValue) ? listValue : 0; + return tablesStream.ReadColumn(tablesStream.MethodPtrTable, listRid, 0, out uint listValue) ? listValue : 0; } /// @@ -214,8 +210,7 @@ uint ToMethodRid(uint listRid) { uint ToParamRid(uint listRid) { if (!hasParamPtr) return listRid; - uint listValue; - return tablesStream.ReadColumn(tablesStream.ParamPtrTable, listRid, 0, out listValue) ? listValue : 0; + return tablesStream.ReadColumn(tablesStream.ParamPtrTable, listRid, 0, out uint listValue) ? listValue : 0; } /// @@ -226,8 +221,7 @@ uint ToParamRid(uint listRid) { uint ToEventRid(uint listRid) { if (!hasEventPtr) return listRid; - uint listValue; - return tablesStream.ReadColumn(tablesStream.EventPtrTable, listRid, 0, out listValue) ? listValue : 0; + return tablesStream.ReadColumn(tablesStream.EventPtrTable, listRid, 0, out uint listValue) ? listValue : 0; } /// @@ -238,8 +232,7 @@ uint ToEventRid(uint listRid) { uint ToPropertyRid(uint listRid) { if (!hasPropertyPtr) return listRid; - uint listValue; - return tablesStream.ReadColumn(tablesStream.PropertyPtrTable, listRid, 0, out listValue) ? listValue : 0; + return tablesStream.ReadColumn(tablesStream.PropertyPtrTable, listRid, 0, out uint listValue) ? listValue : 0; } /// @@ -409,8 +402,7 @@ protected override uint BinarySearch_NoLock(MDTable tableSource, int keyColIndex uint ridLo = 1, ridHi = tableSource.Rows; while (ridLo <= ridHi) { uint rid = (ridLo + ridHi) / 2; - uint key2; - if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out key2)) + if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out uint key2)) break; // Never happens since rid is valid if (key == key2) return rid; @@ -439,8 +431,7 @@ uint LinearSearch_NoLock(MDTable tableSource, int keyColIndex, uint key) { return 0; var keyColumn = tableSource.TableInfo.Columns[keyColIndex]; for (uint rid = 1; rid <= tableSource.Rows; rid++) { - uint key2; - if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out key2)) + if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out uint key2)) break; // Never happens since rid is valid if (key == key2) return rid; diff --git a/src/DotNet/MD/GuidStream.cs b/src/DotNet/MD/GuidStream.cs index dbbfca061..b1c7e4baa 100644 --- a/src/DotNet/MD/GuidStream.cs +++ b/src/DotNet/MD/GuidStream.cs @@ -18,9 +18,7 @@ public GuidStream(IImageStream imageStream, StreamHeader streamHeader) } /// - public override bool IsValidIndex(uint index) { - return index == 0 || (index <= 0x10000000 && IsValidOffset((index - 1) * 16, 16)); - } + public override bool IsValidIndex(uint index) => index == 0 || (index <= 0x10000000 && IsValidOffset((index - 1) * 16, 16)); /// /// Read a diff --git a/src/DotNet/MD/HotHeapStream.cs b/src/DotNet/MD/HotHeapStream.cs index 2d085dacd..3a7edc02f 100644 --- a/src/DotNet/MD/HotHeapStream.cs +++ b/src/DotNet/MD/HotHeapStream.cs @@ -24,9 +24,7 @@ abstract class HotHeapStream : IDisposable { /// /// Gets the heap type /// - public HeapType HeapType { - get { return heapType; } - } + public HeapType HeapType => heapType; /// /// Constructor @@ -53,8 +51,7 @@ protected HotHeapStream(HeapType heapType, IImageStream reader, long baseOffset) /// be (index - 1) * 16 /// The reader (owned by us) or null if the data isn't present public IImageStream GetBlobReader(uint originalHeapOffset) { - long dataOffset; - if (GetBlobOffset(originalHeapOffset, out dataOffset)) { + if (GetBlobOffset(originalHeapOffset, out long dataOffset)) { reader.Position = dataOffset; return reader; } diff --git a/src/DotNet/MD/HotStream.cs b/src/DotNet/MD/HotStream.cs index 9d84cd90f..6284e93e5 100644 --- a/src/DotNet/MD/HotStream.cs +++ b/src/DotNet/MD/HotStream.cs @@ -86,7 +86,7 @@ protected HotStream(IImageStream imageStream, StreamHeader streamHeader, IImageS : base(imageStream, streamHeader) { this.fullStream = fullStream; this.baseOffset = (long)baseOffset; - this.endOffset = (long)baseOffset + imageStream.Length; + endOffset = (long)baseOffset + imageStream.Length; } [HandleProcessCorruptedStateExceptions, SecurityCritical] // Req'd on .NET 4.0 @@ -121,9 +121,7 @@ ThreadSafe.IList CreateHotHeapStreams2() { long dirBaseOffs = GetHotHeapDirectoryBaseOffset(); for (long offs = dirBaseOffs; offs + 8 <= endOffset - 8; offs += 8) { fullStream.Position = offs; - HeapType heapType; - long hotHeapOffset; - ReadHotHeapDirectory(fullStream, dirBaseOffs, out heapType, out hotHeapOffset); + ReadHotHeapDirectory(fullStream, dirBaseOffs, out var heapType, out long hotHeapOffset); IImageStream dataStream = null; HotHeapStream hotHeapStream = null; @@ -251,9 +249,8 @@ protected override void ReadHotHeapDirectory(IImageStream reader, long dirBaseOf } /// - protected override HotHeapStream CreateHotHeapStream(HeapType heapType, IImageStream stream, long baseOffset) { - return new HotHeapStreamCLR20(heapType, stream, baseOffset); - } + protected override HotHeapStream CreateHotHeapStream(HeapType heapType, IImageStream stream, long baseOffset) => + new HotHeapStreamCLR20(heapType, stream, baseOffset); } /// @@ -299,8 +296,7 @@ protected override void ReadHotHeapDirectory(IImageStream reader, long dirBaseOf } /// - protected override HotHeapStream CreateHotHeapStream(HeapType heapType, IImageStream stream, long baseOffset) { - return new HotHeapStreamCLR40(heapType, stream, baseOffset); - } + protected override HotHeapStream CreateHotHeapStream(HeapType heapType, IImageStream stream, long baseOffset) => + new HotHeapStreamCLR40(heapType, stream, baseOffset); } } diff --git a/src/DotNet/MD/HotTableStream.cs b/src/DotNet/MD/HotTableStream.cs index a49d73854..59a58c544 100644 --- a/src/DotNet/MD/HotTableStream.cs +++ b/src/DotNet/MD/HotTableStream.cs @@ -41,8 +41,7 @@ protected HotTableStream(IImageStream fullStream, long baseOffset) { /// A valid row ID (i.e., >= 1 and <= number of rows) /// The reader (owned by us) or null if the row isn't present public IImageStream GetTableReader(MDTable table, uint rid) { - long offset; - if (GetRowOffset(table, rid, out offset)) { + if (GetRowOffset(table, rid, out long offset)) { fullStream.Position = offset; return fullStream; } diff --git a/src/DotNet/MD/ImageCor20Header.cs b/src/DotNet/MD/ImageCor20Header.cs index 5f8019963..8e0135118 100644 --- a/src/DotNet/MD/ImageCor20Header.cs +++ b/src/DotNet/MD/ImageCor20Header.cs @@ -25,93 +25,67 @@ public sealed class ImageCor20Header : FileSection { /// /// Returns true if it has a native header /// - public bool HasNativeHeader { - get { return (flags & ComImageFlags.ILLibrary) != 0; } - } + public bool HasNativeHeader => (flags & ComImageFlags.ILLibrary) != 0; /// /// Returns the IMAGE_COR20_HEADER.cb field /// - public uint CB { - get { return cb; } - } + public uint CB => cb; /// /// Returns the IMAGE_COR20_HEADER.MajorRuntimeVersion field /// - public ushort MajorRuntimeVersion { - get { return majorRuntimeVersion; } - } + public ushort MajorRuntimeVersion => majorRuntimeVersion; /// /// Returns the IMAGE_COR20_HEADER.MinorRuntimeVersion field /// - public ushort MinorRuntimeVersion { - get { return minorRuntimeVersion; } - } + public ushort MinorRuntimeVersion => minorRuntimeVersion; /// /// Returns the IMAGE_COR20_HEADER.MetaData field /// - public ImageDataDirectory MetaData { - get { return metaData; } - } + public ImageDataDirectory MetaData => metaData; /// /// Returns the IMAGE_COR20_HEADER.Flags field /// - public ComImageFlags Flags { - get { return flags; } - } + public ComImageFlags Flags => flags; /// /// Returns the IMAGE_COR20_HEADER.EntryPointToken/EntryPointTokenRVA field /// - public uint EntryPointToken_or_RVA { - get { return entryPointToken_or_RVA; } - } + public uint EntryPointToken_or_RVA => entryPointToken_or_RVA; /// /// Returns the IMAGE_COR20_HEADER.Resources field /// - public ImageDataDirectory Resources { - get { return resources; } - } + public ImageDataDirectory Resources => resources; /// /// Returns the IMAGE_COR20_HEADER.StrongNameSignature field /// - public ImageDataDirectory StrongNameSignature { - get { return strongNameSignature; } - } + public ImageDataDirectory StrongNameSignature => strongNameSignature; /// /// Returns the IMAGE_COR20_HEADER.CodeManagerTable field /// - public ImageDataDirectory CodeManagerTable { - get { return codeManagerTable; } - } + public ImageDataDirectory CodeManagerTable => codeManagerTable; /// /// Returns the IMAGE_COR20_HEADER.VTableFixups field /// - public ImageDataDirectory VTableFixups { - get { return vtableFixups; } - } + public ImageDataDirectory VTableFixups => vtableFixups; /// /// Returns the IMAGE_COR20_HEADER.ExportAddressTableJumps field /// - public ImageDataDirectory ExportAddressTableJumps { - get { return exportAddressTableJumps; } - } + public ImageDataDirectory ExportAddressTableJumps => exportAddressTableJumps; /// /// Returns the IMAGE_COR20_HEADER.ManagedNativeHeader field /// - public ImageDataDirectory ManagedNativeHeader { - get { return managedNativeHeader; } - } + public ImageDataDirectory ManagedNativeHeader => managedNativeHeader; /// /// Constructor @@ -121,20 +95,20 @@ public ImageDataDirectory ManagedNativeHeader { /// Thrown if verification fails public ImageCor20Header(IImageStream reader, bool verify) { SetStartOffset(reader); - this.cb = reader.ReadUInt32(); - if (verify && this.cb < 0x48) + cb = reader.ReadUInt32(); + if (verify && cb < 0x48) throw new BadImageFormatException("Invalid IMAGE_COR20_HEADER.cb value"); - this.majorRuntimeVersion = reader.ReadUInt16(); - this.minorRuntimeVersion = reader.ReadUInt16(); - this.metaData = new ImageDataDirectory(reader, verify); - this.flags = (ComImageFlags)reader.ReadUInt32(); - this.entryPointToken_or_RVA = reader.ReadUInt32(); - this.resources = new ImageDataDirectory(reader, verify); - this.strongNameSignature = new ImageDataDirectory(reader, verify); - this.codeManagerTable = new ImageDataDirectory(reader, verify); - this.vtableFixups = new ImageDataDirectory(reader, verify); - this.exportAddressTableJumps = new ImageDataDirectory(reader, verify); - this.managedNativeHeader = new ImageDataDirectory(reader, verify); + majorRuntimeVersion = reader.ReadUInt16(); + minorRuntimeVersion = reader.ReadUInt16(); + metaData = new ImageDataDirectory(reader, verify); + flags = (ComImageFlags)reader.ReadUInt32(); + entryPointToken_or_RVA = reader.ReadUInt32(); + resources = new ImageDataDirectory(reader, verify); + strongNameSignature = new ImageDataDirectory(reader, verify); + codeManagerTable = new ImageDataDirectory(reader, verify); + vtableFixups = new ImageDataDirectory(reader, verify); + exportAddressTableJumps = new ImageDataDirectory(reader, verify); + managedNativeHeader = new ImageDataDirectory(reader, verify); SetEndoffset(reader); } } diff --git a/src/DotNet/MD/MDTable.cs b/src/DotNet/MD/MDTable.cs index 9d97122a5..a08e814a8 100644 --- a/src/DotNet/MD/MDTable.cs +++ b/src/DotNet/MD/MDTable.cs @@ -17,74 +17,54 @@ public sealed class MDTable : IDisposable, IFileSection { IImageStream imageStream; // Fix for VS2015 expression evaluator: "The debugger is unable to evaluate this expression" - int Count { - get { return tableInfo.Columns.Count; } - } + int Count => tableInfo.Columns.Count; /// - public FileOffset StartOffset { - get { return imageStream.FileOffset; } - } + public FileOffset StartOffset => imageStream.FileOffset; /// - public FileOffset EndOffset { - get { return imageStream.FileOffset + imageStream.Length; } - } + public FileOffset EndOffset => imageStream.FileOffset + imageStream.Length; /// /// Gets the table /// - public Table Table { - get { return table; } - } + public Table Table => table; /// /// Gets the name of this table /// - public string Name { - get { return tableInfo.Name; } - } + public string Name => tableInfo.Name; /// /// Returns total number of rows /// - public uint Rows { - get { return numRows; } - } + public uint Rows => numRows; /// /// Gets the total size in bytes of one row in this table /// - public uint RowSize { - get { return (uint)tableInfo.RowSize; } - } + public uint RowSize => (uint)tableInfo.RowSize; /// /// Returns all the columns /// - public IList Columns { - get { return tableInfo.Columns; } - } + public IList Columns => tableInfo.Columns; /// /// Returns true if there are no valid rows /// - public bool IsEmpty { - get { return numRows == 0; } - } + public bool IsEmpty => numRows == 0; /// /// Returns info about this table /// - public TableInfo TableInfo { - get { return tableInfo; } - } + public TableInfo TableInfo => tableInfo; /// /// The stream that can access all the rows in this table /// internal IImageStream ImageStream { - get { return imageStream; } + get => imageStream; set { var ims = imageStream; if (ims == value) @@ -107,25 +87,19 @@ internal MDTable(Table table, uint numRows, TableInfo tableInfo) { this.tableInfo = tableInfo; } - internal IImageStream CloneImageStream() { - return imageStream.Clone(); - } + internal IImageStream CloneImageStream() => imageStream.Clone(); /// /// Checks whether the row exists /// /// Row ID - public bool IsValidRID(uint rid) { - return rid != 0 && rid <= numRows; - } + public bool IsValidRID(uint rid) => rid != 0 && rid <= numRows; /// /// Checks whether the row does not exist /// /// Row ID - public bool IsInvalidRID(uint rid) { - return rid == 0 || rid > numRows; - } + public bool IsInvalidRID(uint rid) => rid == 0 || rid > numRows; /// public void Dispose() { diff --git a/src/DotNet/MD/MetaData.cs b/src/DotNet/MD/MetaData.cs index 149cc1e92..fc39cb44b 100644 --- a/src/DotNet/MD/MetaData.cs +++ b/src/DotNet/MD/MetaData.cs @@ -70,9 +70,7 @@ abstract class MetaData : IMetaData { protected ThreadSafe.IList allStreams; /// - public bool IsStandalonePortablePdb { - get { return isStandalonePortablePdb; } - } + public bool IsStandalonePortablePdb => isStandalonePortablePdb; /// true if this is standalone Portable PDB metadata protected readonly bool isStandalonePortablePdb; @@ -96,7 +94,7 @@ protected sealed class SortedTable { /// Remembers rid and key /// [DebuggerDisplay("{rid} {key}")] - struct RowInfo : IComparable { + readonly struct RowInfo : IComparable { public readonly uint rid; public readonly uint key; @@ -198,69 +196,43 @@ public RidList FindAllRows(uint key) { public abstract bool IsCompressed { get; } /// - public ImageCor20Header ImageCor20Header { - get { return cor20Header; } - } + public ImageCor20Header ImageCor20Header => cor20Header; /// - public ushort MajorVersion { - get { return mdHeader.MajorVersion; } - } + public ushort MajorVersion => mdHeader.MajorVersion; /// - public ushort MinorVersion { - get { return mdHeader.MinorVersion; } - } + public ushort MinorVersion => mdHeader.MinorVersion; /// - public string VersionString { - get { return mdHeader.VersionString; } - } + public string VersionString => mdHeader.VersionString; /// - public IPEImage PEImage { - get { return peImage; } - } + public IPEImage PEImage => peImage; /// - public MetaDataHeader MetaDataHeader { - get { return mdHeader; } - } + public MetaDataHeader MetaDataHeader => mdHeader; /// - public StringsStream StringsStream { - get { return stringsStream; } - } + public StringsStream StringsStream => stringsStream; /// - public USStream USStream { - get { return usStream; } - } + public USStream USStream => usStream; /// - public BlobStream BlobStream { - get { return blobStream; } - } + public BlobStream BlobStream => blobStream; /// - public GuidStream GuidStream { - get { return guidStream; } - } + public GuidStream GuidStream => guidStream; /// - public TablesStream TablesStream { - get { return tablesStream; } - } + public TablesStream TablesStream => tablesStream; /// - public PdbStream PdbStream { - get { return pdbStream; } - } + public PdbStream PdbStream => pdbStream; /// - public ThreadSafe.IList AllStreams { - get { return allStreams; } - } + public ThreadSafe.IList AllStreams => allStreams; /// /// Constructor @@ -270,7 +242,7 @@ public ThreadSafe.IList AllStreams { /// The MD header protected MetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeader mdHeader) { try { - this.allStreams = ThreadSafeListCreator.Create(); + allStreams = ThreadSafeListCreator.Create(); this.peImage = peImage; this.cor20Header = cor20Header; this.mdHeader = mdHeader; @@ -284,9 +256,9 @@ protected MetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeade } internal MetaData(MetaDataHeader mdHeader, bool isStandalonePortablePdb) { - this.allStreams = ThreadSafeListCreator.Create(); - this.peImage = null; - this.cor20Header = null; + allStreams = ThreadSafeListCreator.Create(); + peImage = null; + cor20Header = null; this.mdHeader = mdHeader; this.isStandalonePortablePdb = isStandalonePortablePdb; } @@ -324,14 +296,10 @@ protected void InitializeNonExistentHeaps() { protected abstract void InitializeInternal(IImageStream mdStream); /// - public virtual RidList GetTypeDefRidList() { - return new ContiguousRidList(1, tablesStream.TypeDefTable.Rows); - } + public virtual RidList GetTypeDefRidList() => new ContiguousRidList(1, tablesStream.TypeDefTable.Rows); /// - public virtual RidList GetExportedTypeRidList() { - return new ContiguousRidList(1, tablesStream.ExportedTypeTable.Rows); - } + public virtual RidList GetExportedTypeRidList() => new ContiguousRidList(1, tablesStream.ExportedTypeTable.Rows); /// public abstract RidList GetFieldRidList(uint typeDefRid); @@ -378,15 +346,13 @@ protected RidList FindAllRows(MDTable tableSource, int keyColIndex, uint key) { uint endRid = startRid + 1; var column = tableSource.TableInfo.Columns[keyColIndex]; for (; startRid > 1; startRid--) { - uint key2; - if (!tablesStream.ReadColumn_NoLock(tableSource, startRid - 1, column, out key2)) + if (!tablesStream.ReadColumn_NoLock(tableSource, startRid - 1, column, out uint key2)) break; // Should never happen since startRid is valid if (key != key2) break; } for (; endRid <= tableSource.Rows; endRid++) { - uint key2; - if (!tablesStream.ReadColumn_NoLock(tableSource, endRid, column, out key2)) + if (!tablesStream.ReadColumn_NoLock(tableSource, endRid, column, out uint key2)) break; // Should never happen since endRid is valid if (key != key2) break; @@ -406,56 +372,45 @@ protected RidList FindAllRows(MDTable tableSource, int keyColIndex, uint key) { /// Key column index /// Key /// A instance - protected virtual RidList FindAllRowsUnsorted(MDTable tableSource, int keyColIndex, uint key) { - return FindAllRows(tableSource, keyColIndex, key); - } + protected virtual RidList FindAllRowsUnsorted(MDTable tableSource, int keyColIndex, uint key) => FindAllRows(tableSource, keyColIndex, key); /// - public RidList GetInterfaceImplRidList(uint typeDefRid) { - return FindAllRowsUnsorted(tablesStream.InterfaceImplTable, 0, typeDefRid); - } + public RidList GetInterfaceImplRidList(uint typeDefRid) => FindAllRowsUnsorted(tablesStream.InterfaceImplTable, 0, typeDefRid); /// public RidList GetGenericParamRidList(Table table, uint rid) { - uint codedToken; - if (!CodedToken.TypeOrMethodDef.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.TypeOrMethodDef.Encode(new MDToken(table, rid), out uint codedToken)) return RidList.Empty; return FindAllRowsUnsorted(tablesStream.GenericParamTable, 2, codedToken); } /// - public RidList GetGenericParamConstraintRidList(uint genericParamRid) { - return FindAllRowsUnsorted(tablesStream.GenericParamConstraintTable, 0, genericParamRid); - } + public RidList GetGenericParamConstraintRidList(uint genericParamRid) => + FindAllRowsUnsorted(tablesStream.GenericParamConstraintTable, 0, genericParamRid); /// public RidList GetCustomAttributeRidList(Table table, uint rid) { - uint codedToken; - if (!CodedToken.HasCustomAttribute.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.HasCustomAttribute.Encode(new MDToken(table, rid), out uint codedToken)) return RidList.Empty; return FindAllRowsUnsorted(tablesStream.CustomAttributeTable, 0, codedToken); } /// public RidList GetDeclSecurityRidList(Table table, uint rid) { - uint codedToken; - if (!CodedToken.HasDeclSecurity.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.HasDeclSecurity.Encode(new MDToken(table, rid), out uint codedToken)) return RidList.Empty; return FindAllRowsUnsorted(tablesStream.DeclSecurityTable, 1, codedToken); } /// public RidList GetMethodSemanticsRidList(Table table, uint rid) { - uint codedToken; - if (!CodedToken.HasSemantic.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.HasSemantic.Encode(new MDToken(table, rid), out uint codedToken)) return RidList.Empty; return FindAllRowsUnsorted(tablesStream.MethodSemanticsTable, 2, codedToken); } /// - public RidList GetMethodImplRidList(uint typeDefRid) { - return FindAllRowsUnsorted(tablesStream.MethodImplTable, 0, typeDefRid); - } + public RidList GetMethodImplRidList(uint typeDefRid) => FindAllRowsUnsorted(tablesStream.MethodImplTable, 0, typeDefRid); /// public uint GetClassLayoutRid(uint typeDefRid) { @@ -471,8 +426,7 @@ public uint GetFieldLayoutRid(uint fieldRid) { /// public uint GetFieldMarshalRid(Table table, uint rid) { - uint codedToken; - if (!CodedToken.HasFieldMarshal.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.HasFieldMarshal.Encode(new MDToken(table, rid), out uint codedToken)) return 0; var list = FindAllRowsUnsorted(tablesStream.FieldMarshalTable, 0, codedToken); return list.Length == 0 ? 0 : list[0]; @@ -486,8 +440,7 @@ public uint GetFieldRVARid(uint fieldRid) { /// public uint GetImplMapRid(Table table, uint rid) { - uint codedToken; - if (!CodedToken.MemberForwarded.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.MemberForwarded.Encode(new MDToken(table, rid), out uint codedToken)) return 0; var list = FindAllRowsUnsorted(tablesStream.ImplMapTable, 1, codedToken); return list.Length == 0 ? 0 : list[0]; @@ -521,8 +474,7 @@ public uint GetPropertyMapRid(uint typeDefRid) { /// public uint GetConstantRid(Table table, uint rid) { - uint codedToken; - if (!CodedToken.HasConstant.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.HasConstant.Encode(new MDToken(table, rid), out uint codedToken)) return 0; var list = FindAllRowsUnsorted(tablesStream.ConstantTable, 2, codedToken); return list.Length == 0 ? 0 : list[0]; @@ -669,8 +621,7 @@ void InitializeInverseGenericParamOwnerRidList() { tablesStream.theLock.EnterWriteLock(); try { #endif for (uint rid = 1; rid <= gpTable.Rows; rid++) { - uint owner; - if (!tablesStream.ReadColumn_NoLock(gpTable, rid, ownerCol, out owner)) + if (!tablesStream.ReadColumn_NoLock(gpTable, rid, ownerCol, out uint owner)) continue; ownersDict[owner] = true; } @@ -683,8 +634,7 @@ void InitializeInverseGenericParamOwnerRidList() { var owners = new List(ownersDict.Keys); owners.Sort(); for (int i = 0; i < owners.Count; i++) { - uint ownerToken; - if (!CodedToken.TypeOrMethodDef.Decode(owners[i], out ownerToken)) + if (!CodedToken.TypeOrMethodDef.Decode(owners[i], out uint ownerToken)) continue; var ridList = GetGenericParamRidList(MDToken.ToTable(ownerToken), MDToken.ToRID(ownerToken)); for (uint j = 0; j < ridList.Length; j++) { @@ -722,8 +672,7 @@ void InitializeInverseGenericParamConstraintOwnerRidList() { tablesStream.theLock.EnterWriteLock(); try { #endif for (uint rid = 1; rid <= gpcTable.Rows; rid++) { - uint owner; - if (!tablesStream.ReadColumn_NoLock(gpcTable, rid, ownerCol, out owner)) + if (!tablesStream.ReadColumn_NoLock(gpcTable, rid, ownerCol, out uint owner)) continue; ownersDict[owner] = true; } @@ -778,8 +727,7 @@ void InitializeInverseParamOwnerRidList() { public RidList GetNestedClassRidList(uint typeDefRid) { if (typeDefRidToNestedClasses == null) InitializeNestedClassesDictionary(); - RandomRidList ridList; - if (typeDefRidToNestedClasses.TryGetValue(typeDefRid, out ridList)) + if (typeDefRidToNestedClasses.TryGetValue(typeDefRid, out var ridList)) return ridList; return RidList.Empty; } @@ -817,8 +765,7 @@ void InitializeNestedClassesDictionary() { var row = tablesStream.ReadNestedClassRow(GetNestedClassRid(nestedRid)); if (row == null) continue; - RandomRidList ridList; - if (!newTypeDefRidToNestedClasses.TryGetValue(row.EnclosingClass, out ridList)) + if (!newTypeDefRidToNestedClasses.TryGetValue(row.EnclosingClass, out var ridList)) newTypeDefRidToNestedClasses[row.EnclosingClass] = ridList = new RandomRidList(); ridList.Add(nestedRid); } @@ -846,9 +793,7 @@ public RidList GetNonNestedClassRidList() { return nonNestedTypes; } - public RidList GetLocalScopeRidList(uint methodRid) { - return FindAllRows(tablesStream.LocalScopeTable, 0, methodRid); - } + public RidList GetLocalScopeRidList(uint methodRid) => FindAllRows(tablesStream.LocalScopeTable, 0, methodRid); public uint GetStateMachineMethodRid(uint methodRid) { var list = FindAllRows(tablesStream.StateMachineMethodTable, 0, methodRid); @@ -856,8 +801,7 @@ public uint GetStateMachineMethodRid(uint methodRid) { } public RidList GetCustomDebugInformationRidList(Table table, uint rid) { - uint codedToken; - if (!CodedToken.HasCustomDebugInformation.Encode(new MDToken(table, rid), out codedToken)) + if (!CodedToken.HasCustomDebugInformation.Encode(new MDToken(table, rid), out uint codedToken)) return RidList.Empty; return FindAllRows(tablesStream.CustomDebugInformationTable, 0, codedToken); } diff --git a/src/DotNet/MD/MetaDataCreator.cs b/src/DotNet/MD/MetaDataCreator.cs index dcf6e10e5..ce494eb46 100644 --- a/src/DotNet/MD/MetaDataCreator.cs +++ b/src/DotNet/MD/MetaDataCreator.cs @@ -101,18 +101,14 @@ internal static MetaData Load(IntPtr addr, ImageLayout imageLayout) { /// /// The PE image /// A new instance - internal static MetaData Load(IPEImage peImage) { - return Create(peImage, true); - } + internal static MetaData Load(IPEImage peImage) => Create(peImage, true); /// /// Create a instance /// /// The PE image /// A new instance - public static IMetaData CreateMetaData(IPEImage peImage) { - return Create(peImage, true); - } + public static IMetaData CreateMetaData(IPEImage peImage) => Create(peImage, true); /// /// Create a instance @@ -120,9 +116,7 @@ public static IMetaData CreateMetaData(IPEImage peImage) { /// The PE image /// true if we should verify that it's a .NET PE file /// A new instance - public static IMetaData CreateMetaData(IPEImage peImage, bool verify) { - return Create(peImage, verify); - } + public static IMetaData CreateMetaData(IPEImage peImage, bool verify) => Create(peImage, verify); /// /// Create a instance diff --git a/src/DotNet/MD/MetaDataHeader.cs b/src/DotNet/MD/MetaDataHeader.cs index 54bd5d6c5..aa9853025 100644 --- a/src/DotNet/MD/MetaDataHeader.cs +++ b/src/DotNet/MD/MetaDataHeader.cs @@ -26,79 +26,57 @@ public sealed class MetaDataHeader : FileSection { /// /// Returns the signature (should be 0x424A5342) /// - public uint Signature { - get { return signature; } - } + public uint Signature => signature; /// /// Returns the major version /// - public ushort MajorVersion { - get { return majorVersion; } - } + public ushort MajorVersion => majorVersion; /// /// Returns the minor version /// - public ushort MinorVersion { - get { return minorVersion; } - } + public ushort MinorVersion => minorVersion; /// /// Returns the reserved dword (pointer to extra header data) /// - public uint Reserved1 { - get { return reserved1; } - } + public uint Reserved1 => reserved1; /// /// Returns the version string length value /// - public uint StringLength { - get { return stringLength; } - } + public uint StringLength => stringLength; /// /// Returns the version string /// - public string VersionString { - get { return versionString; } - } + public string VersionString => versionString; /// /// Returns the offset of STORAGEHEADER /// - public FileOffset StorageHeaderOffset { - get { return offset2ndPart; } - } + public FileOffset StorageHeaderOffset => offset2ndPart; /// /// Returns the flags (reserved) /// - public StorageFlags Flags { - get { return flags; } - } + public StorageFlags Flags => flags; /// /// Returns the reserved byte (padding) /// - public byte Reserved2 { - get { return reserved2; } - } + public byte Reserved2 => reserved2; /// /// Returns the number of streams /// - public ushort Streams { - get { return streams; } - } + public ushort Streams => streams; /// /// Returns all stream headers /// - public IList StreamHeaders { - get { return streamHeaders; } - } + public IList StreamHeaders => streamHeaders; /// /// Constructor @@ -108,21 +86,21 @@ public IList StreamHeaders { /// Thrown if verification fails public MetaDataHeader(IImageStream reader, bool verify) { SetStartOffset(reader); - this.signature = reader.ReadUInt32(); - if (verify && this.signature != 0x424A5342) + signature = reader.ReadUInt32(); + if (verify && signature != 0x424A5342) throw new BadImageFormatException("Invalid MetaData header signature"); - this.majorVersion = reader.ReadUInt16(); - this.minorVersion = reader.ReadUInt16(); + majorVersion = reader.ReadUInt16(); + minorVersion = reader.ReadUInt16(); if (verify && !((majorVersion == 1 && minorVersion == 1) || (majorVersion == 0 && minorVersion >= 19))) - throw new BadImageFormatException(string.Format("Unknown MetaData header version: {0}.{1}", majorVersion, minorVersion)); - this.reserved1 = reader.ReadUInt32(); - this.stringLength = reader.ReadUInt32(); - this.versionString = ReadString(reader, stringLength); - this.offset2ndPart = reader.FileOffset + reader.Position; - this.flags = (StorageFlags)reader.ReadByte(); - this.reserved2 = reader.ReadByte(); - this.streams = reader.ReadUInt16(); - this.streamHeaders = new StreamHeader[streams]; + throw new BadImageFormatException($"Unknown MetaData header version: {majorVersion}.{minorVersion}"); + reserved1 = reader.ReadUInt32(); + stringLength = reader.ReadUInt32(); + versionString = ReadString(reader, stringLength); + offset2ndPart = reader.FileOffset + reader.Position; + flags = (StorageFlags)reader.ReadByte(); + reserved2 = reader.ReadByte(); + streams = reader.ReadUInt16(); + streamHeaders = new StreamHeader[streams]; for (int i = 0; i < streamHeaders.Count; i++) streamHeaders[i] = new StreamHeader(reader, verify); SetEndoffset(reader); @@ -132,7 +110,7 @@ static string ReadString(IImageStream reader, uint maxLength) { long endPos = reader.Position + maxLength; if (endPos < reader.Position || endPos > reader.Length) throw new BadImageFormatException("Invalid MD version string"); - byte[] utf8Bytes = new byte[maxLength]; + var utf8Bytes = new byte[maxLength]; uint i; for (i = 0; i < maxLength; i++) { byte b = reader.ReadByte(); diff --git a/src/DotNet/MD/RawRowEqualityComparer.cs b/src/DotNet/MD/RawRowEqualityComparer.cs index 51b64db35..092463e8c 100644 --- a/src/DotNet/MD/RawRowEqualityComparer.cs +++ b/src/DotNet/MD/RawRowEqualityComparer.cs @@ -41,638 +41,510 @@ public sealed class RawRowEqualityComparer : IEqualityComparer, /// public static readonly RawRowEqualityComparer Instance = new RawRowEqualityComparer(); - static int rol(uint val, int shift) { - return (int)((val << shift) | (val >> (32 - shift))); - } - - public bool Equals(RawModuleRow x, RawModuleRow y) { - return x.Generation == y.Generation && - x.Name == y.Name && - x.Mvid == y.Mvid && - x.EncId == y.EncId && - x.EncBaseId == y.EncBaseId; - } - - public int GetHashCode(RawModuleRow obj) { - return obj.Generation + - rol(obj.Name, 3) + - rol(obj.Mvid, 7) + - rol(obj.EncId, 11) + - rol(obj.EncBaseId, 15); - } - - public bool Equals(RawTypeRefRow x, RawTypeRefRow y) { - return x.ResolutionScope == y.ResolutionScope && - x.Name == y.Name && - x.Namespace == y.Namespace; - } - - public int GetHashCode(RawTypeRefRow obj) { - return (int)obj.ResolutionScope + - rol(obj.Name, 3) + - rol(obj.Namespace, 7); - } - - public bool Equals(RawTypeDefRow x, RawTypeDefRow y) { - return x.Flags == y.Flags && - x.Name == y.Name && - x.Namespace == y.Namespace && - x.Extends == y.Extends && - x.FieldList == y.FieldList && - x.MethodList == y.MethodList; - } - - public int GetHashCode(RawTypeDefRow obj) { - return (int)obj.Flags + - rol(obj.Name, 3) + - rol(obj.Namespace, 7) + - rol(obj.Extends, 11) + - rol(obj.FieldList, 15) + - rol(obj.MethodList, 19); - } - - public bool Equals(RawFieldPtrRow x, RawFieldPtrRow y) { - return x.Field == y.Field; - } - - public int GetHashCode(RawFieldPtrRow obj) { - return (int)obj.Field; - } - - public bool Equals(RawFieldRow x, RawFieldRow y) { - return x.Flags == y.Flags && - x.Name == y.Name && - x.Signature == y.Signature; - } - - public int GetHashCode(RawFieldRow obj) { - return (int)obj.Flags + - rol(obj.Name, 3) + - rol(obj.Signature, 7); - } - - public bool Equals(RawMethodPtrRow x, RawMethodPtrRow y) { - return x.Method == y.Method; - } - - public int GetHashCode(RawMethodPtrRow obj) { - return (int)obj.Method; - } - - public bool Equals(RawMethodRow x, RawMethodRow y) { - return x.RVA == y.RVA && - x.ImplFlags == y.ImplFlags && - x.Flags == y.Flags && - x.Name == y.Name && - x.Signature == y.Signature && - x.ParamList == y.ParamList; - } - - public int GetHashCode(RawMethodRow obj) { - return (int)obj.RVA + - rol(obj.ImplFlags, 3) + - rol(obj.Flags, 7) + - rol(obj.Name, 11) + - rol(obj.Signature, 15) + - rol(obj.ParamList, 19); - } - - public bool Equals(RawParamPtrRow x, RawParamPtrRow y) { - return x.Param == y.Param; - } - - public int GetHashCode(RawParamPtrRow obj) { - return (int)obj.Param; - } - - public bool Equals(RawParamRow x, RawParamRow y) { - return x.Flags == y.Flags && - x.Sequence == y.Sequence && - x.Name == y.Name; - } - - public int GetHashCode(RawParamRow obj) { - return (int)obj.Flags + - rol(obj.Sequence, 3) + - rol(obj.Name, 7); - } - - public bool Equals(RawInterfaceImplRow x, RawInterfaceImplRow y) { - return x.Class == y.Class && - x.Interface == y.Interface; - } - - public int GetHashCode(RawInterfaceImplRow obj) { - return (int)obj.Class + - rol(obj.Interface, 3); - } - - public bool Equals(RawMemberRefRow x, RawMemberRefRow y) { - return x.Class == y.Class && - x.Name == y.Name && - x.Signature == y.Signature; - } - - public int GetHashCode(RawMemberRefRow obj) { - return (int)obj.Class + - rol(obj.Name, 3) + - rol(obj.Signature, 7); - } - - public bool Equals(RawConstantRow x, RawConstantRow y) { - return x.Type == y.Type && - x.Padding == y.Padding && - x.Parent == y.Parent && - x.Value == y.Value; - } - - public int GetHashCode(RawConstantRow obj) { - return (int)obj.Type + - rol(obj.Padding, 3) + - rol(obj.Parent, 7) + - rol(obj.Value, 11); - } - - public bool Equals(RawCustomAttributeRow x, RawCustomAttributeRow y) { - return x.Parent == y.Parent && - x.Type == y.Type && - x.Value == y.Value; - } - - public int GetHashCode(RawCustomAttributeRow obj) { - return (int)obj.Parent + - rol(obj.Type, 3) + - rol(obj.Value, 7); - } - - public bool Equals(RawFieldMarshalRow x, RawFieldMarshalRow y) { - return x.Parent == y.Parent && - x.NativeType == y.NativeType; - } - - public int GetHashCode(RawFieldMarshalRow obj) { - return (int)obj.Parent + - rol(obj.NativeType, 3); - } - - public bool Equals(RawDeclSecurityRow x, RawDeclSecurityRow y) { - return x.Action == y.Action && - x.Parent == y.Parent && - x.PermissionSet == y.PermissionSet; - } - - public int GetHashCode(RawDeclSecurityRow obj) { - return (int)obj.Action + - rol(obj.Parent, 3) + - rol(obj.PermissionSet, 7); - } - - public bool Equals(RawClassLayoutRow x, RawClassLayoutRow y) { - return x.PackingSize == y.PackingSize && - x.ClassSize == y.ClassSize && - x.Parent == y.Parent; - } - - public int GetHashCode(RawClassLayoutRow obj) { - return (int)obj.PackingSize + - rol(obj.ClassSize, 3) + - rol(obj.Parent, 7); - } - - public bool Equals(RawFieldLayoutRow x, RawFieldLayoutRow y) { - return x.OffSet == y.OffSet && - x.Field == y.Field; - } - - public int GetHashCode(RawFieldLayoutRow obj) { - return (int)obj.OffSet + - rol(obj.Field, 3); - } - - public bool Equals(RawStandAloneSigRow x, RawStandAloneSigRow y) { - return x.Signature == y.Signature; - } - - public int GetHashCode(RawStandAloneSigRow obj) { - return (int)obj.Signature; - } - - public bool Equals(RawEventMapRow x, RawEventMapRow y) { - return x.Parent == y.Parent && - x.EventList == y.EventList; - } - - public int GetHashCode(RawEventMapRow obj) { - return (int)obj.Parent + - rol(obj.EventList, 3); - } - - public bool Equals(RawEventPtrRow x, RawEventPtrRow y) { - return x.Event == y.Event; - } - - public int GetHashCode(RawEventPtrRow obj) { - return (int)obj.Event; - } - - public bool Equals(RawEventRow x, RawEventRow y) { - return x.EventFlags == y.EventFlags && - x.Name == y.Name && - x.EventType == y.EventType; - } - - public int GetHashCode(RawEventRow obj) { - return (int)obj.EventFlags + - rol(obj.Name, 3) + - rol(obj.EventType, 7); - } - - public bool Equals(RawPropertyMapRow x, RawPropertyMapRow y) { - return x.Parent == y.Parent && - x.PropertyList == y.PropertyList; - } - - public int GetHashCode(RawPropertyMapRow obj) { - return (int)obj.Parent + - rol(obj.PropertyList, 3); - } - - public bool Equals(RawPropertyPtrRow x, RawPropertyPtrRow y) { - return x.Property == y.Property; - } - - public int GetHashCode(RawPropertyPtrRow obj) { - return (int)obj.Property; - } - - public bool Equals(RawPropertyRow x, RawPropertyRow y) { - return x.PropFlags == y.PropFlags && - x.Name == y.Name && - x.Type == y.Type; - } - - public int GetHashCode(RawPropertyRow obj) { - return (int)obj.PropFlags + - rol(obj.Name, 3) + - rol(obj.Type, 7); - } - - public bool Equals(RawMethodSemanticsRow x, RawMethodSemanticsRow y) { - return x.Semantic == y.Semantic && - x.Method == y.Method && - x.Association == y.Association; - } - - public int GetHashCode(RawMethodSemanticsRow obj) { - return (int)obj.Semantic + - rol(obj.Method, 3) + - rol(obj.Association, 7); - } - - public bool Equals(RawMethodImplRow x, RawMethodImplRow y) { - return x.Class == y.Class && - x.MethodBody == y.MethodBody && - x.MethodDeclaration == y.MethodDeclaration; - } - - public int GetHashCode(RawMethodImplRow obj) { - return (int)obj.Class + - rol(obj.MethodBody, 3) + - rol(obj.MethodDeclaration, 7); - } - - public bool Equals(RawModuleRefRow x, RawModuleRefRow y) { - return x.Name == y.Name; - } - - public int GetHashCode(RawModuleRefRow obj) { - return (int)obj.Name; - } - - public bool Equals(RawTypeSpecRow x, RawTypeSpecRow y) { - return x.Signature == y.Signature; - } - - public int GetHashCode(RawTypeSpecRow obj) { - return (int)obj.Signature; - } - - public bool Equals(RawImplMapRow x, RawImplMapRow y) { - return x.MappingFlags == y.MappingFlags && - x.MemberForwarded == y.MemberForwarded && - x.ImportName == y.ImportName && - x.ImportScope == y.ImportScope; - } - - public int GetHashCode(RawImplMapRow obj) { - return (int)obj.MappingFlags + - rol(obj.MemberForwarded, 3) + - rol(obj.ImportName, 7) + - rol(obj.ImportScope, 11); - } - - public bool Equals(RawFieldRVARow x, RawFieldRVARow y) { - return x.RVA == y.RVA && - x.Field == y.Field; - } - - public int GetHashCode(RawFieldRVARow obj) { - return (int)obj.RVA + - rol(obj.Field, 3); - } - - public bool Equals(RawENCLogRow x, RawENCLogRow y) { - return x.Token == y.Token && - x.FuncCode == y.FuncCode; - } - - public int GetHashCode(RawENCLogRow obj) { - return (int)obj.Token + - rol(obj.FuncCode, 3); - } - - public bool Equals(RawENCMapRow x, RawENCMapRow y) { - return x.Token == y.Token; - } - - public int GetHashCode(RawENCMapRow obj) { - return (int)obj.Token; - } - - public bool Equals(RawAssemblyRow x, RawAssemblyRow y) { - return x.HashAlgId == y.HashAlgId && - x.MajorVersion == y.MajorVersion && - x.MinorVersion == y.MinorVersion && - x.BuildNumber == y.BuildNumber && - x.RevisionNumber == y.RevisionNumber && - x.Flags == y.Flags && - x.PublicKey == y.PublicKey && - x.Name == y.Name && - x.Locale == y.Locale; - } - - public int GetHashCode(RawAssemblyRow obj) { - return (int)obj.HashAlgId + - rol(obj.MajorVersion, 3) + - rol(obj.MinorVersion, 7) + - rol(obj.BuildNumber, 11) + - rol(obj.RevisionNumber, 15) + - rol(obj.Flags, 19) + - rol(obj.PublicKey, 23) + - rol(obj.Name, 27) + - rol(obj.Locale, 31); - } - - public bool Equals(RawAssemblyProcessorRow x, RawAssemblyProcessorRow y) { - return x.Processor == y.Processor; - } - - public int GetHashCode(RawAssemblyProcessorRow obj) { - return (int)obj.Processor; - } - - public bool Equals(RawAssemblyOSRow x, RawAssemblyOSRow y) { - return x.OSPlatformId == y.OSPlatformId && - x.OSMajorVersion == y.OSMajorVersion && - x.OSMinorVersion == y.OSMinorVersion; - } - - public int GetHashCode(RawAssemblyOSRow obj) { - return (int)obj.OSPlatformId + - rol(obj.OSMajorVersion, 3) + - rol(obj.OSMinorVersion, 7); - } - - public bool Equals(RawAssemblyRefRow x, RawAssemblyRefRow y) { - return x.MajorVersion == y.MajorVersion && - x.MinorVersion == y.MinorVersion && - x.BuildNumber == y.BuildNumber && - x.RevisionNumber == y.RevisionNumber && - x.Flags == y.Flags && - x.PublicKeyOrToken == y.PublicKeyOrToken && - x.Name == y.Name && - x.Locale == y.Locale && - x.HashValue == y.HashValue; - } - - public int GetHashCode(RawAssemblyRefRow obj) { - return (int)obj.MajorVersion + - rol(obj.MinorVersion, 3) + - rol(obj.BuildNumber, 7) + - rol(obj.RevisionNumber, 11) + - rol(obj.Flags, 15) + - rol(obj.PublicKeyOrToken, 19) + - rol(obj.Name, 23) + - rol(obj.Locale, 27) + - rol(obj.HashValue, 31); - } - - public bool Equals(RawAssemblyRefProcessorRow x, RawAssemblyRefProcessorRow y) { - return x.Processor == y.Processor && - x.AssemblyRef == y.AssemblyRef; - } - - public int GetHashCode(RawAssemblyRefProcessorRow obj) { - return (int)obj.Processor + - rol(obj.AssemblyRef, 3); - } - - public bool Equals(RawAssemblyRefOSRow x, RawAssemblyRefOSRow y) { - return x.OSPlatformId == y.OSPlatformId && - x.OSMajorVersion == y.OSMajorVersion && - x.OSMinorVersion == y.OSMinorVersion && - x.AssemblyRef == y.AssemblyRef; - } - - public int GetHashCode(RawAssemblyRefOSRow obj) { - return (int)obj.OSPlatformId + - rol(obj.OSMajorVersion, 3) + - rol(obj.OSMinorVersion, 7) + - rol(obj.AssemblyRef, 11); - } - - public bool Equals(RawFileRow x, RawFileRow y) { - return x.Flags == y.Flags && - x.Name == y.Name && - x.HashValue == y.HashValue; - } - - public int GetHashCode(RawFileRow obj) { - return (int)obj.Flags + - rol(obj.Name, 3) + - rol(obj.HashValue, 7); - } - - public bool Equals(RawExportedTypeRow x, RawExportedTypeRow y) { - return x.Flags == y.Flags && - x.TypeDefId == y.TypeDefId && - x.TypeName == y.TypeName && - x.TypeNamespace == y.TypeNamespace && - x.Implementation == y.Implementation; - } - - public int GetHashCode(RawExportedTypeRow obj) { - return (int)obj.Flags + - rol(obj.TypeDefId, 3) + - rol(obj.TypeName, 7) + - rol(obj.TypeNamespace, 11) + - rol(obj.Implementation, 15); - } - - public bool Equals(RawManifestResourceRow x, RawManifestResourceRow y) { - return x.Offset == y.Offset && - x.Flags == y.Flags && - x.Name == y.Name && - x.Implementation == y.Implementation; - } - - public int GetHashCode(RawManifestResourceRow obj) { - return (int)obj.Offset + - rol(obj.Flags, 3) + - rol(obj.Name, 7) + - rol(obj.Implementation, 11); - } - - public bool Equals(RawNestedClassRow x, RawNestedClassRow y) { - return x.NestedClass == y.NestedClass && - x.EnclosingClass == y.EnclosingClass; - } - - public int GetHashCode(RawNestedClassRow obj) { - return (int)obj.NestedClass + - rol(obj.EnclosingClass, 3); - } - - public bool Equals(RawGenericParamRow x, RawGenericParamRow y) { - return x.Number == y.Number && - x.Flags == y.Flags && - x.Owner == y.Owner && - x.Name == y.Name && - x.Kind == y.Kind; - } - - public int GetHashCode(RawGenericParamRow obj) { - return (int)obj.Number + - rol(obj.Flags, 3) + - rol(obj.Owner, 7) + - rol(obj.Name, 11) + - rol(obj.Kind, 15); - } - - public bool Equals(RawMethodSpecRow x, RawMethodSpecRow y) { - return x.Method == y.Method && - x.Instantiation == y.Instantiation; - } - - public int GetHashCode(RawMethodSpecRow obj) { - return (int)obj.Method + - rol(obj.Instantiation, 3); - } - - public bool Equals(RawGenericParamConstraintRow x, RawGenericParamConstraintRow y) { - return x.Owner == y.Owner && - x.Constraint == y.Constraint; - } - - public int GetHashCode(RawGenericParamConstraintRow obj) { - return (int)obj.Owner + - rol(obj.Constraint, 3); - } - - public bool Equals(RawDocumentRow x, RawDocumentRow y) { - return x.Name == y.Name && - x.HashAlgorithm == y.HashAlgorithm && - x.Hash == y.Hash && - x.Language == y.Language; - } - - public int GetHashCode(RawDocumentRow obj) { - return (int)obj.Name + - rol(obj.HashAlgorithm, 3) + - rol(obj.Hash, 7) + - rol(obj.Language, 11); - } - - public bool Equals(RawMethodDebugInformationRow x, RawMethodDebugInformationRow y) { - return x.Document == y.Document && - x.SequencePoints == y.SequencePoints; - } - - public int GetHashCode(RawMethodDebugInformationRow obj) { - return (int)obj.Document + - rol(obj.SequencePoints, 3); - } - - public bool Equals(RawLocalScopeRow x, RawLocalScopeRow y) { - return x.Method == y.Method && - x.ImportScope == y.ImportScope && - x.VariableList == y.VariableList && - x.ConstantList == y.ConstantList && - x.StartOffset == y.StartOffset && - x.Length == y.Length; - } - - public int GetHashCode(RawLocalScopeRow obj) { - return (int)obj.Method + - rol(obj.ImportScope, 3) + - rol(obj.VariableList, 7) + - rol(obj.ConstantList, 11) + - rol(obj.StartOffset, 15) + - rol(obj.Length, 19); - } - - public bool Equals(RawLocalVariableRow x, RawLocalVariableRow y) { - return x.Attributes == y.Attributes && - x.Index == y.Index && - x.Name == y.Name; - } - - public int GetHashCode(RawLocalVariableRow obj) { - return obj.Attributes + - rol(obj.Index, 3) + - rol(obj.Name, 7); - } - - public bool Equals(RawLocalConstantRow x, RawLocalConstantRow y) { - return x.Name == y.Name && - x.Signature == y.Signature; - } - - public int GetHashCode(RawLocalConstantRow obj) { - return (int)obj.Name + - rol(obj.Signature, 3); - } - - public bool Equals(RawImportScopeRow x, RawImportScopeRow y) { - return x.Parent == y.Parent && - x.Imports == y.Imports; - } - - public int GetHashCode(RawImportScopeRow obj) { - return (int)obj.Parent + - rol(obj.Imports, 3); - } - - public bool Equals(RawStateMachineMethodRow x, RawStateMachineMethodRow y) { - return x.MoveNextMethod == y.MoveNextMethod && - x.KickoffMethod == y.KickoffMethod; - } - - public int GetHashCode(RawStateMachineMethodRow obj) { - return (int)obj.MoveNextMethod + - rol(obj.KickoffMethod, 3); - } - - public bool Equals(RawCustomDebugInformationRow x, RawCustomDebugInformationRow y) { - return x.Parent == y.Parent && - x.Kind == y.Kind && - x.Value == y.Value; - } - - public int GetHashCode(RawCustomDebugInformationRow obj) { - return (int)obj.Parent + - rol(obj.Kind, 3) + - rol(obj.Value, 7); - } + static int rol(uint val, int shift) => (int)((val << shift) | (val >> (32 - shift))); + + public bool Equals(RawModuleRow x, RawModuleRow y) => + x.Generation == y.Generation && + x.Name == y.Name && + x.Mvid == y.Mvid && + x.EncId == y.EncId && + x.EncBaseId == y.EncBaseId; + + public int GetHashCode(RawModuleRow obj) => + obj.Generation + + rol(obj.Name, 3) + + rol(obj.Mvid, 7) + + rol(obj.EncId, 11) + + rol(obj.EncBaseId, 15); + + public bool Equals(RawTypeRefRow x, RawTypeRefRow y) => + x.ResolutionScope == y.ResolutionScope && + x.Name == y.Name && + x.Namespace == y.Namespace; + + public int GetHashCode(RawTypeRefRow obj) => + (int)obj.ResolutionScope + + rol(obj.Name, 3) + + rol(obj.Namespace, 7); + + public bool Equals(RawTypeDefRow x, RawTypeDefRow y) => + x.Flags == y.Flags && + x.Name == y.Name && + x.Namespace == y.Namespace && + x.Extends == y.Extends && + x.FieldList == y.FieldList && + x.MethodList == y.MethodList; + + public int GetHashCode(RawTypeDefRow obj) => + (int)obj.Flags + + rol(obj.Name, 3) + + rol(obj.Namespace, 7) + + rol(obj.Extends, 11) + + rol(obj.FieldList, 15) + + rol(obj.MethodList, 19); + + public bool Equals(RawFieldPtrRow x, RawFieldPtrRow y) => x.Field == y.Field; + + public int GetHashCode(RawFieldPtrRow obj) => (int)obj.Field; + + public bool Equals(RawFieldRow x, RawFieldRow y) => + x.Flags == y.Flags && + x.Name == y.Name && + x.Signature == y.Signature; + + public int GetHashCode(RawFieldRow obj) => + (int)obj.Flags + + rol(obj.Name, 3) + + rol(obj.Signature, 7); + + public bool Equals(RawMethodPtrRow x, RawMethodPtrRow y) => x.Method == y.Method; + + public int GetHashCode(RawMethodPtrRow obj) => (int)obj.Method; + + public bool Equals(RawMethodRow x, RawMethodRow y) => + x.RVA == y.RVA && + x.ImplFlags == y.ImplFlags && + x.Flags == y.Flags && + x.Name == y.Name && + x.Signature == y.Signature && + x.ParamList == y.ParamList; + + public int GetHashCode(RawMethodRow obj) => + (int)obj.RVA + + rol(obj.ImplFlags, 3) + + rol(obj.Flags, 7) + + rol(obj.Name, 11) + + rol(obj.Signature, 15) + + rol(obj.ParamList, 19); + + public bool Equals(RawParamPtrRow x, RawParamPtrRow y) => x.Param == y.Param; + + public int GetHashCode(RawParamPtrRow obj) => (int)obj.Param; + + public bool Equals(RawParamRow x, RawParamRow y) => + x.Flags == y.Flags && + x.Sequence == y.Sequence && + x.Name == y.Name; + + public int GetHashCode(RawParamRow obj) => + (int)obj.Flags + + rol(obj.Sequence, 3) + + rol(obj.Name, 7); + + public bool Equals(RawInterfaceImplRow x, RawInterfaceImplRow y) => + x.Class == y.Class && + x.Interface == y.Interface; + + public int GetHashCode(RawInterfaceImplRow obj) => + (int)obj.Class + + rol(obj.Interface, 3); + + public bool Equals(RawMemberRefRow x, RawMemberRefRow y) => + x.Class == y.Class && + x.Name == y.Name && + x.Signature == y.Signature; + + public int GetHashCode(RawMemberRefRow obj) => + (int)obj.Class + + rol(obj.Name, 3) + + rol(obj.Signature, 7); + + public bool Equals(RawConstantRow x, RawConstantRow y) => + x.Type == y.Type && + x.Padding == y.Padding && + x.Parent == y.Parent && + x.Value == y.Value; + + public int GetHashCode(RawConstantRow obj) => + (int)obj.Type + + rol(obj.Padding, 3) + + rol(obj.Parent, 7) + + rol(obj.Value, 11); + + public bool Equals(RawCustomAttributeRow x, RawCustomAttributeRow y) => + x.Parent == y.Parent && + x.Type == y.Type && + x.Value == y.Value; + + public int GetHashCode(RawCustomAttributeRow obj) => + (int)obj.Parent + + rol(obj.Type, 3) + + rol(obj.Value, 7); + + public bool Equals(RawFieldMarshalRow x, RawFieldMarshalRow y) => + x.Parent == y.Parent && + x.NativeType == y.NativeType; + + public int GetHashCode(RawFieldMarshalRow obj) => + (int)obj.Parent + + rol(obj.NativeType, 3); + + public bool Equals(RawDeclSecurityRow x, RawDeclSecurityRow y) => + x.Action == y.Action && + x.Parent == y.Parent && + x.PermissionSet == y.PermissionSet; + + public int GetHashCode(RawDeclSecurityRow obj) => + (int)obj.Action + + rol(obj.Parent, 3) + + rol(obj.PermissionSet, 7); + + public bool Equals(RawClassLayoutRow x, RawClassLayoutRow y) => + x.PackingSize == y.PackingSize && + x.ClassSize == y.ClassSize && + x.Parent == y.Parent; + + public int GetHashCode(RawClassLayoutRow obj) => + (int)obj.PackingSize + + rol(obj.ClassSize, 3) + + rol(obj.Parent, 7); + + public bool Equals(RawFieldLayoutRow x, RawFieldLayoutRow y) => + x.OffSet == y.OffSet && + x.Field == y.Field; + + public int GetHashCode(RawFieldLayoutRow obj) => + (int)obj.OffSet + + rol(obj.Field, 3); + + public bool Equals(RawStandAloneSigRow x, RawStandAloneSigRow y) => x.Signature == y.Signature; + + public int GetHashCode(RawStandAloneSigRow obj) => (int)obj.Signature; + + public bool Equals(RawEventMapRow x, RawEventMapRow y) => + x.Parent == y.Parent && + x.EventList == y.EventList; + + public int GetHashCode(RawEventMapRow obj) => + (int)obj.Parent + + rol(obj.EventList, 3); + + public bool Equals(RawEventPtrRow x, RawEventPtrRow y) => x.Event == y.Event; + + public int GetHashCode(RawEventPtrRow obj) => (int)obj.Event; + + public bool Equals(RawEventRow x, RawEventRow y) => + x.EventFlags == y.EventFlags && + x.Name == y.Name && + x.EventType == y.EventType; + + public int GetHashCode(RawEventRow obj) => + (int)obj.EventFlags + + rol(obj.Name, 3) + + rol(obj.EventType, 7); + + public bool Equals(RawPropertyMapRow x, RawPropertyMapRow y) => + x.Parent == y.Parent && + x.PropertyList == y.PropertyList; + + public int GetHashCode(RawPropertyMapRow obj) => + (int)obj.Parent + + rol(obj.PropertyList, 3); + + public bool Equals(RawPropertyPtrRow x, RawPropertyPtrRow y) => x.Property == y.Property; + + public int GetHashCode(RawPropertyPtrRow obj) => (int)obj.Property; + + public bool Equals(RawPropertyRow x, RawPropertyRow y) => + x.PropFlags == y.PropFlags && + x.Name == y.Name && + x.Type == y.Type; + + public int GetHashCode(RawPropertyRow obj) => + (int)obj.PropFlags + + rol(obj.Name, 3) + + rol(obj.Type, 7); + + public bool Equals(RawMethodSemanticsRow x, RawMethodSemanticsRow y) => + x.Semantic == y.Semantic && + x.Method == y.Method && + x.Association == y.Association; + + public int GetHashCode(RawMethodSemanticsRow obj) => + (int)obj.Semantic + + rol(obj.Method, 3) + + rol(obj.Association, 7); + + public bool Equals(RawMethodImplRow x, RawMethodImplRow y) => + x.Class == y.Class && + x.MethodBody == y.MethodBody && + x.MethodDeclaration == y.MethodDeclaration; + + public int GetHashCode(RawMethodImplRow obj) => + (int)obj.Class + + rol(obj.MethodBody, 3) + + rol(obj.MethodDeclaration, 7); + + public bool Equals(RawModuleRefRow x, RawModuleRefRow y) => x.Name == y.Name; + + public int GetHashCode(RawModuleRefRow obj) => (int)obj.Name; + + public bool Equals(RawTypeSpecRow x, RawTypeSpecRow y) => x.Signature == y.Signature; + + public int GetHashCode(RawTypeSpecRow obj) => (int)obj.Signature; + + public bool Equals(RawImplMapRow x, RawImplMapRow y) => + x.MappingFlags == y.MappingFlags && + x.MemberForwarded == y.MemberForwarded && + x.ImportName == y.ImportName && + x.ImportScope == y.ImportScope; + + public int GetHashCode(RawImplMapRow obj) => + (int)obj.MappingFlags + + rol(obj.MemberForwarded, 3) + + rol(obj.ImportName, 7) + + rol(obj.ImportScope, 11); + + public bool Equals(RawFieldRVARow x, RawFieldRVARow y) => + x.RVA == y.RVA && + x.Field == y.Field; + + public int GetHashCode(RawFieldRVARow obj) => + (int)obj.RVA + + rol(obj.Field, 3); + + public bool Equals(RawENCLogRow x, RawENCLogRow y) => + x.Token == y.Token && + x.FuncCode == y.FuncCode; + + public int GetHashCode(RawENCLogRow obj) => + (int)obj.Token + + rol(obj.FuncCode, 3); + + public bool Equals(RawENCMapRow x, RawENCMapRow y) => x.Token == y.Token; + + public int GetHashCode(RawENCMapRow obj) => (int)obj.Token; + + public bool Equals(RawAssemblyRow x, RawAssemblyRow y) => + x.HashAlgId == y.HashAlgId && + x.MajorVersion == y.MajorVersion && + x.MinorVersion == y.MinorVersion && + x.BuildNumber == y.BuildNumber && + x.RevisionNumber == y.RevisionNumber && + x.Flags == y.Flags && + x.PublicKey == y.PublicKey && + x.Name == y.Name && + x.Locale == y.Locale; + + public int GetHashCode(RawAssemblyRow obj) => + (int)obj.HashAlgId + + rol(obj.MajorVersion, 3) + + rol(obj.MinorVersion, 7) + + rol(obj.BuildNumber, 11) + + rol(obj.RevisionNumber, 15) + + rol(obj.Flags, 19) + + rol(obj.PublicKey, 23) + + rol(obj.Name, 27) + + rol(obj.Locale, 31); + + public bool Equals(RawAssemblyProcessorRow x, RawAssemblyProcessorRow y) => x.Processor == y.Processor; + + public int GetHashCode(RawAssemblyProcessorRow obj) => (int)obj.Processor; + + public bool Equals(RawAssemblyOSRow x, RawAssemblyOSRow y) => + x.OSPlatformId == y.OSPlatformId && + x.OSMajorVersion == y.OSMajorVersion && + x.OSMinorVersion == y.OSMinorVersion; + + public int GetHashCode(RawAssemblyOSRow obj) => + (int)obj.OSPlatformId + + rol(obj.OSMajorVersion, 3) + + rol(obj.OSMinorVersion, 7); + + public bool Equals(RawAssemblyRefRow x, RawAssemblyRefRow y) => + x.MajorVersion == y.MajorVersion && + x.MinorVersion == y.MinorVersion && + x.BuildNumber == y.BuildNumber && + x.RevisionNumber == y.RevisionNumber && + x.Flags == y.Flags && + x.PublicKeyOrToken == y.PublicKeyOrToken && + x.Name == y.Name && + x.Locale == y.Locale && + x.HashValue == y.HashValue; + + public int GetHashCode(RawAssemblyRefRow obj) => + (int)obj.MajorVersion + + rol(obj.MinorVersion, 3) + + rol(obj.BuildNumber, 7) + + rol(obj.RevisionNumber, 11) + + rol(obj.Flags, 15) + + rol(obj.PublicKeyOrToken, 19) + + rol(obj.Name, 23) + + rol(obj.Locale, 27) + + rol(obj.HashValue, 31); + + public bool Equals(RawAssemblyRefProcessorRow x, RawAssemblyRefProcessorRow y) => + x.Processor == y.Processor && + x.AssemblyRef == y.AssemblyRef; + + public int GetHashCode(RawAssemblyRefProcessorRow obj) => + (int)obj.Processor + + rol(obj.AssemblyRef, 3); + + public bool Equals(RawAssemblyRefOSRow x, RawAssemblyRefOSRow y) => + x.OSPlatformId == y.OSPlatformId && + x.OSMajorVersion == y.OSMajorVersion && + x.OSMinorVersion == y.OSMinorVersion && + x.AssemblyRef == y.AssemblyRef; + + public int GetHashCode(RawAssemblyRefOSRow obj) => + (int)obj.OSPlatformId + + rol(obj.OSMajorVersion, 3) + + rol(obj.OSMinorVersion, 7) + + rol(obj.AssemblyRef, 11); + + public bool Equals(RawFileRow x, RawFileRow y) => + x.Flags == y.Flags && + x.Name == y.Name && + x.HashValue == y.HashValue; + + public int GetHashCode(RawFileRow obj) => + (int)obj.Flags + + rol(obj.Name, 3) + + rol(obj.HashValue, 7); + + public bool Equals(RawExportedTypeRow x, RawExportedTypeRow y) => + x.Flags == y.Flags && + x.TypeDefId == y.TypeDefId && + x.TypeName == y.TypeName && + x.TypeNamespace == y.TypeNamespace && + x.Implementation == y.Implementation; + + public int GetHashCode(RawExportedTypeRow obj) => + (int)obj.Flags + + rol(obj.TypeDefId, 3) + + rol(obj.TypeName, 7) + + rol(obj.TypeNamespace, 11) + + rol(obj.Implementation, 15); + + public bool Equals(RawManifestResourceRow x, RawManifestResourceRow y) => + x.Offset == y.Offset && + x.Flags == y.Flags && + x.Name == y.Name && + x.Implementation == y.Implementation; + + public int GetHashCode(RawManifestResourceRow obj) => + (int)obj.Offset + + rol(obj.Flags, 3) + + rol(obj.Name, 7) + + rol(obj.Implementation, 11); + + public bool Equals(RawNestedClassRow x, RawNestedClassRow y) => + x.NestedClass == y.NestedClass && + x.EnclosingClass == y.EnclosingClass; + + public int GetHashCode(RawNestedClassRow obj) => + (int)obj.NestedClass + + rol(obj.EnclosingClass, 3); + + public bool Equals(RawGenericParamRow x, RawGenericParamRow y) => + x.Number == y.Number && + x.Flags == y.Flags && + x.Owner == y.Owner && + x.Name == y.Name && + x.Kind == y.Kind; + + public int GetHashCode(RawGenericParamRow obj) => + (int)obj.Number + + rol(obj.Flags, 3) + + rol(obj.Owner, 7) + + rol(obj.Name, 11) + + rol(obj.Kind, 15); + + public bool Equals(RawMethodSpecRow x, RawMethodSpecRow y) => + x.Method == y.Method && + x.Instantiation == y.Instantiation; + + public int GetHashCode(RawMethodSpecRow obj) => + (int)obj.Method + + rol(obj.Instantiation, 3); + + public bool Equals(RawGenericParamConstraintRow x, RawGenericParamConstraintRow y) => + x.Owner == y.Owner && + x.Constraint == y.Constraint; + + public int GetHashCode(RawGenericParamConstraintRow obj) => + (int)obj.Owner + + rol(obj.Constraint, 3); + + public bool Equals(RawDocumentRow x, RawDocumentRow y) => + x.Name == y.Name && + x.HashAlgorithm == y.HashAlgorithm && + x.Hash == y.Hash && + x.Language == y.Language; + + public int GetHashCode(RawDocumentRow obj) => + (int)obj.Name + + rol(obj.HashAlgorithm, 3) + + rol(obj.Hash, 7) + + rol(obj.Language, 11); + + public bool Equals(RawMethodDebugInformationRow x, RawMethodDebugInformationRow y) => + x.Document == y.Document && + x.SequencePoints == y.SequencePoints; + + public int GetHashCode(RawMethodDebugInformationRow obj) => + (int)obj.Document + + rol(obj.SequencePoints, 3); + + public bool Equals(RawLocalScopeRow x, RawLocalScopeRow y) => + x.Method == y.Method && + x.ImportScope == y.ImportScope && + x.VariableList == y.VariableList && + x.ConstantList == y.ConstantList && + x.StartOffset == y.StartOffset && + x.Length == y.Length; + + public int GetHashCode(RawLocalScopeRow obj) => + (int)obj.Method + + rol(obj.ImportScope, 3) + + rol(obj.VariableList, 7) + + rol(obj.ConstantList, 11) + + rol(obj.StartOffset, 15) + + rol(obj.Length, 19); + + public bool Equals(RawLocalVariableRow x, RawLocalVariableRow y) => + x.Attributes == y.Attributes && + x.Index == y.Index && + x.Name == y.Name; + + public int GetHashCode(RawLocalVariableRow obj) => + obj.Attributes + + rol(obj.Index, 3) + + rol(obj.Name, 7); + + public bool Equals(RawLocalConstantRow x, RawLocalConstantRow y) => + x.Name == y.Name && + x.Signature == y.Signature; + + public int GetHashCode(RawLocalConstantRow obj) => + (int)obj.Name + + rol(obj.Signature, 3); + + public bool Equals(RawImportScopeRow x, RawImportScopeRow y) => + x.Parent == y.Parent && + x.Imports == y.Imports; + + public int GetHashCode(RawImportScopeRow obj) => + (int)obj.Parent + + rol(obj.Imports, 3); + + public bool Equals(RawStateMachineMethodRow x, RawStateMachineMethodRow y) => + x.MoveNextMethod == y.MoveNextMethod && + x.KickoffMethod == y.KickoffMethod; + + public int GetHashCode(RawStateMachineMethodRow obj) => + (int)obj.MoveNextMethod + + rol(obj.KickoffMethod, 3); + + public bool Equals(RawCustomDebugInformationRow x, RawCustomDebugInformationRow y) => + x.Parent == y.Parent && + x.Kind == y.Kind && + x.Value == y.Value; + + public int GetHashCode(RawCustomDebugInformationRow obj) => + (int)obj.Parent + + rol(obj.Kind, 3) + + rol(obj.Value, 7); } } diff --git a/src/DotNet/MD/RawTableRows.cs b/src/DotNet/MD/RawTableRows.cs index 2f195d58a..a6abe3449 100644 --- a/src/DotNet/MD/RawTableRows.cs +++ b/src/DotNet/MD/RawTableRows.cs @@ -186,9 +186,7 @@ public RawFieldPtrRow() { } /// Constructor - public RawFieldPtrRow(uint Field) { - this.Field = Field; - } + public RawFieldPtrRow(uint Field) => this.Field = Field; /// public uint Read(int index) { @@ -262,9 +260,7 @@ public RawMethodPtrRow() { } /// Constructor - public RawMethodPtrRow(uint Method) { - this.Method = Method; - } + public RawMethodPtrRow(uint Method) => this.Method = Method; /// public uint Read(int index) { @@ -353,9 +349,7 @@ public RawParamPtrRow() { } /// Constructor - public RawParamPtrRow(uint Param) { - this.Param = Param; - } + public RawParamPtrRow(uint Param) => this.Param = Param; /// public uint Read(int index) { @@ -763,9 +757,7 @@ public RawStandAloneSigRow() { } /// Constructor - public RawStandAloneSigRow(uint Signature) { - this.Signature = Signature; - } + public RawStandAloneSigRow(uint Signature) => this.Signature = Signature; /// public uint Read(int index) { @@ -834,9 +826,7 @@ public RawEventPtrRow() { } /// Constructor - public RawEventPtrRow(uint Event) { - this.Event = Event; - } + public RawEventPtrRow(uint Event) => this.Event = Event; /// public uint Read(int index) { @@ -948,9 +938,7 @@ public RawPropertyPtrRow() { } /// Constructor - public RawPropertyPtrRow(uint Property) { - this.Property = Property; - } + public RawPropertyPtrRow(uint Property) => this.Property = Property; /// public uint Read(int index) { @@ -1110,9 +1098,7 @@ public RawModuleRefRow() { } /// Constructor - public RawModuleRefRow(uint Name) { - this.Name = Name; - } + public RawModuleRefRow(uint Name) => this.Name = Name; /// public uint Read(int index) { @@ -1143,9 +1129,7 @@ public RawTypeSpecRow() { } /// Constructor - public RawTypeSpecRow(uint Signature) { - this.Signature = Signature; - } + public RawTypeSpecRow(uint Signature) => this.Signature = Signature; /// public uint Read(int index) { @@ -1300,9 +1284,7 @@ public RawENCMapRow() { } /// Constructor - public RawENCMapRow(uint Token) { - this.Token = Token; - } + public RawENCMapRow(uint Token) => this.Token = Token; /// public uint Read(int index) { @@ -1406,9 +1388,7 @@ public RawAssemblyProcessorRow() { } /// Constructor - public RawAssemblyProcessorRow(uint Processor) { - this.Processor = Processor; - } + public RawAssemblyProcessorRow(uint Processor) => this.Processor = Processor; /// public uint Read(int index) { diff --git a/src/DotNet/MD/RidList.cs b/src/DotNet/MD/RidList.cs index 7cd9ccc45..cc94f0b3f 100644 --- a/src/DotNet/MD/RidList.cs +++ b/src/DotNet/MD/RidList.cs @@ -49,19 +49,13 @@ sealed class ContiguousRidList : RidList { /// /// Gets the start rid /// - public uint StartRID { - get { return startRid; } - } + public uint StartRID => startRid; /// - public override uint Length { - get { return length; } - } + public override uint Length => length; /// - public override int Count { - get { return (int)length; } - } + public override int Count => (int)length; /// public override uint this[uint index] { @@ -73,9 +67,7 @@ public override uint this[uint index] { } /// - public override uint this[int index] { - get { return this[(uint)index]; } - } + public override uint this[int index] => this[(uint)index]; /// /// Constructor @@ -96,14 +88,10 @@ sealed class RandomRidList : RidList { readonly IList indexToRid; /// - public override uint Length { - get { return (uint)indexToRid.Count; } - } + public override uint Length => (uint)indexToRid.Count; /// - public override int Count { - get { return indexToRid.Count; } - } + public override int Count => indexToRid.Count; /// public override uint this[uint index] { @@ -115,31 +103,23 @@ public override uint this[uint index] { } /// - public override uint this[int index] { - get { return this[(uint)index]; } - } + public override uint this[int index] => this[(uint)index]; /// /// Default constructor /// - public RandomRidList() { - this.indexToRid = new List(); - } + public RandomRidList() => indexToRid = new List(); /// /// Constructor /// /// Approximate number of rids that will be returned - public RandomRidList(int capacity) { - this.indexToRid = new List(capacity); - } + public RandomRidList(int capacity) => indexToRid = new List(capacity); /// /// Add a new rid that should be returned /// /// The rid - public void Add(uint rid) { - indexToRid.Add(rid); - } + public void Add(uint rid) => indexToRid.Add(rid); } } diff --git a/src/DotNet/MD/StreamHeader.cs b/src/DotNet/MD/StreamHeader.cs index 5cc581730..e3ea5781b 100644 --- a/src/DotNet/MD/StreamHeader.cs +++ b/src/DotNet/MD/StreamHeader.cs @@ -18,23 +18,17 @@ public sealed class StreamHeader : FileSection { /// /// The offset of the stream relative to the start of the MetaData header /// - public uint Offset { - get { return offset; } - } + public uint Offset => offset; /// /// The size of the stream /// - public uint StreamSize { - get { return streamSize; } - } + public uint StreamSize => streamSize; /// /// The name of the stream /// - public string Name { - get { return name; } - } + public string Name => name; /// /// Constructor @@ -44,9 +38,9 @@ public string Name { /// Thrown if verification fails public StreamHeader(IImageStream reader, bool verify) { SetStartOffset(reader); - this.offset = reader.ReadUInt32(); - this.streamSize = reader.ReadUInt32(); - this.name = ReadString(reader, 32, verify); + offset = reader.ReadUInt32(); + streamSize = reader.ReadUInt32(); + name = ReadString(reader, 32, verify); SetEndoffset(reader); if (verify && offset + size < offset) throw new BadImageFormatException("Invalid stream header"); diff --git a/src/DotNet/MD/StringsStream.cs b/src/DotNet/MD/StringsStream.cs index 5c9093b69..e47506273 100644 --- a/src/DotNet/MD/StringsStream.cs +++ b/src/DotNet/MD/StringsStream.cs @@ -44,8 +44,6 @@ public UTF8String Read(uint offset) { /// /// Offset of string /// A instance - public UTF8String ReadNoNull(uint offset) { - return Read(offset) ?? UTF8String.Empty; - } + public UTF8String ReadNoNull(uint offset) => Read(offset) ?? UTF8String.Empty; } } diff --git a/src/DotNet/MD/TableInfo.cs b/src/DotNet/MD/TableInfo.cs index 0c4a0c47e..3171533fd 100644 --- a/src/DotNet/MD/TableInfo.cs +++ b/src/DotNet/MD/TableInfo.cs @@ -17,31 +17,25 @@ public sealed class TableInfo { /// /// Returns the table type /// - public Table Table { - get { return table; } - } + public Table Table => table; /// /// Returns the total size of a row in bytes /// public int RowSize { - get { return rowSize; } - internal set { rowSize = value; } + get => rowSize; + internal set => rowSize = value; } /// /// Returns all the columns /// - public IList Columns { - get { return columns; } - } + public IList Columns => columns; /// /// Returns the name of the table /// - public string Name { - get { return name; } - } + public string Name => name; /// /// Constructor diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 981cc451f..9790a9559 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -85,130 +85,100 @@ public sealed partial class TablesStream : DotNetStream { #endif internal HotTableStream HotTableStream { - set { hotTableStream = value; } + set => hotTableStream = value; } /// /// Gets/sets the column reader /// public IColumnReader ColumnReader { - get { return columnReader; } - set { columnReader = value; } + get => columnReader; + set => columnReader = value; } /// /// Gets/sets the Method table reader /// public IRowReader MethodRowReader { - get { return methodRowReader; } - set { methodRowReader = value; } + get => methodRowReader; + set => methodRowReader = value; } /// /// Gets the reserved field /// - public uint Reserved1 { - get { return reserved1; } - } + public uint Reserved1 => reserved1; /// /// Gets the version. The major version is in the upper 8 bits, and the minor version /// is in the lower 8 bits. /// - public ushort Version { - get { return (ushort)((majorVersion << 8) | minorVersion); } - } + public ushort Version => (ushort)((majorVersion << 8) | minorVersion); /// /// Gets /// - public MDStreamFlags Flags { - get { return flags; } - } + public MDStreamFlags Flags => flags; /// /// Gets the reserved log2 rid field /// - public byte Log2Rid { - get { return log2Rid; } - } + public byte Log2Rid => log2Rid; /// /// Gets the valid mask /// - public ulong ValidMask { - get { return validMask; } - } + public ulong ValidMask => validMask; /// /// Gets the sorted mask /// - public ulong SortedMask { - get { return sortedMask; } - } + public ulong SortedMask => sortedMask; /// /// Gets the extra data /// - public uint ExtraData { - get { return extraData; } - } + public uint ExtraData => extraData; /// /// Gets the MD tables /// - public MDTable[] MDTables { - get { return mdTables; } - } + public MDTable[] MDTables => mdTables; /// /// Gets the bit /// - public bool HasBigStrings { - get { return (flags & MDStreamFlags.BigStrings) != 0; } - } + public bool HasBigStrings => (flags & MDStreamFlags.BigStrings) != 0; /// /// Gets the bit /// - public bool HasBigGUID { - get { return (flags & MDStreamFlags.BigGUID) != 0; } - } + public bool HasBigGUID => (flags & MDStreamFlags.BigGUID) != 0; /// /// Gets the bit /// - public bool HasBigBlob { - get { return (flags & MDStreamFlags.BigBlob) != 0; } - } + public bool HasBigBlob => (flags & MDStreamFlags.BigBlob) != 0; /// /// Gets the bit /// - public bool HasPadding { - get { return (flags & MDStreamFlags.Padding) != 0; } - } + public bool HasPadding => (flags & MDStreamFlags.Padding) != 0; /// /// Gets the bit /// - public bool HasDeltaOnly { - get { return (flags & MDStreamFlags.DeltaOnly) != 0; } - } + public bool HasDeltaOnly => (flags & MDStreamFlags.DeltaOnly) != 0; /// /// Gets the bit /// - public bool HasExtraData { - get { return (flags & MDStreamFlags.ExtraData) != 0; } - } + public bool HasExtraData => (flags & MDStreamFlags.ExtraData) != 0; /// /// Gets the bit /// - public bool HasDelete { - get { return (flags & MDStreamFlags.HasDelete) != 0; } - } + public bool HasDelete => (flags & MDStreamFlags.HasDelete) != 0; /// public TablesStream(IImageStream imageStream, StreamHeader streamHeader) @@ -232,9 +202,8 @@ public void Initialize(uint[] typeSystemTableRows) { validMask = imageStream.ReadUInt64(); sortedMask = imageStream.ReadUInt64(); - int maxPresentTables; var dnTableSizes = new DotNetTableSizes(); - var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables); + var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out int maxPresentTables); if (typeSystemTableRows != null) maxPresentTables = DotNetTableSizes.normalMaxTables; mdTables = new MDTable[tableInfos.Length]; @@ -367,9 +336,7 @@ public MDTable Get(Table table) { /// /// The table type /// true if the table exists - public bool HasTable(Table table) { - return (uint)table < (uint)mdTables.Length; - } + public bool HasTable(Table table) => (uint)table < (uint)mdTables.Length; /// /// Checks whether table is sorted diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index 8458eb7f0..17bf01e14 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -1994,9 +1994,8 @@ internal uint ReadCustomDebugInformationRow2(uint rid, out uint kind) { /// Column index in /// Result is put here or 0 if we return false /// true if we could read the column, false otherwise - public bool ReadColumn(MDTable table, uint rid, int colIndex, out uint value) { - return ReadColumn(table, rid, table.TableInfo.Columns[colIndex], out value); - } + public bool ReadColumn(MDTable table, uint rid, int colIndex, out uint value) => + ReadColumn(table, rid, table.TableInfo.Columns[colIndex], out value); /// /// Reads a column diff --git a/src/DotNet/MD/USStream.cs b/src/DotNet/MD/USStream.cs index 4acd0750e..4865d661b 100644 --- a/src/DotNet/MD/USStream.cs +++ b/src/DotNet/MD/USStream.cs @@ -31,8 +31,7 @@ public string Read(uint offset) { theLock.EnterWriteLock(); try { #endif var reader = GetReader_NoLock(offset); - uint length; - if (!reader.ReadCompressedUInt32(out length)) + if (!reader.ReadCompressedUInt32(out uint length)) return null; if (reader.Position + length < length || reader.Position + length > reader.Length) return null; @@ -58,8 +57,6 @@ public string Read(uint offset) { /// /// Offset of unicode string /// The string - public string ReadNoNull(uint offset) { - return Read(offset) ?? string.Empty; - } + public string ReadNoNull(uint offset) => Read(offset) ?? string.Empty; } } diff --git a/src/DotNet/MDToken.cs b/src/DotNet/MDToken.cs index d898adef3..e83855f66 100644 --- a/src/DotNet/MDToken.cs +++ b/src/DotNet/MDToken.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet { /// MetaData token /// [DebuggerDisplay("{Table} {Rid}")] - public struct MDToken : IEquatable, IComparable { + public readonly struct MDToken : IEquatable, IComparable { /// /// Mask to get the rid from a raw metadata token /// @@ -30,38 +30,28 @@ public struct MDToken : IEquatable, IComparable { /// /// Returns the table type /// - public Table Table { - get { return ToTable(token); } - } + public Table Table => ToTable(token); /// /// Returns the row id /// - public uint Rid { - get { return ToRID(token); } - } + public uint Rid => ToRID(token); /// /// Returns the raw token /// - public uint Raw { - get { return token; } - } + public uint Raw => token; /// /// Returns true if it's a null token /// - public bool IsNull { - get { return Rid == 0; } - } + public bool IsNull => Rid == 0; /// /// Constructor /// /// Raw token - public MDToken(uint token) { - this.token = token; - } + public MDToken(uint token) => this.token = token; /// /// Constructor @@ -94,90 +84,62 @@ public MDToken(Table table, int rid) /// /// A raw metadata token /// A rid - public static uint ToRID(uint token) { - return token & RID_MASK; - } + public static uint ToRID(uint token) => token & RID_MASK; /// /// Returns the rid (row ID) /// /// A raw metadata token /// A rid - public static uint ToRID(int token) { - return ToRID((uint)token); - } + public static uint ToRID(int token) => ToRID((uint)token); /// /// Returns the table /// /// A raw metadata token /// A metadata table index - public static Table ToTable(uint token) { - return (Table)(token >> TABLE_SHIFT); - } + public static Table ToTable(uint token) => (Table)(token >> TABLE_SHIFT); /// /// Returns the table /// /// A raw metadata token /// A metadata table index - public static Table ToTable(int token) { - return ToTable((uint)token); - } + public static Table ToTable(int token) => ToTable((uint)token); /// /// Gets the token as a raw 32-bit signed integer /// - public int ToInt32() { - return (int)token; - } + public int ToInt32() => (int)token; /// /// Gets the token as a raw 32-bit unsigned integer /// - public uint ToUInt32() { - return token; - } + public uint ToUInt32() => token; /// Overloaded operator - public static bool operator ==(MDToken left, MDToken right) { - return left.CompareTo(right) == 0; - } + public static bool operator ==(MDToken left, MDToken right) => left.CompareTo(right) == 0; /// Overloaded operator - public static bool operator !=(MDToken left, MDToken right) { - return left.CompareTo(right) != 0; - } + public static bool operator !=(MDToken left, MDToken right) => left.CompareTo(right) != 0; /// Overloaded operator - public static bool operator <(MDToken left, MDToken right) { - return left.CompareTo(right) < 0; - } + public static bool operator <(MDToken left, MDToken right) => left.CompareTo(right) < 0; /// Overloaded operator - public static bool operator >(MDToken left, MDToken right) { - return left.CompareTo(right) > 0; - } + public static bool operator >(MDToken left, MDToken right) => left.CompareTo(right) > 0; /// Overloaded operator - public static bool operator <=(MDToken left, MDToken right) { - return left.CompareTo(right) <= 0; - } + public static bool operator <=(MDToken left, MDToken right) => left.CompareTo(right) <= 0; /// Overloaded operator - public static bool operator >=(MDToken left, MDToken right) { - return left.CompareTo(right) >= 0; - } + public static bool operator >=(MDToken left, MDToken right) => left.CompareTo(right) >= 0; /// - public int CompareTo(MDToken other) { - return token.CompareTo(other.token); - } + public int CompareTo(MDToken other) => token.CompareTo(other.token); /// - public bool Equals(MDToken other) { - return CompareTo(other) == 0; - } + public bool Equals(MDToken other) => CompareTo(other) == 0; /// public override bool Equals(object obj) { @@ -187,13 +149,9 @@ public override bool Equals(object obj) { } /// - public override int GetHashCode() { - return (int)token; - } + public override int GetHashCode() => (int)token; /// - public override string ToString() { - return string.Format("{0:X8}", token); - } + public override string ToString() => token.ToString("X8"); } } diff --git a/src/DotNet/ManifestResource.cs b/src/DotNet/ManifestResource.cs index 4a6223e5c..80b244518 100644 --- a/src/DotNet/ManifestResource.cs +++ b/src/DotNet/ManifestResource.cs @@ -25,27 +25,23 @@ public abstract class ManifestResource : IHasCustomAttribute, IHasCustomDebugInf protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.ManifestResource, rid); } - } + public MDToken MDToken => new MDToken(Table.ManifestResource, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 18; } - } + public int HasCustomAttributeTag => 18; /// /// From column ManifestResource.Offset /// public uint Offset { - get { return offset; } - set { offset = value; } + get => offset; + set => offset = value; } /// protected uint offset; @@ -54,8 +50,8 @@ public uint Offset { /// From column ManifestResource.Flags /// public ManifestResourceAttributes Flags { - get { return (ManifestResourceAttributes)attributes; } - set { attributes = (int)value; } + get => (ManifestResourceAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -64,8 +60,8 @@ public ManifestResourceAttributes Flags { /// From column ManifestResource.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -74,8 +70,8 @@ public UTF8String Name { /// From column ManifestResource.Implementation /// public IImplementation Implementation { - get { return implementation; } - set { implementation = value; } + get => implementation; + set => implementation = value; } /// protected IImplementation implementation; @@ -93,24 +89,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 18; } - } + public int HasCustomDebugInformationTag => 18; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -125,9 +114,8 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Modify property: = @@ -151,23 +139,19 @@ void ModifyAttributes(ManifestResourceAttributes andMask, ManifestResourceAttrib /// Gets/sets the visibility /// public ManifestResourceAttributes Visibility { - get { return (ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask; } - set { ModifyAttributes(~ManifestResourceAttributes.VisibilityMask, value & ManifestResourceAttributes.VisibilityMask); } + get => (ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask; + set => ModifyAttributes(~ManifestResourceAttributes.VisibilityMask, value & ManifestResourceAttributes.VisibilityMask); } /// /// true if is set /// - public bool IsPublic { - get { return ((ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Public; } - } + public bool IsPublic => ((ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Public; /// /// true if is set /// - public bool IsPrivate { - get { return ((ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private; } - } + public bool IsPrivate => ((ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private; } /// @@ -209,7 +193,7 @@ public ManifestResourceUser(UTF8String name, IImplementation implementation, Man public ManifestResourceUser(UTF8String name, IImplementation implementation, ManifestResourceAttributes flags, uint offset) { this.name = name; this.implementation = implementation; - this.attributes = (int)flags; + attributes = (int)flags; this.offset = offset; } } @@ -224,9 +208,7 @@ sealed class ManifestResourceMD : ManifestResource, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -254,13 +236,12 @@ public ManifestResourceMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ManifestResourceTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("ManifestResource rid {0} does not exist", rid)); + throw new BadImageFormatException($"ManifestResource rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint implementation = readerModule.TablesStream.ReadManifestResourceRow(origRid, out this.offset, out this.attributes, out name); + uint implementation = readerModule.TablesStream.ReadManifestResourceRow(origRid, out offset, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); this.implementation = readerModule.ResolveImplementation(implementation); } diff --git a/src/DotNet/MarshalBlobReader.cs b/src/DotNet/MarshalBlobReader.cs index e59bb914c..25a452391 100644 --- a/src/DotNet/MarshalBlobReader.cs +++ b/src/DotNet/MarshalBlobReader.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet { /// /// Reads s /// - public struct MarshalBlobReader : IDisposable { + public readonly struct MarshalBlobReader : IDisposable { readonly ModuleDef module; readonly IBinaryReader reader; readonly GenericParamContext gpContext; @@ -18,9 +18,7 @@ public struct MarshalBlobReader : IDisposable { /// Module /// Blob offset /// A new instance - public static MarshalType Read(ModuleDefMD module, uint sig) { - return Read(module, module.BlobStream.CreateStream(sig), new GenericParamContext()); - } + public static MarshalType Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateStream(sig), new GenericParamContext()); /// /// Reads a from the #Blob heap @@ -29,9 +27,7 @@ public static MarshalType Read(ModuleDefMD module, uint sig) { /// Blob offset /// Generic parameter context /// A new instance - public static MarshalType Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) { - return Read(module, module.BlobStream.CreateStream(sig), gpContext); - } + public static MarshalType Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateStream(sig), gpContext); /// /// Reads a from @@ -39,9 +35,7 @@ public static MarshalType Read(ModuleDefMD module, uint sig, GenericParamContext /// Owner module /// Marshal data /// A new instance - public static MarshalType Read(ModuleDef module, byte[] data) { - return Read(module, MemoryImageStream.Create(data), new GenericParamContext()); - } + public static MarshalType Read(ModuleDef module, byte[] data) => Read(module, MemoryImageStream.Create(data), new GenericParamContext()); /// /// Reads a from @@ -50,9 +44,7 @@ public static MarshalType Read(ModuleDef module, byte[] data) { /// Marshal data /// Generic parameter context /// A new instance - public static MarshalType Read(ModuleDef module, byte[] data, GenericParamContext gpContext) { - return Read(module, MemoryImageStream.Create(data), gpContext); - } + public static MarshalType Read(ModuleDef module, byte[] data, GenericParamContext gpContext) => Read(module, MemoryImageStream.Create(data), gpContext); /// /// Reads a from @@ -60,9 +52,7 @@ public static MarshalType Read(ModuleDef module, byte[] data, GenericParamContex /// Owner module /// A reader that will be owned by us /// A new instance - public static MarshalType Read(ModuleDef module, IBinaryReader reader) { - return Read(module, reader, new GenericParamContext()); - } + public static MarshalType Read(ModuleDef module, IBinaryReader reader) => Read(module, reader, new GenericParamContext()); /// /// Reads a from @@ -142,9 +132,7 @@ MarshalType Read() { return returnValue; } - bool CanRead() { - return reader.Position < reader.Length; - } + bool CanRead() => reader.Position < reader.Length; UTF8String ReadUTF8String() { uint len = reader.ReadCompressedUInt32(); @@ -152,9 +140,6 @@ UTF8String ReadUTF8String() { } /// - public void Dispose() { - if (reader != null) - reader.Dispose(); - } + public void Dispose() => reader?.Dispose(); } } diff --git a/src/DotNet/MarshalType.cs b/src/DotNet/MarshalType.cs index 788b6ecca..bec6c4e7e 100644 --- a/src/DotNet/MarshalType.cs +++ b/src/DotNet/MarshalType.cs @@ -15,22 +15,16 @@ public class MarshalType { /// /// Gets the /// - public NativeType NativeType { - get { return nativeType; } - } + public NativeType NativeType => nativeType; /// /// Constructor /// /// Native type - public MarshalType(NativeType nativeType) { - this.nativeType = nativeType; - } + public MarshalType(NativeType nativeType) => this.nativeType = nativeType; /// - public override string ToString() { - return nativeType.ToString(); - } + public override string ToString() => nativeType.ToString(); } /// @@ -43,8 +37,8 @@ public sealed class RawMarshalType : MarshalType { /// Gets/sets the raw data /// public byte[] Data { - get { return data; } - set { data = value; } + get => data; + set => data = value; } /// @@ -52,9 +46,7 @@ public byte[] Data { /// /// Raw data public RawMarshalType(byte[] data) - : base(NativeType.RawBlob) { - this.data = data; - } + : base(NativeType.RawBlob) => this.data = data; } /// @@ -67,16 +59,14 @@ public sealed class FixedSysStringMarshalType : MarshalType { /// Gets/sets the size /// public int Size { - get { return size; } - set { size = value; } + get => size; + set => size = value; } /// /// true if is valid /// - public bool IsSizeValid { - get { return size >= 0; } - } + public bool IsSizeValid => size >= 0; /// /// Default constructor @@ -90,15 +80,13 @@ public FixedSysStringMarshalType() /// /// Size public FixedSysStringMarshalType(int size) - : base(NativeType.FixedSysString) { - this.size = size; - } + : base(NativeType.FixedSysString) => this.size = size; /// public override string ToString() { if (IsSizeValid) - return string.Format("{0} ({1})", nativeType, size); - return string.Format("{0} ()", nativeType); + return $"{nativeType} ({size})"; + return $"{nativeType} ()"; } } @@ -113,31 +101,27 @@ public sealed class SafeArrayMarshalType : MarshalType { /// Gets/sets the variant type /// public VariantType VariantType { - get { return vt; } - set { vt = value; } + get => vt; + set => vt = value; } /// /// Gets/sets the user-defined sub type (it's usually null) /// public ITypeDefOrRef UserDefinedSubType { - get { return userDefinedSubType; } - set { userDefinedSubType = value; } + get => userDefinedSubType; + set => userDefinedSubType = value; } /// /// true if is valid /// - public bool IsVariantTypeValid { - get { return vt != VariantType.NotInitialized; } - } + public bool IsVariantTypeValid => vt != VariantType.NotInitialized; /// /// true if is valid /// - public bool IsUserDefinedSubTypeValid { - get { return userDefinedSubType != null; } - } + public bool IsUserDefinedSubTypeValid => userDefinedSubType != null; /// /// Default constructor @@ -177,8 +161,8 @@ public SafeArrayMarshalType(VariantType vt, ITypeDefOrRef userDefinedSubType) public override string ToString() { var udt = userDefinedSubType; if (udt != null) - return string.Format("{0} ({1}, {2})", nativeType, vt, udt); - return string.Format("{0} ({1})", nativeType, vt); + return $"{nativeType} ({vt}, {udt})"; + return $"{nativeType} ({vt})"; } } @@ -193,31 +177,27 @@ public sealed class FixedArrayMarshalType : MarshalType { /// Gets/sets the element type /// public NativeType ElementType { - get { return elementType; } - set { elementType = value; } + get => elementType; + set => elementType = value; } /// /// Gets/sets the size /// public int Size { - get { return size; } - set { size = value; } + get => size; + set => size = value; } /// /// true if is valid /// - public bool IsElementTypeValid { - get { return elementType != NativeType.NotInitialized; } - } + public bool IsElementTypeValid => elementType != NativeType.NotInitialized; /// /// true if is valid /// - public bool IsSizeValid { - get { return size >= 0; } - } + public bool IsSizeValid => size >= 0; /// /// Default constructor @@ -246,9 +226,7 @@ public FixedArrayMarshalType(int size, NativeType elementType) } /// - public override string ToString() { - return string.Format("{0} ({1}, {2})", nativeType, size, elementType); - } + public override string ToString() => $"{nativeType} ({size}, {elementType})"; } /// @@ -264,61 +242,53 @@ public sealed class ArrayMarshalType : MarshalType { /// Gets/sets the element type /// public NativeType ElementType { - get { return elementType; } - set { elementType = value; } + get => elementType; + set => elementType = value; } /// /// Gets/sets the parameter number /// public int ParamNumber { - get { return paramNum; } - set { paramNum = value; } + get => paramNum; + set => paramNum = value; } /// /// Gets/sets the size of the array /// public int Size { - get { return numElems; } - set { numElems = value; } + get => numElems; + set => numElems = value; } /// /// Gets/sets the flags /// public int Flags { - get { return flags; } - set { flags = value; } + get => flags; + set => flags = value; } /// /// true if is valid /// - public bool IsElementTypeValid { - get { return elementType != NativeType.NotInitialized; } - } + public bool IsElementTypeValid => elementType != NativeType.NotInitialized; /// /// true if is valid /// - public bool IsParamNumberValid { - get { return paramNum >= 0; } - } + public bool IsParamNumberValid => paramNum >= 0; /// /// true if is valid /// - public bool IsSizeValid { - get { return numElems >= 0; } - } + public bool IsSizeValid => numElems >= 0; /// /// true if is valid /// - public bool IsFlagsValid { - get { return flags >= 0; } - } + public bool IsFlagsValid => flags >= 0; const int ntaSizeParamIndexSpecified = 1; @@ -326,17 +296,13 @@ public bool IsFlagsValid { /// true if ntaSizeParamIndexSpecified bit is set, false if it's not /// set or if is invalid. /// - public bool IsSizeParamIndexSpecified { - get { return IsFlagsValid && (flags & ntaSizeParamIndexSpecified) != 0; } - } + public bool IsSizeParamIndexSpecified => IsFlagsValid && (flags & ntaSizeParamIndexSpecified) != 0; /// /// true if ntaSizeParamIndexSpecified bit is not set, false if it's /// set or if is invalid. /// - public bool IsSizeParamIndexNotSpecified { - get { return IsFlagsValid && (flags & ntaSizeParamIndexSpecified) == 0; } - } + public bool IsSizeParamIndexNotSpecified => IsFlagsValid && (flags & ntaSizeParamIndexSpecified) == 0; /// /// Default constructor @@ -388,9 +354,7 @@ public ArrayMarshalType(NativeType elementType, int paramNum, int numElems, int } /// - public override string ToString() { - return string.Format("{0} ({1}, {2}, {3}, {4})", nativeType, elementType, paramNum, numElems, flags); - } + public override string ToString() => $"{nativeType} ({elementType}, {paramNum}, {numElems}, {flags})"; } /// @@ -406,32 +370,32 @@ public sealed class CustomMarshalType : MarshalType { /// Gets/sets the GUID string /// public UTF8String Guid { - get { return guid; } - set { guid = value; } + get => guid; + set => guid = value; } /// /// Gets/sets the native type name string /// public UTF8String NativeTypeName { - get { return nativeTypeName; } - set { nativeTypeName = value; } + get => nativeTypeName; + set => nativeTypeName = value; } /// /// Gets/sets the custom marshaler /// public ITypeDefOrRef CustomMarshaler { - get { return custMarshaler; } - set { custMarshaler = value; } + get => custMarshaler; + set => custMarshaler = value; } /// /// Gets/sets the cookie string /// public UTF8String Cookie { - get { return cookie; } - set { cookie = value; } + get => cookie; + set => cookie = value; } /// @@ -484,9 +448,7 @@ public CustomMarshalType(UTF8String guid, UTF8String nativeTypeName, ITypeDefOrR } /// - public override string ToString() { - return string.Format("{0} ({1}, {2}, {3}, {4})", nativeType, guid, nativeTypeName, custMarshaler, cookie); - } + public override string ToString() => $"{nativeType} ({guid}, {nativeTypeName}, {custMarshaler}, {cookie})"; } /// @@ -500,16 +462,14 @@ public sealed class InterfaceMarshalType : MarshalType { /// Gets/sets the IID parameter index /// public int IidParamIndex { - get { return iidParamIndex; } - set { iidParamIndex = value; } + get => iidParamIndex; + set => iidParamIndex = value; } /// /// true if is valid /// - public bool IsIidParamIndexValid { - get { return iidParamIndex >= 0; } - } + public bool IsIidParamIndexValid => iidParamIndex >= 0; /// /// Constructor @@ -534,8 +494,6 @@ public InterfaceMarshalType(NativeType nativeType, int iidParamIndex) } /// - public override string ToString() { - return string.Format("{0} ({1})", nativeType, iidParamIndex); - } + public override string ToString() => $"{nativeType} ({iidParamIndex})"; } } diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index 32d645c92..42978843a 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -136,7 +136,7 @@ void ProcessAll() { case ObjectType.TypeSig: Add((TypeSig)o); break; case ObjectType.TypeSpec: Add((TypeSpec)o); break; case ObjectType.ExportedType: Add((ExportedType)o); break; - default: throw new InvalidOperationException(string.Format("Unknown type: {0}", o.GetType())); + default: throw new InvalidOperationException($"Unknown type: {o.GetType()}"); } } } @@ -146,8 +146,7 @@ ObjectType GetObjectType(object o) { if (o == null) return ObjectType.Unknown; var type = o.GetType(); - ObjectType mrType; - if (toObjectType.TryGetValue(type, out mrType)) + if (toObjectType.TryGetValue(type, out var mrType)) return mrType; mrType = GetObjectType2(o); toObjectType[type] = mrType; @@ -200,26 +199,22 @@ void Add(CallingConventionSig sig) { if (sig == null) return; - var fs = sig as FieldSig; - if (fs != null) { + if (sig is FieldSig fs) { Add(fs); return; } - var mbs = sig as MethodBaseSig; - if (mbs != null) { + if (sig is MethodBaseSig mbs) { Add(mbs); return; } - var ls = sig as LocalSig; - if (ls != null) { + if (sig is LocalSig ls) { Add(ls); return; } - var gims = sig as GenericInstMethodSig; - if (gims != null) { + if (sig is GenericInstMethodSig gims) { Add(gims); return; } @@ -322,20 +317,17 @@ void Add(SecurityAttribute secAttr) { } void Add(ITypeDefOrRef tdr) { - var td = tdr as TypeDef; - if (td != null) { + if (tdr is TypeDef td) { Add(td); return; } - var tr = tdr as TypeRef; - if (tr != null) { + if (tdr is TypeRef tr) { Add(tr); return; } - var ts = tdr as TypeSpec; - if (ts != null) { + if (tdr is TypeSpec ts) { Add(ts); return; } @@ -449,8 +441,7 @@ void Add(MethodDef md) { } void Add(MethodBody mb) { - var cb = mb as CilBody; - if (cb != null) + if (mb is CilBody cb) Add(cb); } diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index 2486b5504..a1cd9513b 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -29,37 +29,29 @@ public abstract class MemberRef : IHasCustomAttribute, IMethodDefOrRef, ICustomA protected ModuleDef module; /// - public MDToken MDToken { - get { return new MDToken(Table.MemberRef, rid); } - } + public MDToken MDToken => new MDToken(Table.MemberRef, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 6; } - } + public int HasCustomAttributeTag => 6; /// - public int MethodDefOrRefTag { - get { return 1; } - } + public int MethodDefOrRefTag => 1; /// - public int CustomAttributeTypeTag { - get { return 3; } - } + public int CustomAttributeTypeTag => 3; /// /// From column MemberRef.Class /// public IMemberRefParent Class { - get { return @class; } - set { @class = value; } + get => @class; + set => @class = value; } /// protected IMemberRefParent @class; @@ -68,8 +60,8 @@ public IMemberRefParent Class { /// From column MemberRef.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -78,8 +70,8 @@ public UTF8String Name { /// From column MemberRef.Signature /// public CallingConventionSig Signature { - get { return signature; } - set { signature = value; } + get => signature; + set => signature = value; } /// protected CallingConventionSig signature; @@ -97,24 +89,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 6; } - } + public int HasCustomDebugInformationTag => 6; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -129,25 +114,21 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// public ITypeDefOrRef DeclaringType { get { var owner = @class; - var tdr = owner as ITypeDefOrRef; - if (tdr != null) + if (owner is ITypeDefOrRef tdr) return tdr; - var method = owner as MethodDef; - if (method != null) + if (owner is MethodDef method) return method.DeclaringType; - var mr = owner as ModuleRef; - if (mr != null) { + if (owner is ModuleRef mr) { var tr = GetGlobalTypeRef(mr); if (module != null) return module.UpdateRowId(tr); @@ -183,92 +164,48 @@ TypeRefUser CreateDefaultGlobalTypeRef(ModuleRef mr) { return tr; } - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return IsMethodRef; } - } - - bool IMemberRef.IsField { - get { return IsFieldRef; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return true; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => IsMethodRef; + bool IMemberRef.IsField => IsFieldRef; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => true; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// /// true if this is a method reference ( != null) /// - public bool IsMethodRef { - get { return MethodSig != null; } - } + public bool IsMethodRef => MethodSig != null; /// /// true if this is a field reference ( != null) /// - public bool IsFieldRef { - get { return FieldSig != null; } - } + public bool IsFieldRef => FieldSig != null; /// /// Gets/sets the method sig /// public MethodSig MethodSig { - get { return signature as MethodSig; } - set { signature = value; } + get => signature as MethodSig; + set => signature = value; } /// /// Gets/sets the field sig /// public FieldSig FieldSig { - get { return signature as FieldSig; } - set { signature = value; } + get => signature as FieldSig; + set => signature = value; } /// - public ModuleDef Module { - get { return module; } - } + public ModuleDef Module => module; /// /// true if the method has a hidden 'this' parameter @@ -304,10 +241,7 @@ public CallingConvention CallingConvention { /// Gets/sets the method return type /// public TypeSig ReturnType { - get { - var ms = MethodSig; - return ms == null ? null : ms.RetType; - } + get => MethodSig?.RetType; set { var ms = MethodSig; if (ms != null) @@ -316,12 +250,7 @@ public TypeSig ReturnType { } /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { - var sig = MethodSig; - return sig == null ? 0 : (int)sig.GenParamCount; - } - } + int IGenericParameterProvider.NumberOfGenericParameters => (int)(MethodSig?.GenParamCount ?? 0); /// /// Gets the full name @@ -331,8 +260,7 @@ public string FullName { var parent = @class; IList typeGenArgs = null; if (parent is TypeSpec) { - var sig = ((TypeSpec)parent).TypeSig as GenericInstSig; - if (sig != null) + if (((TypeSpec)parent).TypeSig is GenericInstSig sig) typeGenArgs = sig.GenericArguments; } var methodSig = MethodSig; @@ -349,9 +277,7 @@ public string FullName { /// Get the declaring type's full name /// /// Full name or null if there's no declaring type - public string GetDeclaringTypeFullName() { - return GetDeclaringTypeFullName(@class); - } + public string GetDeclaringTypeFullName() => GetDeclaringTypeFullName(@class); string GetDeclaringTypeFullName(IMemberRefParent parent) { if (parent == null) @@ -359,10 +285,10 @@ string GetDeclaringTypeFullName(IMemberRefParent parent) { if (parent is ITypeDefOrRef) return ((ITypeDefOrRef)parent).FullName; if (parent is ModuleRef) - return string.Format("[module:{0}]", ((ModuleRef)parent).ToString()); + return $"[module:{((ModuleRef)parent).ToString()}]"; if (parent is MethodDef) { var declaringType = ((MethodDef)parent).DeclaringType; - return declaringType == null ? null : declaringType.FullName; + return declaringType?.FullName; } return null; // Should never be reached } @@ -387,16 +313,14 @@ public IMemberForwarded ResolveThrow() { var memberDef = Resolve(); if (memberDef != null) return memberDef; - throw new MemberRefResolveException(string.Format("Could not resolve method/field: {0} ({1})", this, this.GetDefinitionAssembly())); + throw new MemberRefResolveException($"Could not resolve method/field: {this} ({this.GetDefinitionAssembly()})"); } /// /// Resolves the field /// /// A instance or null if it couldn't be resolved. - public FieldDef ResolveField() { - return Resolve() as FieldDef; - } + public FieldDef ResolveField() => Resolve() as FieldDef; /// /// Resolves the field @@ -407,16 +331,14 @@ public FieldDef ResolveFieldThrow() { var field = ResolveField(); if (field != null) return field; - throw new MemberRefResolveException(string.Format("Could not resolve field: {0} ({1})", this, this.GetDefinitionAssembly())); + throw new MemberRefResolveException($"Could not resolve field: {this} ({this.GetDefinitionAssembly()})"); } /// /// Resolves the method /// /// A instance or null if it couldn't be resolved. - public MethodDef ResolveMethod() { - return Resolve() as MethodDef; - } + public MethodDef ResolveMethod() => Resolve() as MethodDef; /// /// Resolves the method @@ -427,12 +349,10 @@ public MethodDef ResolveMethodThrow() { var method = ResolveMethod(); if (method != null) return method; - throw new MemberRefResolveException(string.Format("Could not resolve method: {0} ({1})", this, this.GetDefinitionAssembly())); + throw new MemberRefResolveException($"Could not resolve method: {this} ({this.GetDefinitionAssembly()})"); } - bool IContainsGenericParameter.ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// /// Gets a that can be used as signature context @@ -442,22 +362,16 @@ bool IContainsGenericParameter.ContainsGenericParameter { /// protected static GenericParamContext GetSignatureGenericParamContext(GenericParamContext gpContext, IMemberRefParent @class) { TypeDef type = null; - MethodDef method = gpContext.Method; + var method = gpContext.Method; - var ts = @class as TypeSpec; - if (ts != null) { - var gis = ts.TypeSig as GenericInstSig; - if (gis != null) - type = gis.GenericType.ToTypeDefOrRef().ResolveTypeDef(); - } + if (@class is TypeSpec ts && ts.TypeSig is GenericInstSig gis) + type = gis.GenericType.ToTypeDefOrRef().ResolveTypeDef(); return new GenericParamContext(type, method); } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -468,9 +382,7 @@ public class MemberRefUser : MemberRef { /// Constructor /// /// Owner module - public MemberRefUser(ModuleDef module) { - this.module = module; - } + public MemberRefUser(ModuleDef module) => this.module = module; /// /// Constructor @@ -503,7 +415,7 @@ public MemberRefUser(ModuleDef module, UTF8String name, FieldSig sig, IMemberRef this.module = module; this.name = name; this.@class = @class; - this.signature = sig; + signature = sig; } /// @@ -527,7 +439,7 @@ public MemberRefUser(ModuleDef module, UTF8String name, MethodSig sig, IMemberRe this.module = module; this.name = name; this.@class = @class; - this.signature = sig; + signature = sig; } } @@ -542,9 +454,7 @@ sealed class MemberRefMD : MemberRef, IMDTokenProviderMD { readonly GenericParamContext gpContext; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -573,15 +483,14 @@ public MemberRefMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpCon if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.MemberRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("MemberRef rid {0} does not exist", rid)); + throw new BadImageFormatException($"MemberRef rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; this.gpContext = gpContext; - this.module = readerModule; - uint @class, name; - uint signature = readerModule.TablesStream.ReadMemberRefRow(origRid, out @class, out name); + module = readerModule; + uint signature = readerModule.TablesStream.ReadMemberRefRow(origRid, out uint @class, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); this.@class = readerModule.ResolveMemberRefParent(@class, gpContext); this.signature = readerModule.ReadSignature(signature, GetSignatureGenericParamContext(gpContext, this.@class)); diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index ba8d5ca6f..a5dad3862 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -39,57 +39,41 @@ public abstract class MethodDef : IHasCustomAttribute, IHasDeclSecurity, IMember protected ParameterList parameterList; /// - public MDToken MDToken { - get { return new MDToken(Table.Method, rid); } - } + public MDToken MDToken => new MDToken(Table.Method, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 0; } - } + public int HasCustomAttributeTag => 0; /// - public int HasDeclSecurityTag { - get { return 1; } - } + public int HasDeclSecurityTag => 1; /// - public int MemberRefParentTag { - get { return 3; } - } + public int MemberRefParentTag => 3; /// - public int MethodDefOrRefTag { - get { return 0; } - } + public int MethodDefOrRefTag => 0; /// - public int MemberForwardedTag { - get { return 1; } - } + public int MemberForwardedTag => 1; /// - public int CustomAttributeTypeTag { - get { return 2; } - } + public int CustomAttributeTypeTag => 2; /// - public int TypeOrMethodDefTag { - get { return 1; } - } + public int TypeOrMethodDefTag => 1; /// /// From column Method.RVA /// public RVA RVA { - get { return rva; } - set { rva = value; } + get => rva; + set => rva = value; } /// protected RVA rva; @@ -98,8 +82,8 @@ public RVA RVA { /// From column Method.ImplFlags /// public MethodImplAttributes ImplAttributes { - get { return (MethodImplAttributes)implAttributes; } - set { implAttributes = (int)value; } + get => (MethodImplAttributes)implAttributes; + set => implAttributes = (int)value; } /// Implementation attributes protected int implAttributes; @@ -108,8 +92,8 @@ public MethodImplAttributes ImplAttributes { /// From column Method.Flags /// public MethodAttributes Attributes { - get { return (MethodAttributes)attributes; } - set { attributes = (int)value; } + get => (MethodAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -118,8 +102,8 @@ public MethodAttributes Attributes { /// From column Method.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -128,8 +112,8 @@ public UTF8String Name { /// From column Method.Signature /// public CallingConventionSig Signature { - get { return signature; } - set { signature = value; } + get => signature; + set => signature = value; } /// protected CallingConventionSig signature; @@ -147,9 +131,8 @@ public ThreadSafe.IList ParamDefs { /// protected LazyList paramDefs; /// Initializes - protected virtual void InitializeParamDefs() { + protected virtual void InitializeParamDefs() => Interlocked.CompareExchange(ref paramDefs, new LazyList(this), null); - } /// public ThreadSafe.IList GenericParameters { @@ -162,9 +145,8 @@ public ThreadSafe.IList GenericParameters { /// protected LazyList genericParameters; /// Initializes - protected virtual void InitializeGenericParameters() { + protected virtual void InitializeGenericParameters() => Interlocked.CompareExchange(ref genericParameters, new LazyList(this), null); - } /// public ThreadSafe.IList DeclSecurities { @@ -177,9 +159,8 @@ public ThreadSafe.IList DeclSecurities { /// protected ThreadSafe.IList declSecurities; /// Initializes - protected virtual void InitializeDeclSecurities() { + protected virtual void InitializeDeclSecurities() => Interlocked.CompareExchange(ref declSecurities, ThreadSafeListCreator.Create(), null); - } /// public ImplMap ImplMap { @@ -218,14 +199,10 @@ void InitializeImplMap() { } /// Called to initialize - protected virtual ImplMap GetImplMap_NoLock() { - return null; - } + protected virtual ImplMap GetImplMap_NoLock() => null; /// Reset - protected void ResetImplMap() { - implMap_isInitialized = false; - } + protected void ResetImplMap() => implMap_isInitialized = false; /// /// Gets/sets the method body. See also @@ -285,16 +262,12 @@ public void FreeMethodBody() { } /// Called to initialize - protected virtual MethodBody GetMethodBody_NoLock() { - return null; - } + protected virtual MethodBody GetMethodBody_NoLock() => null; /// /// true if can free the method body /// - protected virtual bool CanFreeMethodBody { - get { return true; } - } + protected virtual bool CanFreeMethodBody => true; /// /// Gets all custom attributes @@ -309,19 +282,14 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public int HasCustomDebugInformationTag { - get { return 0; } - } + public int HasCustomDebugInformationTag => 0; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -336,9 +304,8 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Gets the methods this method implements @@ -353,42 +320,35 @@ public ThreadSafe.IList Overrides { /// protected ThreadSafe.IList overrides; /// Initializes - protected virtual void InitializeOverrides() { + protected virtual void InitializeOverrides() => Interlocked.CompareExchange(ref overrides, ThreadSafeListCreator.Create(), null); - } /// /// Gets the export info or null if the method isn't exported to unmanaged code. /// public MethodExportInfo ExportInfo { - get { return exportInfo; } - set { exportInfo = value; } + get => exportInfo; + set => exportInfo = value; } /// protected MethodExportInfo exportInfo; /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public bool HasDeclSecurities { - get { return DeclSecurities.Count > 0; } - } + public bool HasDeclSecurities => DeclSecurities.Count > 0; /// /// true if is not empty /// - public bool HasParamDefs { - get { return ParamDefs.Count > 0; } - } + public bool HasParamDefs => ParamDefs.Count > 0; /// /// Gets/sets the declaring type (owner type) /// public TypeDef DeclaringType { - get { return declaringType2; } + get => declaringType2; set { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) @@ -401,9 +361,7 @@ public TypeDef DeclaringType { } /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return declaringType2; } - } + ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; /// /// Called by and should normally not be called by any user @@ -411,71 +369,28 @@ ITypeDefOrRef IMemberRef.DeclaringType { /// declaring type without inserting it in the declaring type's method list. /// public TypeDef DeclaringType2 { - get { return declaringType2; } - set { declaringType2 = value; } + get => declaringType2; + set => declaringType2 = value; } /// protected TypeDef declaringType2; /// - public ModuleDef Module { - get { - var dt = declaringType2; - return dt == null ? null : dt.Module; - } - } - - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return true; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return true; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + public ModuleDef Module => declaringType2?.Module; + + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => true; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => true; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// /// Gets/sets the CIL method body. See also @@ -486,7 +401,7 @@ public CilBody Body { InitializeMethodBody(); return methodBody as CilBody; } - set { MethodBody = value; } + set => MethodBody = value; } /// @@ -498,61 +413,46 @@ public NativeMethodBody NativeBody { InitializeMethodBody(); return methodBody as NativeMethodBody; } - set { MethodBody = value; } + set => MethodBody = value; } /// /// true if there's at least one in /// - public bool HasGenericParameters { - get { return GenericParameters.Count > 0; } - } + public bool HasGenericParameters => GenericParameters.Count > 0; /// /// true if it has a /// - public bool HasBody { - get { return Body != null; } - } + public bool HasBody => Body != null; /// /// true if there's at least one in /// - public bool HasOverrides { - get { return Overrides.Count > 0; } - } + public bool HasOverrides => Overrides.Count > 0; /// /// true if is not null /// - public bool HasImplMap { - get { return ImplMap != null; } - } + public bool HasImplMap => ImplMap != null; /// /// Gets the full name /// - public string FullName { - get { - var dt = declaringType2; - return FullNameCreator.MethodFullName(dt == null ? null : dt.FullName, name, MethodSig, null, null, this, null); - } - } + public string FullName => FullNameCreator.MethodFullName(declaringType2?.FullName, name, MethodSig, null, null, this, null); /// /// Gets/sets the /// public MethodSig MethodSig { - get { return signature as MethodSig; } - set { signature = value; } + get => signature as MethodSig; + set => signature = value; } /// /// Gets the parameters /// - public ParameterList Parameters { - get { return parameterList; } - } + public ParameterList Parameters => parameterList; /// int IGenericParameterProvider.NumberOfGenericParameters { @@ -596,10 +496,7 @@ public CallingConvention CallingConvention { /// Gets/sets the method return type /// public TypeSig ReturnType { - get { - var ms = MethodSig; - return ms == null ? null : ms.RetType; - } + get => MethodSig?.RetType; set { var ms = MethodSig; if (ms != null) @@ -610,9 +507,7 @@ public TypeSig ReturnType { /// /// true if the method returns a value (i.e., return type is not ) /// - public bool HasReturnType { - get { return ReturnType.RemovePinnedAndModifiers().GetElementType() != ElementType.Void; } - } + public bool HasReturnType => ReturnType.RemovePinnedAndModifiers().GetElementType() != ElementType.Void; /// /// Gets/sets the method semantics attributes. If you remove/add a method to a property or @@ -625,16 +520,14 @@ public MethodSemanticsAttributes SemanticsAttributes { InitializeSemanticsAttributes(); return (MethodSemanticsAttributes)semAttrs; } - set { semAttrs = (ushort)value | SEMATTRS_INITD; } + set => semAttrs = (ushort)value | SEMATTRS_INITD; } /// Set when has been initialized protected internal static int SEMATTRS_INITD = unchecked((int)0x80000000); /// protected internal int semAttrs; /// Initializes - protected virtual void InitializeSemanticsAttributes() { - semAttrs = 0 | SEMATTRS_INITD; - } + protected virtual void InitializeSemanticsAttributes() => semAttrs = 0 | SEMATTRS_INITD; /// /// Set or clear flags in @@ -750,359 +643,327 @@ void ModifyImplAttributes(bool set, MethodImplAttributes flags) { /// Gets/sets the method access /// public MethodAttributes Access { - get { return (MethodAttributes)attributes & MethodAttributes.MemberAccessMask; } - set { ModifyAttributes(~MethodAttributes.MemberAccessMask, value & MethodAttributes.MemberAccessMask); } + get => (MethodAttributes)attributes & MethodAttributes.MemberAccessMask; + set => ModifyAttributes(~MethodAttributes.MemberAccessMask, value & MethodAttributes.MemberAccessMask); } /// /// true if is set /// - public bool IsCompilerControlled { - get { return IsPrivateScope; } - } + public bool IsCompilerControlled => IsPrivateScope; /// /// true if is set /// - public bool IsPrivateScope { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope; } - } + public bool IsPrivateScope => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope; /// /// true if is set /// - public bool IsPrivate { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } - } + public bool IsPrivate => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; /// /// true if is set /// - public bool IsFamilyAndAssembly { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } - } + public bool IsFamilyAndAssembly => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; /// /// true if is set /// - public bool IsAssembly { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } - } + public bool IsAssembly => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; /// /// true if is set /// - public bool IsFamily { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } - } + public bool IsFamily => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; /// /// true if is set /// - public bool IsFamilyOrAssembly { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } - } + public bool IsFamilyOrAssembly => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; /// /// true if is set /// - public bool IsPublic { - get { return ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } - } + public bool IsPublic => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; /// /// Gets/sets the bit /// public bool IsStatic { - get { return ((MethodAttributes)attributes & MethodAttributes.Static) != 0; } - set { ModifyAttributes(value, MethodAttributes.Static); } + get => ((MethodAttributes)attributes & MethodAttributes.Static) != 0; + set => ModifyAttributes(value, MethodAttributes.Static); } /// /// Gets/sets the bit /// public bool IsFinal { - get { return ((MethodAttributes)attributes & MethodAttributes.Final) != 0; } - set { ModifyAttributes(value, MethodAttributes.Final); } + get => ((MethodAttributes)attributes & MethodAttributes.Final) != 0; + set => ModifyAttributes(value, MethodAttributes.Final); } /// /// Gets/sets the bit /// public bool IsVirtual { - get { return ((MethodAttributes)attributes & MethodAttributes.Virtual) != 0; } - set { ModifyAttributes(value, MethodAttributes.Virtual); } + get => ((MethodAttributes)attributes & MethodAttributes.Virtual) != 0; + set => ModifyAttributes(value, MethodAttributes.Virtual); } /// /// Gets/sets the bit /// public bool IsHideBySig { - get { return ((MethodAttributes)attributes & MethodAttributes.HideBySig) != 0; } - set { ModifyAttributes(value, MethodAttributes.HideBySig); } + get => ((MethodAttributes)attributes & MethodAttributes.HideBySig) != 0; + set => ModifyAttributes(value, MethodAttributes.HideBySig); } /// /// Gets/sets the bit /// public bool IsNewSlot { - get { return ((MethodAttributes)attributes & MethodAttributes.NewSlot) != 0; } - set { ModifyAttributes(value, MethodAttributes.NewSlot); } + get => ((MethodAttributes)attributes & MethodAttributes.NewSlot) != 0; + set => ModifyAttributes(value, MethodAttributes.NewSlot); } /// /// Gets/sets the bit /// public bool IsReuseSlot { - get { return ((MethodAttributes)attributes & MethodAttributes.NewSlot) == 0; } - set { ModifyAttributes(!value, MethodAttributes.NewSlot); } + get => ((MethodAttributes)attributes & MethodAttributes.NewSlot) == 0; + set => ModifyAttributes(!value, MethodAttributes.NewSlot); } /// /// Gets/sets the bit /// public bool IsCheckAccessOnOverride { - get { return ((MethodAttributes)attributes & MethodAttributes.CheckAccessOnOverride) != 0; } - set { ModifyAttributes(value, MethodAttributes.CheckAccessOnOverride); } + get => ((MethodAttributes)attributes & MethodAttributes.CheckAccessOnOverride) != 0; + set => ModifyAttributes(value, MethodAttributes.CheckAccessOnOverride); } /// /// Gets/sets the bit /// public bool IsAbstract { - get { return ((MethodAttributes)attributes & MethodAttributes.Abstract) != 0; } - set { ModifyAttributes(value, MethodAttributes.Abstract); } + get => ((MethodAttributes)attributes & MethodAttributes.Abstract) != 0; + set => ModifyAttributes(value, MethodAttributes.Abstract); } /// /// Gets/sets the bit /// public bool IsSpecialName { - get { return ((MethodAttributes)attributes & MethodAttributes.SpecialName) != 0; } - set { ModifyAttributes(value, MethodAttributes.SpecialName); } + get => ((MethodAttributes)attributes & MethodAttributes.SpecialName) != 0; + set => ModifyAttributes(value, MethodAttributes.SpecialName); } /// /// Gets/sets the bit /// public bool IsPinvokeImpl { - get { return ((MethodAttributes)attributes & MethodAttributes.PinvokeImpl) != 0; } - set { ModifyAttributes(value, MethodAttributes.PinvokeImpl); } + get => ((MethodAttributes)attributes & MethodAttributes.PinvokeImpl) != 0; + set => ModifyAttributes(value, MethodAttributes.PinvokeImpl); } /// /// Gets/sets the bit /// public bool IsUnmanagedExport { - get { return ((MethodAttributes)attributes & MethodAttributes.UnmanagedExport) != 0; } - set { ModifyAttributes(value, MethodAttributes.UnmanagedExport); } + get => ((MethodAttributes)attributes & MethodAttributes.UnmanagedExport) != 0; + set => ModifyAttributes(value, MethodAttributes.UnmanagedExport); } /// /// Gets/sets the bit /// public bool IsRuntimeSpecialName { - get { return ((MethodAttributes)attributes & MethodAttributes.RTSpecialName) != 0; } - set { ModifyAttributes(value, MethodAttributes.RTSpecialName); } + get => ((MethodAttributes)attributes & MethodAttributes.RTSpecialName) != 0; + set => ModifyAttributes(value, MethodAttributes.RTSpecialName); } /// /// Gets/sets the bit /// public bool HasSecurity { - get { return ((MethodAttributes)attributes & MethodAttributes.HasSecurity) != 0; } - set { ModifyAttributes(value, MethodAttributes.HasSecurity); } + get => ((MethodAttributes)attributes & MethodAttributes.HasSecurity) != 0; + set => ModifyAttributes(value, MethodAttributes.HasSecurity); } /// /// Gets/sets the bit /// public bool IsRequireSecObject { - get { return ((MethodAttributes)attributes & MethodAttributes.RequireSecObject) != 0; } - set { ModifyAttributes(value, MethodAttributes.RequireSecObject); } + get => ((MethodAttributes)attributes & MethodAttributes.RequireSecObject) != 0; + set => ModifyAttributes(value, MethodAttributes.RequireSecObject); } /// /// Gets/sets the code type /// public MethodImplAttributes CodeType { - get { return (MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask; } - set { ModifyImplAttributes(~MethodImplAttributes.CodeTypeMask, value & MethodImplAttributes.CodeTypeMask); } + get => (MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask; + set => ModifyImplAttributes(~MethodImplAttributes.CodeTypeMask, value & MethodImplAttributes.CodeTypeMask); } /// /// true if is set /// - public bool IsIL { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.IL; } - } + public bool IsIL => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.IL; /// /// true if is set /// - public bool IsNative { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Native; } - } + public bool IsNative => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Native; /// /// true if is set /// - public bool IsOPTIL { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.OPTIL; } - } + public bool IsOPTIL => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.OPTIL; /// /// true if is set /// - public bool IsRuntime { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Runtime; } - } + public bool IsRuntime => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Runtime; /// /// Gets/sets the bit /// public bool IsUnmanaged { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.Unmanaged) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.Unmanaged); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.Unmanaged) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.Unmanaged); } /// /// Gets/sets the bit /// public bool IsManaged { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.Unmanaged) == 0; } - set { ModifyImplAttributes(!value, MethodImplAttributes.Unmanaged); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.Unmanaged) == 0; + set => ModifyImplAttributes(!value, MethodImplAttributes.Unmanaged); } /// /// Gets/sets the bit /// public bool IsForwardRef { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.ForwardRef) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.ForwardRef); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.ForwardRef) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.ForwardRef); } /// /// Gets/sets the bit /// public bool IsPreserveSig { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.PreserveSig) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.PreserveSig); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.PreserveSig) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.PreserveSig); } /// /// Gets/sets the bit /// public bool IsInternalCall { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.InternalCall) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.InternalCall); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.InternalCall) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.InternalCall); } /// /// Gets/sets the bit /// public bool IsSynchronized { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.Synchronized) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.Synchronized); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.Synchronized) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.Synchronized); } /// /// Gets/sets the bit /// public bool IsNoInlining { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.NoInlining) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.NoInlining); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.NoInlining) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.NoInlining); } /// /// Gets/sets the bit /// public bool IsAggressiveInlining { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.AggressiveInlining) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.AggressiveInlining); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.AggressiveInlining) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.AggressiveInlining); } /// /// Gets/sets the bit /// public bool IsNoOptimization { - get { return ((MethodImplAttributes)implAttributes & MethodImplAttributes.NoOptimization) != 0; } - set { ModifyImplAttributes(value, MethodImplAttributes.NoOptimization); } + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.NoOptimization) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.NoOptimization); } /// /// Gets/sets the bit /// public bool IsSetter { - get { return (SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0; } - set { ModifyAttributes(value, MethodSemanticsAttributes.Setter); } + get => (SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0; + set => ModifyAttributes(value, MethodSemanticsAttributes.Setter); } /// /// Gets/sets the bit /// public bool IsGetter { - get { return (SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0; } - set { ModifyAttributes(value, MethodSemanticsAttributes.Getter); } + get => (SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0; + set => ModifyAttributes(value, MethodSemanticsAttributes.Getter); } /// /// Gets/sets the bit /// public bool IsOther { - get { return (SemanticsAttributes & MethodSemanticsAttributes.Other) != 0; } - set { ModifyAttributes(value, MethodSemanticsAttributes.Other); } + get => (SemanticsAttributes & MethodSemanticsAttributes.Other) != 0; + set => ModifyAttributes(value, MethodSemanticsAttributes.Other); } /// /// Gets/sets the bit /// public bool IsAddOn { - get { return (SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0; } - set { ModifyAttributes(value, MethodSemanticsAttributes.AddOn); } + get => (SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0; + set => ModifyAttributes(value, MethodSemanticsAttributes.AddOn); } /// /// Gets/sets the bit /// public bool IsRemoveOn { - get { return (SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0; } - set { ModifyAttributes(value, MethodSemanticsAttributes.RemoveOn); } + get => (SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0; + set => ModifyAttributes(value, MethodSemanticsAttributes.RemoveOn); } /// /// Gets/sets the bit /// public bool IsFire { - get { return (SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0; } - set { ModifyAttributes(value, MethodSemanticsAttributes.Fire); } + get => (SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0; + set => ModifyAttributes(value, MethodSemanticsAttributes.Fire); } /// /// true if this is the static type constructor /// - public bool IsStaticConstructor { - get { return IsRuntimeSpecialName && UTF8String.Equals(name, StaticConstructorName); } - } + public bool IsStaticConstructor => IsRuntimeSpecialName && UTF8String.Equals(name, StaticConstructorName); /// /// true if this is an instance constructor /// - public bool IsInstanceConstructor { - get { return IsRuntimeSpecialName && UTF8String.Equals(name, InstanceConstructorName); } - } + public bool IsInstanceConstructor => IsRuntimeSpecialName && UTF8String.Equals(name, InstanceConstructorName); /// /// true if this is a static or an instance constructor /// - public bool IsConstructor { - get { return IsStaticConstructor || IsInstanceConstructor; } - } + public bool IsConstructor => IsStaticConstructor || IsInstanceConstructor; /// - void IListListener.OnLazyAdd(int index, ref GenericParam value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref GenericParam value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref GenericParam value) { #if DEBUG @@ -1119,9 +980,7 @@ void IListListener.OnAdd(int index, GenericParam value) { } /// - void IListListener.OnRemove(int index, GenericParam value) { - value.Owner = null; - } + void IListListener.OnRemove(int index, GenericParam value) => value.Owner = null; /// void IListListener.OnResize(int index) { @@ -1134,9 +993,7 @@ void IListListener.OnClear() { } /// - void IListListener.OnLazyAdd(int index, ref ParamDef value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref ParamDef value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref ParamDef value) { #if DEBUG @@ -1153,9 +1010,7 @@ void IListListener.OnAdd(int index, ParamDef value) { } /// - void IListListener.OnRemove(int index, ParamDef value) { - value.DeclaringMethod = null; - } + void IListListener.OnRemove(int index, ParamDef value) => value.DeclaringMethod = null; /// void IListListener.OnResize(int index) { @@ -1168,9 +1023,7 @@ void IListListener.OnClear() { } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -1181,10 +1034,10 @@ public class MethodDefUser : MethodDef { /// Default constructor /// public MethodDefUser() { - this.paramDefs = new LazyList(this); - this.genericParameters = new LazyList(this); - this.parameterList = new ParameterList(this, null); - this.semAttrs = 0 | SEMATTRS_INITD; + paramDefs = new LazyList(this); + genericParameters = new LazyList(this); + parameterList = new ParameterList(this, null); + semAttrs = 0 | SEMATTRS_INITD; } /// @@ -1233,13 +1086,13 @@ public MethodDefUser(UTF8String name, MethodSig methodSig, MethodImplAttributes /// Flags public MethodDefUser(UTF8String name, MethodSig methodSig, MethodImplAttributes implFlags, MethodAttributes flags) { this.name = name; - this.signature = methodSig; - this.paramDefs = new LazyList(this); - this.genericParameters = new LazyList(this); - this.implAttributes = (int)implFlags; - this.attributes = (int)flags; - this.parameterList = new ParameterList(this, null); - this.semAttrs = 0 | SEMATTRS_INITD; + signature = methodSig; + paramDefs = new LazyList(this); + genericParameters = new LazyList(this); + implAttributes = (int)implFlags; + attributes = (int)flags; + parameterList = new ParameterList(this, null); + semAttrs = 0 | SEMATTRS_INITD; } } @@ -1255,9 +1108,7 @@ sealed class MethodDefMD : MethodDef, IMDTokenProviderMD { readonly MethodImplAttributes origImplAttributes; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeParamDefs() { @@ -1281,14 +1132,10 @@ protected override void InitializeDeclSecurities() { } /// - protected override ImplMap GetImplMap_NoLock() { - return readerModule.ResolveImplMap(readerModule.MetaData.GetImplMapRid(Table.Method, origRid)); - } + protected override ImplMap GetImplMap_NoLock() => readerModule.ResolveImplMap(readerModule.MetaData.GetImplMapRid(Table.Method, origRid)); /// - protected override MethodBody GetMethodBody_NoLock() { - return readerModule.ReadMethodBody(this, origRva, origImplAttributes, new GenericParamContext(declaringType2, this)); - } + protected override MethodBody GetMethodBody_NoLock() => readerModule.ReadMethodBody(this, origRva, origImplAttributes, new GenericParamContext(declaringType2, this)); /// protected override void InitializeCustomAttributes() { @@ -1315,8 +1162,7 @@ protected override void InitializeOverrides() { /// protected override void InitializeSemanticsAttributes() { - var dt = DeclaringType as TypeDefMD; - if (dt != null) + if (DeclaringType is TypeDefMD dt) dt.InitializeMethodSemanticsAttributes(); semAttrs |= SEMATTRS_INITD; } @@ -1333,20 +1179,19 @@ public MethodDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.MethodTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Method rid {0} does not exist", rid)); + throw new BadImageFormatException($"Method rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint signature = readerModule.TablesStream.ReadMethodRow(origRid, out this.rva, out this.implAttributes, out this.attributes, out name); + uint signature = readerModule.TablesStream.ReadMethodRow(origRid, out rva, out implAttributes, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); - this.origRva = rva; - this.origImplAttributes = (MethodImplAttributes)implAttributes; - this.declaringType2 = readerModule.GetOwnerType(this); + origRva = rva; + origImplAttributes = (MethodImplAttributes)implAttributes; + declaringType2 = readerModule.GetOwnerType(this); this.signature = readerModule.ReadSignature(signature, new GenericParamContext(declaringType2, this)); - this.parameterList = new ParameterList(this, declaringType2); - this.exportInfo = readerModule.GetExportInfo(rid); + parameterList = new ParameterList(this, declaringType2); + exportInfo = readerModule.GetExportInfo(rid); } internal MethodDefMD InitializeAll() { diff --git a/src/DotNet/MethodExportInfo.cs b/src/DotNet/MethodExportInfo.cs index e7d7bd406..6c8b31b96 100644 --- a/src/DotNet/MethodExportInfo.cs +++ b/src/DotNet/MethodExportInfo.cs @@ -18,8 +18,8 @@ public sealed class MethodExportInfo { /// Gets the ordinal or null /// public ushort? Ordinal { - get { return ordinal; } - set { ordinal = value; } + get => ordinal; + set => ordinal = value; } /// @@ -27,24 +27,22 @@ public ushort? Ordinal { /// () is used as the exported name. /// public string Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets the options /// public MethodExportInfoOptions Options { - get { return options; } - set { options = value; } + get => options; + set => options = value; } /// /// Constructor /// - public MethodExportInfo() { - options = DefaultOptions; - } + public MethodExportInfo() => options = DefaultOptions; /// /// Constructor diff --git a/src/DotNet/MethodExportInfoProvider.cs b/src/DotNet/MethodExportInfoProvider.cs index 9fd9477a3..872b42a89 100644 --- a/src/DotNet/MethodExportInfoProvider.cs +++ b/src/DotNet/MethodExportInfoProvider.cs @@ -33,9 +33,8 @@ void Initialize(ModuleDefMD module) { if (exportHdr.VirtualAddress == 0 || exportHdr.Size < 0x28) return; - CpuArch cpuArch; - if (!CpuArch.TryGetCpuArch(peImage.ImageNTHeaders.FileHeader.Machine, out cpuArch)) { - Debug.Fail(string.Format("Exported methods: Unsupported machine: {0}", peImage.ImageNTHeaders.FileHeader.Machine)); + if (!CpuArch.TryGetCpuArch(peImage.ImageNTHeaders.FileHeader.Machine, out var cpuArch)) { + Debug.Fail($"Exported methods: Unsupported machine: {peImage.ImageNTHeaders.FileHeader.Machine}"); return; } @@ -55,9 +54,8 @@ void Initialize(ModuleDefMD module) { int slotSize = is64bit ? 8 : 4; while (numSlots-- > 0 && reader.CanRead(slotSize)) { var tokenPos = reader.Position; - MethodExportInfo exportInfo; uint token = reader.ReadUInt32(); - bool b = offsetToInfo.TryGetValue(tokenPos, out exportInfo); + bool b = offsetToInfo.TryGetValue(tokenPos, out var exportInfo); Debug.Assert(token == 0 || b); if (b) { exportInfo = new MethodExportInfo(exportInfo.Name, exportInfo.Ordinal, exportOptions); @@ -100,9 +98,8 @@ static Dictionary GetOffsetToExportInfoDictionary(IImage for (int i = 0; i < allInfos.Length; i++) { var currOffset = reader.Position; var nextOffset = reader.Position + 4; - uint funcRva; reader.Position = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); - bool rvaValid = cpuArch.TryGetExportedRvaFromStub(reader, peImage, out funcRva); + bool rvaValid = cpuArch.TryGetExportedRvaFromStub(reader, peImage, out uint funcRva); long funcOffset = rvaValid ? (long)peImage.ToFileOffset((RVA)funcRva) : 0; var exportInfo = new MethodExportInfo((ushort)(ordinalBase + (uint)i)); if (funcOffset != 0) @@ -154,8 +151,7 @@ static string ReadMethodNameASCIIZ(IImageStream reader, long offset) { public MethodExportInfo GetMethodExportInfo(uint token) { if (toInfo.Count == 0) return null; - MethodExportInfo info; - if (toInfo.TryGetValue(token, out info)) + if (toInfo.TryGetValue(token, out var info)) return new MethodExportInfo(info.Name, info.Ordinal, info.Options); return null; } diff --git a/src/DotNet/MethodOverride.cs b/src/DotNet/MethodOverride.cs index b5d2feeb1..b1714fa97 100644 --- a/src/DotNet/MethodOverride.cs +++ b/src/DotNet/MethodOverride.cs @@ -21,8 +21,8 @@ public struct MethodOverride { /// Method body /// The method implements public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration) { - this.MethodBody = methodBody; - this.MethodDeclaration = methodDeclaration; + MethodBody = methodBody; + MethodDeclaration = methodDeclaration; } } } diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index 713fd8c58..5a23bb444 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -23,27 +23,23 @@ public abstract class MethodSpec : IHasCustomAttribute, IHasCustomDebugInformati protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.MethodSpec, rid); } - } + public MDToken MDToken => new MDToken(Table.MethodSpec, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 21; } - } + public int HasCustomAttributeTag => 21; /// /// From column MethodSpec.Method /// public IMethodDefOrRef Method { - get { return method; } - set { method = value; } + get => method; + set => method = value; } /// protected IMethodDefOrRef method; @@ -52,8 +48,8 @@ public IMethodDefOrRef Method { /// From column MethodSpec.Instantiation /// public CallingConventionSig Instantiation { - get { return instantiation; } - set { instantiation = value; } + get => instantiation; + set => instantiation = value; } /// protected CallingConventionSig instantiation; @@ -71,24 +67,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 21; } - } + public int HasCustomDebugInformationTag => 21; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -103,16 +92,12 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// MethodSig IMethod.MethodSig { - get { - var m = method; - return m == null ? null : m.MethodSig; - } + get => method?.MethodSig; set { var m = method; if (m != null) @@ -134,58 +119,37 @@ public UTF8String Name { } /// - public ITypeDefOrRef DeclaringType { - get { - var m = method; - return m == null ? null : m.DeclaringType; - } - } + public ITypeDefOrRef DeclaringType => method?.DeclaringType; /// /// Gets/sets the generic instance method sig /// public GenericInstMethodSig GenericInstMethodSig { - get { return instantiation as GenericInstMethodSig; } - set { instantiation = value; } + get => instantiation as GenericInstMethodSig; + set => instantiation = value; } /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { - var sig = GenericInstMethodSig; - return sig == null ? 0 : sig.GenericArguments.Count; - } - } + int IGenericParameterProvider.NumberOfGenericParameters => GenericInstMethodSig?.GenericArguments.Count ?? 0; /// - public ModuleDef Module { - get { - var m = method; - return m == null ? null : m.Module; - } - } + public ModuleDef Module => method?.Module; /// /// Gets the full name /// public string FullName { get { - var gims = GenericInstMethodSig; - var methodGenArgs = gims == null ? null : gims.GenericArguments; + var methodGenArgs = GenericInstMethodSig?.GenericArguments; var m = method; - var methodDef = m as MethodDef; - if (methodDef != null) { - var declaringType = methodDef.DeclaringType; - return FullNameCreator.MethodFullName(declaringType == null ? null : declaringType.FullName, methodDef.Name, methodDef.MethodSig, null, methodGenArgs, null, null); - } + if (m is MethodDef methodDef) + return FullNameCreator.MethodFullName(methodDef.DeclaringType?.FullName, methodDef.Name, methodDef.MethodSig, null, methodGenArgs, null, null); - var memberRef = m as MemberRef; - if (memberRef != null) { + if (m is MemberRef memberRef) { var methodSig = memberRef.MethodSig; if (methodSig != null) { - var tsOwner = memberRef.Class as TypeSpec; - var gis = tsOwner == null ? null : tsOwner.TypeSig as GenericInstSig; - var typeGenArgs = gis == null ? null : gis.GenericArguments; + var gis = (memberRef.Class as TypeSpec)?.TypeSig as GenericInstSig; + var typeGenArgs = gis?.GenericArguments; return FullNameCreator.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs, null, null); } } @@ -194,66 +158,23 @@ public string FullName { } } - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return true; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return true; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } - - bool IContainsGenericParameter.ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => true; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => true; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; + bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -281,7 +202,7 @@ public MethodSpecUser(IMethodDefOrRef method) /// The instantiated method sig public MethodSpecUser(IMethodDefOrRef method, GenericInstMethodSig sig) { this.method = method; - this.instantiation = sig; + instantiation = sig; } } @@ -296,9 +217,7 @@ sealed class MethodSpecMD : MethodSpec, IMDTokenProviderMD { readonly GenericParamContext gpContext; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -327,14 +246,13 @@ public MethodSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpCo if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.MethodSpecTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("MethodSpec rid {0} does not exist", rid)); + throw new BadImageFormatException($"MethodSpec rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; this.gpContext = gpContext; - uint method; - uint instantiation = readerModule.TablesStream.ReadMethodSpecRow(origRid, out method); + uint instantiation = readerModule.TablesStream.ReadMethodSpecRow(origRid, out uint method); this.method = readerModule.ResolveMethodDefOrRef(method, gpContext); this.instantiation = readerModule.ReadSignature(instantiation, gpContext); } diff --git a/src/DotNet/ModuleContext.cs b/src/DotNet/ModuleContext.cs index 3071923d9..f7959d6be 100644 --- a/src/DotNet/ModuleContext.cs +++ b/src/DotNet/ModuleContext.cs @@ -19,7 +19,7 @@ public IAssemblyResolver AssemblyResolver { Interlocked.CompareExchange(ref assemblyResolver, NullResolver.Instance, null); return assemblyResolver; } - set { assemblyResolver = value; } + set => assemblyResolver = value; } /// @@ -31,7 +31,7 @@ public IResolver Resolver { Interlocked.CompareExchange(ref resolver, NullResolver.Instance, null); return resolver; } - set { resolver = value; } + set => resolver = value; } /// diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index a827b2347..90bfddba9 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -52,8 +52,8 @@ public sealed class ModuleCreationOptions { /// Default constructor /// public ModuleCreationOptions() { - this.PdbImplementation = PdbImplType.Default; - this.TryToLoadPdbFromDisk = true; + PdbImplementation = PdbImplType.Default; + TryToLoadPdbFromDisk = true; } /// @@ -61,9 +61,9 @@ public ModuleCreationOptions() { /// /// Module context public ModuleCreationOptions(ModuleContext context) { - this.Context = context; - this.PdbImplementation = PdbImplType.Default; - this.TryToLoadPdbFromDisk = true; + Context = context; + PdbImplementation = PdbImplType.Default; + TryToLoadPdbFromDisk = true; } } diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 6924d630f..b092327b8 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -60,51 +60,41 @@ public abstract class ModuleDef : IHasCustomAttribute, IHasCustomDebugInformatio protected ModuleContext context; /// - public MDToken MDToken { - get { return new MDToken(Table.Module, rid); } - } + public MDToken MDToken => new MDToken(Table.Module, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 7; } - } + public int HasCustomAttributeTag => 7; /// - public int ResolutionScopeTag { - get { return 0; } - } + public int ResolutionScopeTag => 0; /// /// Gets/sets a user value. This is never used by dnlib. This property isn't thread safe. /// public object Tag { - get { return tag; } - set { tag = value; } + get => tag; + set => tag = value; } object tag; /// - public ScopeType ScopeType { - get { return ScopeType.ModuleDef; } - } + public ScopeType ScopeType => ScopeType.ModuleDef; /// - public string ScopeName { - get { return FullName; } - } + public string ScopeName => FullName; /// /// Gets/sets Module.Generation column /// public ushort Generation { - get { return generation; } - set { generation = value; } + get => generation; + set => generation = value; } /// protected ushort generation; @@ -113,8 +103,8 @@ public ushort Generation { /// Gets/sets Module.Name column /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -123,8 +113,8 @@ public UTF8String Name { /// Gets/sets Module.Mvid column /// public Guid? Mvid { - get { return mvid; } - set { mvid = value; } + get => mvid; + set => mvid = value; } /// protected Guid? mvid; @@ -133,8 +123,8 @@ public Guid? Mvid { /// Gets/sets Module.EncId column /// public Guid? EncId { - get { return encId; } - set { encId = value; } + get => encId; + set => encId = value; } /// protected Guid? encId; @@ -143,8 +133,8 @@ public Guid? EncId { /// Gets/sets Module.EncBaseId column /// public Guid? EncBaseId { - get { return encBaseId; } - set { encBaseId = value; } + get => encBaseId; + set => encBaseId = value; } /// protected Guid? encBaseId; @@ -162,19 +152,14 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public int HasCustomDebugInformationTag { - get { return 7; } - } + public int HasCustomDebugInformationTag => 7; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -189,17 +174,16 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Gets the module's assembly. To set this value, add this /// to . /// public AssemblyDef Assembly { - get { return assembly; } - internal set { assembly = value; } + get => assembly; + internal set => assembly = value; } /// protected AssemblyDef assembly; @@ -217,9 +201,8 @@ public ThreadSafe.IList Types { /// protected LazyList types; /// Initializes - protected virtual void InitializeTypes() { + protected virtual void InitializeTypes() => Interlocked.CompareExchange(ref types, new LazyList(this), null); - } /// /// Gets a list of all s @@ -234,9 +217,8 @@ public ThreadSafe.IList ExportedTypes { /// protected ThreadSafe.IList exportedTypes; /// Initializes - protected virtual void InitializeExportedTypes() { + protected virtual void InitializeExportedTypes() => Interlocked.CompareExchange(ref exportedTypes, ThreadSafeListCreator.Create(), null); - } /// /// Gets/sets the native entry point. Only one of and @@ -305,47 +287,35 @@ void InitializeNativeAndManagedEntryPoint() { #endif } /// Called to initialize - protected virtual RVA GetNativeEntryPoint_NoLock() { - return 0; - } + protected virtual RVA GetNativeEntryPoint_NoLock() => 0; /// Called to initialize - protected virtual IManagedEntryPoint GetManagedEntryPoint_NoLock() { - return null; - } + protected virtual IManagedEntryPoint GetManagedEntryPoint_NoLock() => null; /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// /// Gets/sets the entry point method /// public MethodDef EntryPoint { - get { return ManagedEntryPoint as MethodDef; } - set { ManagedEntryPoint = value; } + get => ManagedEntryPoint as MethodDef; + set => ManagedEntryPoint = value; } /// /// true if is non-zero /// - public bool IsNativeEntryPointValid { - get { return NativeEntryPoint != 0; } - } + public bool IsNativeEntryPointValid => NativeEntryPoint != 0; /// /// true if is non-null /// - public bool IsManagedEntryPointValid { - get { return ManagedEntryPoint != null; } - } + public bool IsManagedEntryPointValid => ManagedEntryPoint != null; /// /// true if is non-null /// - public bool IsEntryPointValid { - get { return EntryPoint != null; } - } + public bool IsEntryPointValid => EntryPoint != null; /// /// Gets a list of all s @@ -360,9 +330,8 @@ public ResourceCollection Resources { /// protected ResourceCollection resources; /// Initializes - protected virtual void InitializeResources() { + protected virtual void InitializeResources() => Interlocked.CompareExchange(ref resources, new ResourceCollection(), null); - } /// /// Gets/sets the . This is null if there are no @@ -404,42 +373,32 @@ void InitializeVTableFixups() { } /// Called to initialize - protected virtual VTableFixups GetVTableFixups_NoLock() { - return null; - } + protected virtual VTableFixups GetVTableFixups_NoLock() => null; /// /// true if there's at least one in /// - public bool HasTypes { - get { return Types.Count > 0; } - } + public bool HasTypes => Types.Count > 0; /// /// true if there's at least one in /// - public bool HasExportedTypes { - get { return ExportedTypes.Count > 0; } - } + public bool HasExportedTypes => ExportedTypes.Count > 0; /// /// true if there's at least one in /// - public bool HasResources { - get { return Resources.Count > 0; } - } + public bool HasResources => Resources.Count > 0; /// - public string FullName { - get { return UTF8String.ToSystemStringOrEmpty(name); } - } + public string FullName => UTF8String.ToSystemStringOrEmpty(name); /// /// Gets/sets the path of the module or an empty string if it wasn't loaded from disk /// public string Location { - get { return location; } - set { location = value; } + get => location; + set => location = value; } /// protected string location; @@ -447,9 +406,7 @@ public string Location { /// /// Gets the /// - public ICorLibTypes CorLibTypes { - get { return corLibTypes; } - } + public ICorLibTypes CorLibTypes => corLibTypes; /// /// Gets the instance @@ -471,7 +428,7 @@ public ModuleContext Context { Interlocked.CompareExchange(ref context, new ModuleContext(), null); return context; } - set { context = value ?? new ModuleContext(); } + set => context = value ?? new ModuleContext(); } /// @@ -487,8 +444,8 @@ public ModuleContext Context { /// /// public bool EnableTypeDefFindCache { - get { return TypeDefFinder.IsCacheEnabled; } - set { TypeDefFinder.IsCacheEnabled = value; } + get => TypeDefFinder.IsCacheEnabled; + set => TypeDefFinder.IsCacheEnabled = value; } /// @@ -504,9 +461,7 @@ public bool IsManifestModule { /// /// Gets the global (aka. <Module>) type or null if there are no types /// - public TypeDef GlobalType { - get { return Types.Get(0, null); } - } + public TypeDef GlobalType => Types.Get(0, null); /// /// true if it's the core library module, false if it's not the core library module, @@ -553,17 +508,13 @@ void InitializeWin32Resources() { } /// Called to initialize - protected virtual Win32Resources GetWin32Resources_NoLock() { - return null; - } + protected virtual Win32Resources GetWin32Resources_NoLock() => null; /// /// Gets the . This is null if no PDB file /// has been loaded or if no PDB file could be found. /// - public PdbState PdbState { - get { return pdbState; } - } + public PdbState PdbState => pdbState; /// /// Module kind @@ -586,7 +537,7 @@ public PdbState PdbState { /// /// Not thread safe public string RuntimeVersion { - get { return runtimeVersion; } + get => runtimeVersion; set { if (runtimeVersion != value) { runtimeVersion = value; @@ -616,23 +567,17 @@ public WinMDStatus WinMDStatus { /// /// true if this is a WinMD file /// - public bool IsWinMD { - get { return WinMDStatus != WinMDStatus.None; } - } + public bool IsWinMD => WinMDStatus != WinMDStatus.None; /// /// true if this is a managed WinMD file /// - public bool IsManagedWinMD { - get { return WinMDStatus == WinMDStatus.Managed; } - } + public bool IsManagedWinMD => WinMDStatus == WinMDStatus.Managed; /// /// true if this is a pure (non-managed) WinMD file /// - public bool IsPureWinMD { - get { return WinMDStatus == WinMDStatus.Pure; } - } + public bool IsPureWinMD => WinMDStatus == WinMDStatus.Pure; /// /// Gets the CLR runtime version of the managed WinMD file or null if none. This is @@ -721,88 +666,65 @@ public bool IsClr10 { /// /// true if is the CLR v1.0 string /// - public bool IsClr10Exactly { - get { - return RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10 || - RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10_X86RETAIL || - RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10_RETAIL || - RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10_COMPLUS; - } - } + public bool IsClr10Exactly => + RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10 || + RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10_X86RETAIL || + RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10_RETAIL || + RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_10_COMPLUS; /// /// true if is the CLR v1.1 string (only the major /// and minor version numbers are checked) /// - public bool IsClr11 { - get { return (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_11_PREFIX); } - } + public bool IsClr11 => (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_11_PREFIX); /// /// true if is the CLR v1.1 string /// - public bool IsClr11Exactly { - get { return RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_11; } - } + public bool IsClr11Exactly => RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_11; /// /// true if is the CLR v1.0 or v1.1 string (only the /// major and minor version numbers are checked) /// - public bool IsClr1x { - get { return IsClr10 || IsClr11; } - } + public bool IsClr1x => IsClr10 || IsClr11; /// /// true if is the CLR v1.0 or v1.1 string /// - public bool IsClr1xExactly { - get { return IsClr10Exactly || IsClr11Exactly; } - } + public bool IsClr1xExactly => IsClr10Exactly || IsClr11Exactly; /// /// true if is the CLR v2.0 string (only the major /// and minor version numbers are checked) /// - public bool IsClr20 { - get { return (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_20_PREFIX); } - } + public bool IsClr20 => (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_20_PREFIX); /// /// true if is the CLR v2.0 string /// - public bool IsClr20Exactly { - get { return RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_20; } - } + public bool IsClr20Exactly => RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_20; /// /// true if is the CLR v4.0 string (only the major /// and minor version numbers are checked) /// - public bool IsClr40 { - get { return (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_40_PREFIX); } - } + public bool IsClr40 => (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_40_PREFIX); /// /// true if is the CLR v4.0 string /// - public bool IsClr40Exactly { - get { return RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_40; } - } + public bool IsClr40Exactly => RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_40; /// /// true if is the ECMA 2002 string /// - public bool IsEcma2002 { - get { return RuntimeVersion == MDHeaderRuntimeVersion.ECMA_2002; } - } + public bool IsEcma2002 => RuntimeVersion == MDHeaderRuntimeVersion.ECMA_2002; /// /// true if is the ECMA 2005 string /// - public bool IsEcma2005 { - get { return RuntimeVersion == MDHeaderRuntimeVersion.ECMA_2005; } - } + public bool IsEcma2005 => RuntimeVersion == MDHeaderRuntimeVersion.ECMA_2005; /// /// Gets/sets the (from PE header) @@ -812,37 +734,29 @@ public bool IsEcma2005 { /// /// true if is /// - public bool IsI386 { - get { return Machine == Machine.I386; } - } + public bool IsI386 => Machine == Machine.I386; /// /// true if is /// - public bool IsIA64 { - get { return Machine == Machine.IA64; } - } + public bool IsIA64 => Machine == Machine.IA64; /// /// true if is /// - public bool IsAMD64 { - get { return Machine == Machine.AMD64; } - } + public bool IsAMD64 => Machine == Machine.AMD64; /// /// true if is /// - public bool IsARM64 { - get { return Machine == Machine.ARM64; } - } + public bool IsARM64 => Machine == Machine.ARM64; /// /// Gets/sets the (from .NET header) /// public ComImageFlags Cor20HeaderFlags { - get { return (ComImageFlags)cor20HeaderFlags; } - set { cor20HeaderFlags = (int)value; } + get => (ComImageFlags)cor20HeaderFlags; + set => cor20HeaderFlags = (int)value; } /// protected int cor20HeaderFlags; @@ -895,40 +809,40 @@ void ModifyComImageFlags(bool set, ComImageFlags flags) { /// Gets/sets the bit /// public bool IsILOnly { - get { return ((ComImageFlags)cor20HeaderFlags & ComImageFlags.ILOnly) != 0; } - set { ModifyComImageFlags(value, ComImageFlags.ILOnly); } + get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.ILOnly) != 0; + set => ModifyComImageFlags(value, ComImageFlags.ILOnly); } /// /// Gets/sets the bit /// public bool Is32BitRequired { - get { return ((ComImageFlags)cor20HeaderFlags & ComImageFlags._32BitRequired) != 0; } - set { ModifyComImageFlags(value, ComImageFlags._32BitRequired); } + get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags._32BitRequired) != 0; + set => ModifyComImageFlags(value, ComImageFlags._32BitRequired); } /// /// Gets/sets the bit /// public bool IsStrongNameSigned { - get { return ((ComImageFlags)cor20HeaderFlags & ComImageFlags.StrongNameSigned) != 0; } - set { ModifyComImageFlags(value, ComImageFlags.StrongNameSigned); } + get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.StrongNameSigned) != 0; + set => ModifyComImageFlags(value, ComImageFlags.StrongNameSigned); } /// /// Gets/sets the bit /// public bool HasNativeEntryPoint { - get { return ((ComImageFlags)cor20HeaderFlags & ComImageFlags.NativeEntryPoint) != 0; } - set { ModifyComImageFlags(value, ComImageFlags.NativeEntryPoint); } + get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.NativeEntryPoint) != 0; + set => ModifyComImageFlags(value, ComImageFlags.NativeEntryPoint); } /// /// Gets/sets the bit /// public bool Is32BitPreferred { - get { return ((ComImageFlags)cor20HeaderFlags & ComImageFlags._32BitPreferred) != 0; } - set { ModifyComImageFlags(value, ComImageFlags._32BitPreferred); } + get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags._32BitPreferred) != 0; + set => ModifyComImageFlags(value, ComImageFlags._32BitPreferred); } /// @@ -962,9 +876,7 @@ protected virtual void Dispose(bool disposing) { /// /// Gets all the types (including nested types) present in this module /// - public IEnumerable GetTypes() { - return AllTypesHelper.Types(Types); - } + public IEnumerable GetTypes() => AllTypesHelper.Types(Types); /// /// Adds as a non-nested type. If it's already nested, its @@ -1015,18 +927,14 @@ uint GetNextFreeRid(Table table) { /// /// The type /// The imported type or null if is invalid - public ITypeDefOrRef Import(Type type) { - return new Importer(this).Import(type); - } + public ITypeDefOrRef Import(Type type) => new Importer(this).Import(type); /// /// Imports a as a /// /// The type /// The imported type or null if is invalid - public TypeSig ImportAsTypeSig(Type type) { - return new Importer(this).ImportAsTypeSig(type); - } + public TypeSig ImportAsTypeSig(Type type) => new Importer(this).ImportAsTypeSig(type); /// /// Imports a as a @@ -1034,9 +942,7 @@ public TypeSig ImportAsTypeSig(Type type) { /// The field /// The imported field or null if is invalid /// or if we failed to import the field - public MemberRef Import(FieldInfo fieldInfo) { - return (MemberRef)new Importer(this).Import(fieldInfo); - } + public MemberRef Import(FieldInfo fieldInfo) => (MemberRef)new Importer(this).Import(fieldInfo); /// /// Imports a as a . This will be either @@ -1045,116 +951,90 @@ public MemberRef Import(FieldInfo fieldInfo) { /// The method /// The imported method or null if is invalid /// or if we failed to import the method - public IMethod Import(MethodBase methodBase) { - return new Importer(this).Import(methodBase); - } + public IMethod Import(MethodBase methodBase) => new Importer(this).Import(methodBase); /// /// Imports a /// /// The type /// The imported type or null - public IType Import(IType type) { - return new Importer(this).Import(type); - } + public IType Import(IType type) => new Importer(this).Import(type); /// /// Imports a as a /// /// The type /// The imported type or null - public TypeRef Import(TypeDef type) { - return (TypeRef)new Importer(this).Import(type); - } + public TypeRef Import(TypeDef type) => (TypeRef)new Importer(this).Import(type); /// /// Imports a /// /// The type /// The imported type or null - public TypeRef Import(TypeRef type) { - return (TypeRef)new Importer(this).Import(type); - } + public TypeRef Import(TypeRef type) => (TypeRef)new Importer(this).Import(type); /// /// Imports a /// /// The type /// The imported type or null - public TypeSpec Import(TypeSpec type) { - return new Importer(this).Import(type); - } + public TypeSpec Import(TypeSpec type) => new Importer(this).Import(type); /// /// Imports a /// /// The type /// The imported type or null - public TypeSig Import(TypeSig type) { - return new Importer(this).Import(type); - } + public TypeSig Import(TypeSig type) => new Importer(this).Import(type); /// /// Imports a /// /// The field /// The imported type or null if is invalid - public MemberRef Import(IField field) { - return (MemberRef)new Importer(this).Import(field); - } + public MemberRef Import(IField field) => (MemberRef)new Importer(this).Import(field); /// /// Imports a as a /// /// The field /// The imported type or null if is invalid - public MemberRef Import(FieldDef field) { - return (MemberRef)new Importer(this).Import(field); - } + public MemberRef Import(FieldDef field) => (MemberRef)new Importer(this).Import(field); /// /// Imports a /// /// The method /// The imported method or null if is invalid - public IMethod Import(IMethod method) { - return new Importer(this).Import(method); - } + public IMethod Import(IMethod method) => new Importer(this).Import(method); /// /// Imports a as a /// /// The method /// The imported method or null if is invalid - public MemberRef Import(MethodDef method) { - return (MemberRef)new Importer(this).Import(method); - } + public MemberRef Import(MethodDef method) => (MemberRef)new Importer(this).Import(method); /// /// Imports a /// /// The method /// The imported method or null if is invalid - public MethodSpec Import(MethodSpec method) { - return new Importer(this).Import(method); - } + public MethodSpec Import(MethodSpec method) => new Importer(this).Import(method); /// /// Imports a /// /// The member ref /// The imported member ref or null if is invalid - public MemberRef Import(MemberRef memberRef) { - return new Importer(this).Import(memberRef); - } + public MemberRef Import(MemberRef memberRef) => new Importer(this).Import(memberRef); /// /// Writes the module to a file on disk. If the file exists, it will be overwritten. /// /// Filename - public void Write(string filename) { - Write(filename, null); - } + public void Write(string filename) => Write(filename, null); /// /// Writes the module to a file on disk. If the file exists, it will be overwritten. @@ -1170,9 +1050,7 @@ public void Write(string filename, ModuleWriterOptions options) { /// Writes the module to a stream. /// /// Destination stream - public void Write(Stream dest) { - Write(dest, null); - } + public void Write(Stream dest) => Write(dest, null); /// /// Writes the module to a stream. @@ -1189,9 +1067,7 @@ public void Write(Stream dest, ModuleWriterOptions options) { /// to true. Use this method if the cache is /// enabled but some of the types have been modified (eg. removed, added, renamed). /// - public void ResetTypeDefFindCache() { - TypeDefFinder.ResetCache(); - } + public void ResetTypeDefFindCache() => TypeDefFinder.ResetCache(); /// /// Finds a @@ -1200,18 +1076,13 @@ public void ResetTypeDefFindCache() { /// Name /// Language ID /// The or null if none found - public ResourceData FindWin32ResourceData(ResourceName type, ResourceName name, ResourceName langId) { - var w32Resources = Win32Resources; - return w32Resources == null ? null : w32Resources.Find(type, name, langId); - } + public ResourceData FindWin32ResourceData(ResourceName type, ResourceName name, ResourceName langId) => Win32Resources?.Find(type, name, langId); /// /// Creates a new /// /// PDB file kind - public void CreatePdbState(PdbFileKind pdbFileKind) { - SetPdbState(new PdbState(this, pdbFileKind)); - } + public void CreatePdbState(PdbFileKind pdbFileKind) => SetPdbState(new PdbState(this, pdbFileKind)); /// /// Sets a @@ -1219,7 +1090,7 @@ public void CreatePdbState(PdbFileKind pdbFileKind) { /// New public void SetPdbState(PdbState pdbState) { if (pdbState == null) - throw new ArgumentNullException("pdbState"); + throw new ArgumentNullException(nameof(pdbState)); var orig = Interlocked.CompareExchange(ref this.pdbState, pdbState, null); if (orig != null) throw new InvalidOperationException("PDB file has already been initialized"); @@ -1237,9 +1108,7 @@ uint GetCor20RuntimeVersion() { /// if it can be 32-bit or 64-bit. /// /// Size of a pointer (4 or 8) - public int GetPointerSize() { - return GetPointerSize(4); - } + public int GetPointerSize() => GetPointerSize(4); /// /// Returns the size of a pointer @@ -1247,9 +1116,7 @@ public int GetPointerSize() { /// Default pointer size if it's not known or if it /// can be 32-bit or 64-bit /// Size of a pointer (4 or 8) - public int GetPointerSize(int defaultPointerSize) { - return GetPointerSize(defaultPointerSize, defaultPointerSize); - } + public int GetPointerSize(int defaultPointerSize) => GetPointerSize(defaultPointerSize, defaultPointerSize); /// /// Returns the size of a pointer @@ -1317,9 +1184,7 @@ void IListListener.OnAdd(int index, TypeDef value) { } /// - void IListListener.OnRemove(int index, TypeDef value) { - value.Module2 = null; - } + void IListListener.OnRemove(int index, TypeDef value) => value.Module2 = null; /// void IListListener.OnResize(int index) { @@ -1340,9 +1205,7 @@ void IListListener.OnClear() { /// type names are separated by a + character. If false, nested type names /// are separated by a / character. /// An existing or null if it wasn't found. - public TypeDef Find(string fullName, bool isReflectionName) { - return TypeDefFinder.Find(fullName, isReflectionName); - } + public TypeDef Find(string fullName, bool isReflectionName) => TypeDefFinder.Find(fullName, isReflectionName); /// /// Finds a . Its scope (i.e., module or assembly) is ignored when @@ -1351,9 +1214,7 @@ public TypeDef Find(string fullName, bool isReflectionName) { /// /// The type ref /// An existing or null if it wasn't found. - public TypeDef Find(TypeRef typeRef) { - return TypeDefFinder.Find(typeRef); - } + public TypeDef Find(TypeRef typeRef) => TypeDefFinder.Find(typeRef); /// /// Finds a @@ -1361,12 +1222,10 @@ public TypeDef Find(TypeRef typeRef) { /// The type /// A or null if it wasn't found public TypeDef Find(ITypeDefOrRef typeRef) { - var td = typeRef as TypeDef; - if (td != null) + if (typeRef is TypeDef td) return td.Module == this ? td : null; - var tr = typeRef as TypeRef; - if (tr != null) + if (typeRef is TypeRef tr) return Find(tr); var ts = typeRef as TypeSpec; @@ -1408,23 +1267,17 @@ public static ModuleContext CreateModuleContext(bool addOtherSearchPaths = true) /// properties are read to make sure everything is cached. /// /// Cancellation token or null - public virtual void LoadEverything(ICancellationToken cancellationToken = null) { - ModuleLoader.LoadAll(this, cancellationToken); - } + public virtual void LoadEverything(ICancellationToken cancellationToken = null) => ModuleLoader.LoadAll(this, cancellationToken); /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; /// /// Resolves a token /// /// The metadata token /// A or null if is invalid - public IMDTokenProvider ResolveToken(MDToken mdToken) { - return ResolveToken(mdToken.Raw, new GenericParamContext()); - } + public IMDTokenProvider ResolveToken(MDToken mdToken) => ResolveToken(mdToken.Raw, new GenericParamContext()); /// /// Resolves a token @@ -1432,18 +1285,14 @@ public IMDTokenProvider ResolveToken(MDToken mdToken) { /// The metadata token /// Generic parameter context /// A or null if is invalid - public IMDTokenProvider ResolveToken(MDToken mdToken, GenericParamContext gpContext) { - return ResolveToken(mdToken.Raw, gpContext); - } + public IMDTokenProvider ResolveToken(MDToken mdToken, GenericParamContext gpContext) => ResolveToken(mdToken.Raw, gpContext); /// /// Resolves a token /// /// The metadata token /// A or null if is invalid - public IMDTokenProvider ResolveToken(int token) { - return ResolveToken((uint)token, new GenericParamContext()); - } + public IMDTokenProvider ResolveToken(int token) => ResolveToken((uint)token, new GenericParamContext()); /// /// Resolves a token @@ -1451,18 +1300,14 @@ public IMDTokenProvider ResolveToken(int token) { /// The metadata token /// Generic parameter context /// A or null if is invalid - public IMDTokenProvider ResolveToken(int token, GenericParamContext gpContext) { - return ResolveToken((uint)token, gpContext); - } + public IMDTokenProvider ResolveToken(int token, GenericParamContext gpContext) => ResolveToken((uint)token, gpContext); /// /// Resolves a token /// /// The metadata token /// A or null if is invalid - public IMDTokenProvider ResolveToken(uint token) { - return ResolveToken(token, new GenericParamContext()); - } + public IMDTokenProvider ResolveToken(uint token) => ResolveToken(token, new GenericParamContext()); /// /// Resolves a token @@ -1470,9 +1315,7 @@ public IMDTokenProvider ResolveToken(uint token) { /// The metadata token /// Generic parameter context /// A or null if is invalid - public virtual IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext) { - return null; - } + public virtual IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext) => null; /// /// Gets all s @@ -1502,9 +1345,7 @@ public IEnumerable GetModuleRefs() { /// Gets all s. s with generic parameters /// aren't cached and a new copy is always returned. /// - public IEnumerable GetMemberRefs() { - return GetMemberRefs(new GenericParamContext()); - } + public IEnumerable GetMemberRefs() => GetMemberRefs(new GenericParamContext()); /// /// Gets all s. s with generic parameters @@ -1565,15 +1406,12 @@ protected static bool IsGreaterAssemblyRefVersion(AssemblyRef found, AssemblyRef } ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.TypeDefOrRef.Decode(codedToken, out token)) + if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) return null; return ResolveToken(token) as ITypeDefOrRef; } - TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) { - return null; - } + TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) => null; } /// @@ -1612,19 +1450,19 @@ public ModuleDefUser(UTF8String name, Guid? mvid) /// Module version ID /// Corlib assembly ref or null public ModuleDefUser(UTF8String name, Guid? mvid, AssemblyRef corLibAssemblyRef) { - this.Kind = ModuleKind.Windows; - this.Characteristics = DefaultCharacteristics; - this.DllCharacteristics = DefaultDllCharacteristics; - this.RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; - this.Machine = Machine.I386; - this.cor20HeaderFlags = (int)ComImageFlags.ILOnly; - this.Cor20HeaderRuntimeVersion = 0x00020005; // .NET 2.0 or later should use 2.5 - this.TablesHeaderVersion = 0x0200; // .NET 2.0 or later should use 2.0 - this.types = new LazyList(this); - this.exportedTypes = new LazyList(); - this.resources = new ResourceCollection(); - this.corLibTypes = new CorLibTypes(this, corLibAssemblyRef); - this.types = new LazyList(this); + Kind = ModuleKind.Windows; + Characteristics = DefaultCharacteristics; + DllCharacteristics = DefaultDllCharacteristics; + RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; + Machine = Machine.I386; + cor20HeaderFlags = (int)ComImageFlags.ILOnly; + Cor20HeaderRuntimeVersion = 0x00020005; // .NET 2.0 or later should use 2.5 + TablesHeaderVersion = 0x0200; // .NET 2.0 or later should use 2.0 + types = new LazyList(this); + exportedTypes = new LazyList(); + resources = new ResourceCollection(); + corLibTypes = new CorLibTypes(this, corLibAssemblyRef); + types = new LazyList(this); this.name = name; this.mvid = mvid; types.Add(CreateModuleType()); @@ -1648,9 +1486,7 @@ public class ModuleDefMD2 : ModuleDef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -1667,14 +1503,10 @@ protected override void InitializeCustomDebugInfos() { } /// - protected override RVA GetNativeEntryPoint_NoLock() { - return readerModule.GetNativeEntryPoint(); - } + protected override RVA GetNativeEntryPoint_NoLock() => readerModule.GetNativeEntryPoint(); /// - protected override IManagedEntryPoint GetManagedEntryPoint_NoLock() { - return readerModule.GetManagedEntryPoint(); - } + protected override IManagedEntryPoint GetManagedEntryPoint_NoLock() => readerModule.GetManagedEntryPoint(); /// /// Constructor @@ -1690,22 +1522,22 @@ internal ModuleDefMD2(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (rid != 1 && readerModule.TablesStream.ModuleTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Module rid {0} does not exist", rid)); + throw new BadImageFormatException($"Module rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; if (rid != 1) { - this.Kind = ModuleKind.Windows; - this.Characteristics = DefaultCharacteristics; - this.DllCharacteristics = DefaultDllCharacteristics; - this.RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; - this.Machine = Machine.I386; - this.cor20HeaderFlags = (int)ComImageFlags.ILOnly; - this.Cor20HeaderRuntimeVersion = 0x00020005; // .NET 2.0 or later should use 2.5 - this.TablesHeaderVersion = 0x0200; // .NET 2.0 or later should use 2.0 - this.corLibTypes = new CorLibTypes(this); - this.location = string.Empty; + Kind = ModuleKind.Windows; + Characteristics = DefaultCharacteristics; + DllCharacteristics = DefaultDllCharacteristics; + RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; + Machine = Machine.I386; + cor20HeaderFlags = (int)ComImageFlags.ILOnly; + Cor20HeaderRuntimeVersion = 0x00020005; // .NET 2.0 or later should use 2.5 + TablesHeaderVersion = 0x0200; // .NET 2.0 or later should use 2.0 + corLibTypes = new CorLibTypes(this); + location = string.Empty; InitializeFromRawRow(); } } @@ -1714,8 +1546,7 @@ internal ModuleDefMD2(ModuleDefMD readerModule, uint rid) { /// Initialize fields from the raw Module row /// protected void InitializeFromRawRow() { - uint name, mvid, encId; - uint encBaseId = readerModule.TablesStream.ReadModuleRow(origRid, out generation, out name, out mvid, out encId); + uint encBaseId = readerModule.TablesStream.ReadModuleRow(origRid, out generation, out uint name, out uint mvid, out uint encId); this.mvid = readerModule.GuidStream.Read(mvid); this.encId = readerModule.GuidStream.Read(encId); this.encBaseId = readerModule.GuidStream.Read(encBaseId); diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 38ee4226e..aa439ee18 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -60,59 +60,47 @@ public sealed class ModuleDefMD : ModuleDefMD2, IInstructionOperandResolver { /// Gets/sets the method decrypter /// public IMethodDecrypter MethodDecrypter { - get { return methodDecrypter; } - set { methodDecrypter = value; } + get => methodDecrypter; + set => methodDecrypter = value; } /// /// Gets/sets the string decrypter /// public IStringDecrypter StringDecrypter { - get { return stringDecrypter; } - set { stringDecrypter = value; } + get => stringDecrypter; + set => stringDecrypter = value; } /// /// Returns the .NET metadata interface /// - public IMetaData MetaData { - get { return metaData; } - } + public IMetaData MetaData => metaData; /// /// Returns the #~ or #- tables stream /// - public TablesStream TablesStream { - get { return metaData.TablesStream; } - } + public TablesStream TablesStream => metaData.TablesStream; /// /// Returns the #Strings stream /// - public StringsStream StringsStream { - get { return metaData.StringsStream; } - } + public StringsStream StringsStream => metaData.StringsStream; /// /// Returns the #Blob stream /// - public BlobStream BlobStream { - get { return metaData.BlobStream; } - } + public BlobStream BlobStream => metaData.BlobStream; /// /// Returns the #GUID stream /// - public GuidStream GuidStream { - get { return metaData.GuidStream; } - } + public GuidStream GuidStream => metaData.GuidStream; /// /// Returns the #US stream /// - public USStream USStream { - get { return metaData.USStream; } - } + public USStream USStream => metaData.USStream; /// protected override void InitializeTypes() { @@ -136,9 +124,7 @@ protected override void InitializeResources() { } /// - protected override Win32Resources GetWin32Resources_NoLock() { - return metaData.PEImage.Win32Resources; - } + protected override Win32Resources GetWin32Resources_NoLock() => metaData.PEImage.Win32Resources; /// protected override VTableFixups GetVTableFixups_NoLock() { @@ -154,9 +140,7 @@ protected override VTableFixups GetVTableFixups_NoLock() { /// File name of an existing .NET module/assembly /// Module context or null /// A new instance - public static ModuleDefMD Load(string fileName, ModuleContext context) { - return Load(fileName, new ModuleCreationOptions(context)); - } + public static ModuleDefMD Load(string fileName, ModuleContext context) => Load(fileName, new ModuleCreationOptions(context)); /// /// Creates a instance from a file @@ -164,9 +148,7 @@ public static ModuleDefMD Load(string fileName, ModuleContext context) { /// File name of an existing .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) { - return Load(MetaDataCreator.Load(fileName), options); - } + public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) => Load(MetaDataCreator.Load(fileName), options); /// /// Creates a instance from a byte[] @@ -174,9 +156,7 @@ public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = /// Contents of a .NET module/assembly /// Module context or null /// A new instance - public static ModuleDefMD Load(byte[] data, ModuleContext context) { - return Load(data, new ModuleCreationOptions(context)); - } + public static ModuleDefMD Load(byte[] data, ModuleContext context) => Load(data, new ModuleCreationOptions(context)); /// /// Creates a instance from a byte[] @@ -184,18 +164,14 @@ public static ModuleDefMD Load(byte[] data, ModuleContext context) { /// Contents of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) { - return Load(MetaDataCreator.Load(data), options); - } + public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) => Load(MetaDataCreator.Load(data), options); /// /// Creates a instance from a reflection module /// /// An existing reflection module /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod) { - return Load(mod, (ModuleCreationOptions)null, GetImageLayout(mod)); - } + public static ModuleDefMD Load(System.Reflection.Module mod) => Load(mod, (ModuleCreationOptions)null, GetImageLayout(mod)); /// /// Creates a instance from a reflection module @@ -203,9 +179,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod) { /// An existing reflection module /// Module context or null /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext context) { - return Load(mod, new ModuleCreationOptions(context), GetImageLayout(mod)); - } + public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext context) => Load(mod, new ModuleCreationOptions(context), GetImageLayout(mod)); /// /// Creates a instance from a reflection module @@ -213,9 +187,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext conte /// An existing reflection module /// Module creation options or null /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptions options) { - return Load(mod, options, GetImageLayout(mod)); - } + public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptions options) => Load(mod, options, GetImageLayout(mod)); static ImageLayout GetImageLayout(System.Reflection.Module mod) { var fqn = mod.FullyQualifiedName; @@ -231,9 +203,7 @@ static ImageLayout GetImageLayout(System.Reflection.Module mod) { /// Module context or null /// Image layout of the module in memory /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext context, ImageLayout imageLayout) { - return Load(mod, new ModuleCreationOptions(context), imageLayout); - } + public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext context, ImageLayout imageLayout) => Load(mod, new ModuleCreationOptions(context), imageLayout); static IntPtr GetModuleHandle(System.Reflection.Module mod) { #if NETSTANDARD2_0 @@ -259,9 +229,9 @@ static IntPtr GetModuleHandle(System.Reflection.Module mod) { /// Image layout of the module in memory /// A new instance public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptions options, ImageLayout imageLayout) { - IntPtr addr = GetModuleHandle(mod); + var addr = GetModuleHandle(mod); if (addr == new IntPtr(-1)) - throw new InvalidOperationException(string.Format("Module {0} has no HINSTANCE", mod)); + throw new InvalidOperationException($"Module {mod} has no HINSTANCE"); return Load(addr, options, imageLayout); } @@ -270,9 +240,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// /// Address of a .NET module/assembly /// A new instance - public static ModuleDefMD Load(IntPtr addr) { - return Load(MetaDataCreator.Load(addr), (ModuleCreationOptions)null); - } + public static ModuleDefMD Load(IntPtr addr) => Load(MetaDataCreator.Load(addr), (ModuleCreationOptions)null); /// /// Creates a instance from a memory location @@ -280,9 +248,7 @@ public static ModuleDefMD Load(IntPtr addr) { /// Address of a .NET module/assembly /// Module context or null /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleContext context) { - return Load(MetaDataCreator.Load(addr), new ModuleCreationOptions(context)); - } + public static ModuleDefMD Load(IntPtr addr, ModuleContext context) => Load(MetaDataCreator.Load(addr), new ModuleCreationOptions(context)); /// /// Creates a instance from a memory location @@ -290,18 +256,14 @@ public static ModuleDefMD Load(IntPtr addr, ModuleContext context) { /// Address of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options) { - return Load(MetaDataCreator.Load(addr), options); - } + public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options) => Load(MetaDataCreator.Load(addr), options); /// /// Creates a instance /// /// PE image /// A new instance - public static ModuleDefMD Load(IPEImage peImage) { - return Load(MetaDataCreator.Load(peImage), (ModuleCreationOptions)null); - } + public static ModuleDefMD Load(IPEImage peImage) => Load(MetaDataCreator.Load(peImage), (ModuleCreationOptions)null); /// /// Creates a instance @@ -309,9 +271,7 @@ public static ModuleDefMD Load(IPEImage peImage) { /// PE image /// Module context or null /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) { - return Load(MetaDataCreator.Load(peImage), new ModuleCreationOptions(context)); - } + public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) => Load(MetaDataCreator.Load(peImage), new ModuleCreationOptions(context)); /// /// Creates a instance @@ -319,9 +279,7 @@ public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) { /// PE image /// Module creation options or null /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) { - return Load(MetaDataCreator.Load(peImage), options); - } + public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) => Load(MetaDataCreator.Load(peImage), options); /// /// Creates a instance from a memory location @@ -330,9 +288,7 @@ public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) /// Module context or null /// Image layout of the file in memory /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout imageLayout) { - return Load(MetaDataCreator.Load(addr, imageLayout), new ModuleCreationOptions(context)); - } + public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout imageLayout) => Load(MetaDataCreator.Load(addr, imageLayout), new ModuleCreationOptions(context)); /// /// Creates a instance from a memory location @@ -341,9 +297,7 @@ public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout i /// Module creation options or null /// Image layout of the file in memory /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, ImageLayout imageLayout) { - return Load(MetaDataCreator.Load(addr, imageLayout), options); - } + public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, ImageLayout imageLayout) => Load(MetaDataCreator.Load(addr, imageLayout), options); /// /// Creates a instance from a stream @@ -353,9 +307,7 @@ public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, Image /// The stream (owned by caller) /// A new instance /// If is null - public static ModuleDefMD Load(Stream stream) { - return Load(stream, (ModuleCreationOptions)null); - } + public static ModuleDefMD Load(Stream stream) => Load(stream, (ModuleCreationOptions)null); /// /// Creates a instance from a stream @@ -366,9 +318,7 @@ public static ModuleDefMD Load(Stream stream) { /// Module context or null /// A new instance /// If is null - public static ModuleDefMD Load(Stream stream, ModuleContext context) { - return Load(stream, new ModuleCreationOptions(context)); - } + public static ModuleDefMD Load(Stream stream, ModuleContext context) => Load(stream, new ModuleCreationOptions(context)); /// /// Creates a instance from a stream @@ -381,7 +331,7 @@ public static ModuleDefMD Load(Stream stream, ModuleContext context) { /// If is null public static ModuleDefMD Load(Stream stream, ModuleCreationOptions options) { if (stream == null) - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); if (stream.Length > int.MaxValue) throw new ArgumentException("Stream is too big"); var data = new byte[(int)stream.Length]; @@ -397,9 +347,7 @@ public static ModuleDefMD Load(Stream stream, ModuleCreationOptions options) { /// The metadata /// Module creation options or null /// A new instance that now owns - internal static ModuleDefMD Load(MetaData metaData, ModuleCreationOptions options) { - return new ModuleDefMD(metaData, options); - } + internal static ModuleDefMD Load(MetaData metaData, ModuleCreationOptions options) => new ModuleDefMD(metaData, options); /// /// Constructor @@ -416,19 +364,19 @@ internal static ModuleDefMD Load(MetaData metaData, ModuleCreationOptions option if (options == null) options = ModuleCreationOptions.Default; this.metaData = metaData; - this.context = options.Context; + context = options.Context; Initialize(); InitializeFromRawRow(); location = metaData.PEImage.FileName ?? string.Empty; - this.Kind = GetKind(); - this.Characteristics = MetaData.PEImage.ImageNTHeaders.FileHeader.Characteristics; - this.DllCharacteristics = MetaData.PEImage.ImageNTHeaders.OptionalHeader.DllCharacteristics; - this.RuntimeVersion = MetaData.VersionString; - this.Machine = MetaData.PEImage.ImageNTHeaders.FileHeader.Machine; - this.Cor20HeaderFlags = MetaData.ImageCor20Header.Flags; - this.Cor20HeaderRuntimeVersion = (uint)(MetaData.ImageCor20Header.MajorRuntimeVersion << 16) | MetaData.ImageCor20Header.MinorRuntimeVersion; - this.TablesHeaderVersion = MetaData.TablesStream.Version; + Kind = GetKind(); + Characteristics = MetaData.PEImage.ImageNTHeaders.FileHeader.Characteristics; + DllCharacteristics = MetaData.PEImage.ImageNTHeaders.OptionalHeader.DllCharacteristics; + RuntimeVersion = MetaData.VersionString; + Machine = MetaData.PEImage.ImageNTHeaders.FileHeader.Machine; + Cor20HeaderFlags = MetaData.ImageCor20Header.Flags; + Cor20HeaderRuntimeVersion = (uint)(MetaData.ImageCor20Header.MajorRuntimeVersion << 16) | MetaData.ImageCor20Header.MinorRuntimeVersion; + TablesHeaderVersion = MetaData.TablesStream.Version; corLibTypes = new CorLibTypes(this, options.CorLibAssemblyRef ?? FindCorLibAssemblyRef() ?? CreateDefaultCorLibAssemblyRef()); InitializePdb(options); } @@ -454,12 +402,10 @@ SymbolReader CreateSymbolReader(ModuleCreationOptions options) { return symReader; } - var pdbData = options.PdbFileOrData as byte[]; - if (pdbData != null) + if (options.PdbFileOrData is byte[] pdbData) return SymbolReaderCreator.Create(options.PdbImplementation, metaData, pdbData); - var pdbStream = options.PdbFileOrData as IImageStream; - if (pdbStream != null) + if (options.PdbFileOrData is IImageStream pdbStream) return SymbolReaderCreator.Create(options.PdbImplementation, metaData, pdbStream); } @@ -492,59 +438,45 @@ public void LoadPdb(SymbolReader symbolReader) { /// Loads symbols from a PDB file /// /// PDB file name - public void LoadPdb(string pdbFileName) { - LoadPdb(PdbImplType.Default, pdbFileName); - } + public void LoadPdb(string pdbFileName) => LoadPdb(PdbImplType.Default, pdbFileName); /// /// Loads symbols from a PDB file /// /// PDB implementation to use /// PDB file name - public void LoadPdb(PdbImplType pdbImpl, string pdbFileName) { - LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, pdbFileName)); - } + public void LoadPdb(PdbImplType pdbImpl, string pdbFileName) => LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, pdbFileName)); /// /// Loads symbols from a byte array /// /// PDB data - public void LoadPdb(byte[] pdbData) { - LoadPdb(PdbImplType.Default, pdbData); - } + public void LoadPdb(byte[] pdbData) => LoadPdb(PdbImplType.Default, pdbData); /// /// Loads symbols from a byte array /// /// PDB implementation to use /// PDB data - public void LoadPdb(PdbImplType pdbImpl, byte[] pdbData) { - LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, pdbData)); - } + public void LoadPdb(PdbImplType pdbImpl, byte[] pdbData) => LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, pdbData)); /// /// Loads symbols from a stream /// /// PDB file stream which is now owned by us - public void LoadPdb(IImageStream pdbStream) { - LoadPdb(PdbImplType.Default, pdbStream); - } + public void LoadPdb(IImageStream pdbStream) => LoadPdb(PdbImplType.Default, pdbStream); /// /// Loads symbols from a stream /// /// PDB implementation to use /// PDB file stream which is now owned by us - public void LoadPdb(PdbImplType pdbImpl, IImageStream pdbStream) { - LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, pdbStream)); - } + public void LoadPdb(PdbImplType pdbImpl, IImageStream pdbStream) => LoadPdb(SymbolReaderCreator.Create(pdbImpl, metaData, pdbStream)); /// /// Loads symbols if a PDB file is available /// - public void LoadPdb() { - LoadPdb(PdbImplType.Default); - } + public void LoadPdb() => LoadPdb(PdbImplType.Default); /// /// Loads symbols if a PDB file is available @@ -647,8 +579,7 @@ AssemblyRef FindCorLibAssemblyRef() { int currentPriority = int.MinValue; for (uint i = 1; i <= numAsmRefs; i++) { var asmRef = ResolveAssemblyRef(i); - int priority; - if (!preferredCorLibs.TryGetValue(asmRef.FullName, out priority)) + if (!preferredCorLibs.TryGetValue(asmRef.FullName, out int priority)) continue; if (priority > currentPriority) { currentPriority = priority; @@ -697,13 +628,13 @@ AssemblyRef CreateDefaultCorLibAssemblyRef() { if (asmRef != null) return UpdateRowId(asmRef); - if (this.IsClr40) + if (IsClr40) return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR40()); - if (this.IsClr20) + if (IsClr20) return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20()); - if (this.IsClr11) + if (IsClr11) return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR11()); - if (this.IsClr10) + if (IsClr10) return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR10()); return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR40()); } @@ -788,63 +719,49 @@ public override IMDTokenProvider ResolveToken(uint token, GenericParamContext gp /// /// The row ID /// A instance or null if is invalid - public ModuleDef ResolveModule(uint rid) { - return listModuleDefMD[rid - 1]; - } + public ModuleDef ResolveModule(uint rid) => listModuleDefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public TypeRef ResolveTypeRef(uint rid) { - return listTypeRefMD[rid - 1]; - } + public TypeRef ResolveTypeRef(uint rid) => listTypeRefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public TypeDef ResolveTypeDef(uint rid) { - return listTypeDefMD[rid - 1]; - } + public TypeDef ResolveTypeDef(uint rid) => listTypeDefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public FieldDef ResolveField(uint rid) { - return listFieldDefMD[rid - 1]; - } + public FieldDef ResolveField(uint rid) => listFieldDefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public MethodDef ResolveMethod(uint rid) { - return listMethodDefMD[rid - 1]; - } + public MethodDef ResolveMethod(uint rid) => listMethodDefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public ParamDef ResolveParam(uint rid) { - return listParamDefMD[rid - 1]; - } + public ParamDef ResolveParam(uint rid) => listParamDefMD[rid - 1]; /// /// Resolves an /// /// The row ID /// A instance or null if is invalid - public InterfaceImpl ResolveInterfaceImpl(uint rid) { - return listInterfaceImplMD[rid - 1, new GenericParamContext()]; - } + public InterfaceImpl ResolveInterfaceImpl(uint rid) => listInterfaceImplMD[rid - 1, new GenericParamContext()]; /// /// Resolves an @@ -852,18 +769,14 @@ public InterfaceImpl ResolveInterfaceImpl(uint rid) { /// The row ID /// Generic parameter context /// A instance or null if is invalid - public InterfaceImpl ResolveInterfaceImpl(uint rid, GenericParamContext gpContext) { - return listInterfaceImplMD[rid - 1, gpContext]; - } + public InterfaceImpl ResolveInterfaceImpl(uint rid, GenericParamContext gpContext) => listInterfaceImplMD[rid - 1, gpContext]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public MemberRef ResolveMemberRef(uint rid) { - return listMemberRefMD[rid - 1, new GenericParamContext()]; - } + public MemberRef ResolveMemberRef(uint rid) => listMemberRefMD[rid - 1, new GenericParamContext()]; /// /// Resolves a @@ -871,45 +784,35 @@ public MemberRef ResolveMemberRef(uint rid) { /// The row ID /// Generic parameter context /// A instance or null if is invalid - public MemberRef ResolveMemberRef(uint rid, GenericParamContext gpContext) { - return listMemberRefMD[rid - 1, gpContext]; - } + public MemberRef ResolveMemberRef(uint rid, GenericParamContext gpContext) => listMemberRefMD[rid - 1, gpContext]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public Constant ResolveConstant(uint rid) { - return listConstantMD[rid - 1]; - } + public Constant ResolveConstant(uint rid) => listConstantMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public DeclSecurity ResolveDeclSecurity(uint rid) { - return listDeclSecurityMD[rid - 1]; - } + public DeclSecurity ResolveDeclSecurity(uint rid) => listDeclSecurityMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public ClassLayout ResolveClassLayout(uint rid) { - return listClassLayoutMD[rid - 1]; - } + public ClassLayout ResolveClassLayout(uint rid) => listClassLayoutMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public StandAloneSig ResolveStandAloneSig(uint rid) { - return listStandAloneSigMD[rid - 1, new GenericParamContext()]; - } + public StandAloneSig ResolveStandAloneSig(uint rid) => listStandAloneSigMD[rid - 1, new GenericParamContext()]; /// /// Resolves a @@ -917,45 +820,35 @@ public StandAloneSig ResolveStandAloneSig(uint rid) { /// The row ID /// Generic parameter context /// A instance or null if is invalid - public StandAloneSig ResolveStandAloneSig(uint rid, GenericParamContext gpContext) { - return listStandAloneSigMD[rid - 1, gpContext]; - } + public StandAloneSig ResolveStandAloneSig(uint rid, GenericParamContext gpContext) => listStandAloneSigMD[rid - 1, gpContext]; /// /// Resolves an /// /// The row ID /// A instance or null if is invalid - public EventDef ResolveEvent(uint rid) { - return listEventDefMD[rid - 1]; - } + public EventDef ResolveEvent(uint rid) => listEventDefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public PropertyDef ResolveProperty(uint rid) { - return listPropertyDefMD[rid - 1]; - } + public PropertyDef ResolveProperty(uint rid) => listPropertyDefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public ModuleRef ResolveModuleRef(uint rid) { - return listModuleRefMD[rid - 1]; - } + public ModuleRef ResolveModuleRef(uint rid) => listModuleRefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public TypeSpec ResolveTypeSpec(uint rid) { - return listTypeSpecMD[rid - 1, new GenericParamContext()]; - } + public TypeSpec ResolveTypeSpec(uint rid) => listTypeSpecMD[rid - 1, new GenericParamContext()]; /// /// Resolves a @@ -963,81 +856,63 @@ public TypeSpec ResolveTypeSpec(uint rid) { /// The row ID /// Generic parameter context /// A instance or null if is invalid - public TypeSpec ResolveTypeSpec(uint rid, GenericParamContext gpContext) { - return listTypeSpecMD[rid - 1, gpContext]; - } + public TypeSpec ResolveTypeSpec(uint rid, GenericParamContext gpContext) => listTypeSpecMD[rid - 1, gpContext]; /// /// Resolves an /// /// The row ID /// A instance or null if is invalid - public ImplMap ResolveImplMap(uint rid) { - return listImplMapMD[rid - 1]; - } + public ImplMap ResolveImplMap(uint rid) => listImplMapMD[rid - 1]; /// /// Resolves an /// /// The row ID /// A instance or null if is invalid - public AssemblyDef ResolveAssembly(uint rid) { - return listAssemblyDefMD[rid - 1]; - } + public AssemblyDef ResolveAssembly(uint rid) => listAssemblyDefMD[rid - 1]; /// /// Resolves an /// /// The row ID /// A instance or null if is invalid - public AssemblyRef ResolveAssemblyRef(uint rid) { - return listAssemblyRefMD[rid - 1]; - } + public AssemblyRef ResolveAssemblyRef(uint rid) => listAssemblyRefMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public FileDef ResolveFile(uint rid) { - return listFileDefMD[rid - 1]; - } + public FileDef ResolveFile(uint rid) => listFileDefMD[rid - 1]; /// /// Resolves an /// /// The row ID /// A instance or null if is invalid - public ExportedType ResolveExportedType(uint rid) { - return listExportedTypeMD[rid - 1]; - } + public ExportedType ResolveExportedType(uint rid) => listExportedTypeMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public ManifestResource ResolveManifestResource(uint rid) { - return listManifestResourceMD[rid - 1]; - } + public ManifestResource ResolveManifestResource(uint rid) => listManifestResourceMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public GenericParam ResolveGenericParam(uint rid) { - return listGenericParamMD[rid - 1]; - } + public GenericParam ResolveGenericParam(uint rid) => listGenericParamMD[rid - 1]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public MethodSpec ResolveMethodSpec(uint rid) { - return listMethodSpecMD[rid - 1, new GenericParamContext()]; - } + public MethodSpec ResolveMethodSpec(uint rid) => listMethodSpecMD[rid - 1, new GenericParamContext()]; /// /// Resolves a @@ -1045,18 +920,14 @@ public MethodSpec ResolveMethodSpec(uint rid) { /// The row ID /// Generic parameter context /// A instance or null if is invalid - public MethodSpec ResolveMethodSpec(uint rid, GenericParamContext gpContext) { - return listMethodSpecMD[rid - 1, gpContext]; - } + public MethodSpec ResolveMethodSpec(uint rid, GenericParamContext gpContext) => listMethodSpecMD[rid - 1, gpContext]; /// /// Resolves a /// /// The row ID /// A instance or null if is invalid - public GenericParamConstraint ResolveGenericParamConstraint(uint rid) { - return listGenericParamConstraintMD[rid - 1, new GenericParamContext()]; - } + public GenericParamConstraint ResolveGenericParamConstraint(uint rid) => listGenericParamConstraintMD[rid - 1, new GenericParamContext()]; /// /// Resolves a @@ -1064,18 +935,14 @@ public GenericParamConstraint ResolveGenericParamConstraint(uint rid) { /// The row ID /// Generic parameter context /// A instance or null if is invalid - public GenericParamConstraint ResolveGenericParamConstraint(uint rid, GenericParamContext gpContext) { - return listGenericParamConstraintMD[rid - 1, gpContext]; - } + public GenericParamConstraint ResolveGenericParamConstraint(uint rid, GenericParamContext gpContext) => listGenericParamConstraintMD[rid - 1, gpContext]; /// /// Resolves a /// /// A TypeDefOrRef coded token /// A or null if is invalid - public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken) { - return ResolveTypeDefOrRef(codedToken, new GenericParamContext()); - } + public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken) => ResolveTypeDefOrRef(codedToken, new GenericParamContext()); /// /// Resolves a @@ -1084,8 +951,7 @@ public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken) { /// Generic parameter context /// A or null if is invalid public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.TypeDefOrRef.Decode(codedToken, out token)) + if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1102,8 +968,7 @@ public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken, GenericParamContext gp /// A HasConstant coded token /// A or null if is invalid public IHasConstant ResolveHasConstant(uint codedToken) { - uint token; - if (!CodedToken.HasConstant.Decode(codedToken, out token)) + if (!CodedToken.HasConstant.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1119,9 +984,7 @@ public IHasConstant ResolveHasConstant(uint codedToken) { /// /// A HasCustomAttribute coded token /// A or null if is invalid - public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken) { - return ResolveHasCustomAttribute(codedToken, new GenericParamContext()); - } + public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken) => ResolveHasCustomAttribute(codedToken, new GenericParamContext()); /// /// Resolves a @@ -1130,8 +993,7 @@ public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken) { /// Generic parameter context /// A or null if is invalid public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.HasCustomAttribute.Decode(codedToken, out token)) + if (!CodedToken.HasCustomAttribute.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1167,8 +1029,7 @@ public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken, GenericPar /// A HasFieldMarshal coded token /// A or null if is invalid public IHasFieldMarshal ResolveHasFieldMarshal(uint codedToken) { - uint token; - if (!CodedToken.HasFieldMarshal.Decode(codedToken, out token)) + if (!CodedToken.HasFieldMarshal.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1184,8 +1045,7 @@ public IHasFieldMarshal ResolveHasFieldMarshal(uint codedToken) { /// A HasDeclSecurity coded token /// A or null if is invalid public IHasDeclSecurity ResolveHasDeclSecurity(uint codedToken) { - uint token; - if (!CodedToken.HasDeclSecurity.Decode(codedToken, out token)) + if (!CodedToken.HasDeclSecurity.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1201,9 +1061,7 @@ public IHasDeclSecurity ResolveHasDeclSecurity(uint codedToken) { /// /// A MemberRefParent coded token /// A or null if is invalid - public IMemberRefParent ResolveMemberRefParent(uint codedToken) { - return ResolveMemberRefParent(codedToken, new GenericParamContext()); - } + public IMemberRefParent ResolveMemberRefParent(uint codedToken) => ResolveMemberRefParent(codedToken, new GenericParamContext()); /// /// Resolves a @@ -1212,8 +1070,7 @@ public IMemberRefParent ResolveMemberRefParent(uint codedToken) { /// Generic parameter context /// A or null if is invalid public IMemberRefParent ResolveMemberRefParent(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.MemberRefParent.Decode(codedToken, out token)) + if (!CodedToken.MemberRefParent.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1232,8 +1089,7 @@ public IMemberRefParent ResolveMemberRefParent(uint codedToken, GenericParamCont /// A HasSemantic coded token /// A or null if is invalid public IHasSemantic ResolveHasSemantic(uint codedToken) { - uint token; - if (!CodedToken.HasSemantic.Decode(codedToken, out token)) + if (!CodedToken.HasSemantic.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1248,9 +1104,7 @@ public IHasSemantic ResolveHasSemantic(uint codedToken) { /// /// A MethodDefOrRef coded token /// A or null if is invalid - public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken) { - return ResolveMethodDefOrRef(codedToken, new GenericParamContext()); - } + public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken) => ResolveMethodDefOrRef(codedToken, new GenericParamContext()); /// /// Resolves a @@ -1259,8 +1113,7 @@ public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken) { /// Generic parameter context /// A or null if is invalid public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.MethodDefOrRef.Decode(codedToken, out token)) + if (!CodedToken.MethodDefOrRef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1276,8 +1129,7 @@ public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken, GenericParamContex /// A MemberForwarded coded token /// A or null if is invalid public IMemberForwarded ResolveMemberForwarded(uint codedToken) { - uint token; - if (!CodedToken.MemberForwarded.Decode(codedToken, out token)) + if (!CodedToken.MemberForwarded.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1293,8 +1145,7 @@ public IMemberForwarded ResolveMemberForwarded(uint codedToken) { /// An Implementation coded token /// A or null if is invalid public IImplementation ResolveImplementation(uint codedToken) { - uint token; - if (!CodedToken.Implementation.Decode(codedToken, out token)) + if (!CodedToken.Implementation.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1310,9 +1161,7 @@ public IImplementation ResolveImplementation(uint codedToken) { /// /// A CustomAttributeType coded token /// A or null if is invalid - public ICustomAttributeType ResolveCustomAttributeType(uint codedToken) { - return ResolveCustomAttributeType(codedToken, new GenericParamContext()); - } + public ICustomAttributeType ResolveCustomAttributeType(uint codedToken) => ResolveCustomAttributeType(codedToken, new GenericParamContext()); /// /// Resolves a @@ -1321,8 +1170,7 @@ public ICustomAttributeType ResolveCustomAttributeType(uint codedToken) { /// Generic parameter context /// A or null if is invalid public ICustomAttributeType ResolveCustomAttributeType(uint codedToken, GenericParamContext gpContext) { - uint token; - if (!CodedToken.CustomAttributeType.Decode(codedToken, out token)) + if (!CodedToken.CustomAttributeType.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1338,8 +1186,7 @@ public ICustomAttributeType ResolveCustomAttributeType(uint codedToken, GenericP /// A ResolutionScope coded token /// A or null if is invalid public IResolutionScope ResolveResolutionScope(uint codedToken) { - uint token; - if (!CodedToken.ResolutionScope.Decode(codedToken, out token)) + if (!CodedToken.ResolutionScope.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1357,8 +1204,7 @@ public IResolutionScope ResolveResolutionScope(uint codedToken) { /// A TypeOrMethodDef> coded token /// A or null if is invalid public ITypeOrMethodDef ResolveTypeOrMethodDef(uint codedToken) { - uint token; - if (!CodedToken.TypeOrMethodDef.Decode(codedToken, out token)) + if (!CodedToken.TypeOrMethodDef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { @@ -1374,9 +1220,7 @@ public ITypeOrMethodDef ResolveTypeOrMethodDef(uint codedToken) { /// #Blob stream offset of signature /// A new instance or null if /// is invalid. - public CallingConventionSig ReadSignature(uint sig) { - return SignatureReader.ReadSig(this, sig, new GenericParamContext()); - } + public CallingConventionSig ReadSignature(uint sig) => SignatureReader.ReadSig(this, sig, new GenericParamContext()); /// /// Reads a signature from the #Blob stream @@ -1385,9 +1229,7 @@ public CallingConventionSig ReadSignature(uint sig) { /// Generic parameter context /// A new instance or null if /// is invalid. - public CallingConventionSig ReadSignature(uint sig, GenericParamContext gpContext) { - return SignatureReader.ReadSig(this, sig, gpContext); - } + public CallingConventionSig ReadSignature(uint sig, GenericParamContext gpContext) => SignatureReader.ReadSig(this, sig, gpContext); /// /// Reads a type signature from the #Blob stream @@ -1395,9 +1237,7 @@ public CallingConventionSig ReadSignature(uint sig, GenericParamContext gpContex /// #Blob stream offset of signature /// A new instance or null if /// is invalid. - public TypeSig ReadTypeSignature(uint sig) { - return SignatureReader.ReadTypeSig(this, sig, new GenericParamContext()); - } + public TypeSig ReadTypeSignature(uint sig) => SignatureReader.ReadTypeSig(this, sig, new GenericParamContext()); /// /// Reads a type signature from the #Blob stream @@ -1406,9 +1246,7 @@ public TypeSig ReadTypeSignature(uint sig) { /// Generic parameter context /// A new instance or null if /// is invalid. - public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext) { - return SignatureReader.ReadTypeSig(this, sig, gpContext); - } + public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext) => SignatureReader.ReadTypeSig(this, sig, gpContext); /// /// Reads a type signature from the #Blob stream @@ -1418,9 +1256,7 @@ public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext) { /// here, else this will be null /// A new instance or null if /// is invalid. - public TypeSig ReadTypeSignature(uint sig, out byte[] extraData) { - return SignatureReader.ReadTypeSig(this, sig, new GenericParamContext(), out extraData); - } + public TypeSig ReadTypeSignature(uint sig, out byte[] extraData) => SignatureReader.ReadTypeSig(this, sig, new GenericParamContext(), out extraData); /// /// Reads a type signature from the #Blob stream @@ -1431,9 +1267,7 @@ public TypeSig ReadTypeSignature(uint sig, out byte[] extraData) { /// Generic parameter context /// A new instance or null if /// is invalid. - public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext, out byte[] extraData) { - return SignatureReader.ReadTypeSig(this, sig, gpContext, out extraData); - } + public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext, out byte[] extraData) => SignatureReader.ReadTypeSig(this, sig, gpContext, out extraData); /// /// Reads a from the blob @@ -1457,9 +1291,7 @@ internal MarshalType ReadMarshalType(Table table, uint rid, GenericParamContext /// RVA /// A new instance. It's empty if RVA is invalid (eg. 0 or /// it doesn't point to a CIL method body) - public CilBody ReadCilBody(IList parameters, RVA rva) { - return ReadCilBody(parameters, rva, new GenericParamContext()); - } + public CilBody ReadCilBody(IList parameters, RVA rva) => ReadCilBody(parameters, rva, new GenericParamContext()); /// /// Reads a CIL method body @@ -1489,63 +1321,49 @@ public CilBody ReadCilBody(IList parameters, RVA rva, GenericParamCon /// /// The field /// The owner type or null if none - internal TypeDef GetOwnerType(FieldDefMD field) { - return ResolveTypeDef(MetaData.GetOwnerTypeOfField(field.OrigRid)); - } + internal TypeDef GetOwnerType(FieldDefMD field) => ResolveTypeDef(MetaData.GetOwnerTypeOfField(field.OrigRid)); /// /// Returns the owner type of a method /// /// The method /// The owner type or null if none - internal TypeDef GetOwnerType(MethodDefMD method) { - return ResolveTypeDef(MetaData.GetOwnerTypeOfMethod(method.OrigRid)); - } + internal TypeDef GetOwnerType(MethodDefMD method) => ResolveTypeDef(MetaData.GetOwnerTypeOfMethod(method.OrigRid)); /// /// Returns the owner type of an event /// /// The event /// The owner type or null if none - internal TypeDef GetOwnerType(EventDefMD evt) { - return ResolveTypeDef(MetaData.GetOwnerTypeOfEvent(evt.OrigRid)); - } + internal TypeDef GetOwnerType(EventDefMD evt) => ResolveTypeDef(MetaData.GetOwnerTypeOfEvent(evt.OrigRid)); /// /// Returns the owner type of a property /// /// The property /// The owner type or null if none - internal TypeDef GetOwnerType(PropertyDefMD property) { - return ResolveTypeDef(MetaData.GetOwnerTypeOfProperty(property.OrigRid)); - } + internal TypeDef GetOwnerType(PropertyDefMD property) => ResolveTypeDef(MetaData.GetOwnerTypeOfProperty(property.OrigRid)); /// /// Returns the owner type/method of a generic param /// /// The generic param /// The owner type/method or null if none - internal ITypeOrMethodDef GetOwner(GenericParamMD gp) { - return ResolveTypeOrMethodDef(MetaData.GetOwnerOfGenericParam(gp.OrigRid)); - } + internal ITypeOrMethodDef GetOwner(GenericParamMD gp) => ResolveTypeOrMethodDef(MetaData.GetOwnerOfGenericParam(gp.OrigRid)); /// /// Returns the owner generic param of a generic param constraint /// /// The generic param constraint /// The owner generic param or null if none - internal GenericParam GetOwner(GenericParamConstraintMD gpc) { - return ResolveGenericParam(MetaData.GetOwnerOfGenericParamConstraint(gpc.OrigRid)); - } + internal GenericParam GetOwner(GenericParamConstraintMD gpc) => ResolveGenericParam(MetaData.GetOwnerOfGenericParamConstraint(gpc.OrigRid)); /// /// Returns the owner method of a param /// /// The param /// The owner method or null if none - internal MethodDef GetOwner(ParamDefMD pd) { - return ResolveMethod(MetaData.GetOwnerOfParam(pd.OrigRid)); - } + internal MethodDef GetOwner(ParamDefMD pd) => ResolveMethod(MetaData.GetOwnerOfParam(pd.OrigRid)); /// /// Reads a module @@ -1667,8 +1485,7 @@ Resource CreateResource(uint rid) { if (row == null) return new EmbeddedResource(UTF8String.Empty, MemoryImageStream.CreateEmpty(), 0) { Rid = rid }; - MDToken token; - if (!CodedToken.Implementation.Decode(row.Implementation, out token)) + if (!CodedToken.Implementation.Decode(row.Implementation, out MDToken token)) return new EmbeddedResource(UTF8String.Empty, MemoryImageStream.CreateEmpty(), 0) { Rid = rid }; var mr = ResolveManifestResource(rid); @@ -1678,12 +1495,10 @@ Resource CreateResource(uint rid) { if (token.Rid == 0) return new EmbeddedResource(mr.Name, CreateResourceStream(mr.Offset), mr.Flags) { Rid = rid, Offset = mr.Offset }; - var file = mr.Implementation as FileDef; - if (file != null) + if (mr.Implementation is FileDef file) return new LinkedResource(mr.Name, file, mr.Flags) { Rid = rid, Offset = mr.Offset }; - var asmRef = mr.Implementation as AssemblyRef; - if (asmRef != null) + if (mr.Implementation is AssemblyRef asmRef) return new AssemblyLinkedResource(mr.Name, asmRef, mr.Flags) { Rid = rid, Offset = mr.Offset }; return new EmbeddedResource(mr.Name, MemoryImageStream.CreateEmpty(), mr.Flags) { Rid = rid, Offset = mr.Offset }; @@ -1746,9 +1561,7 @@ IImageStream CreateResourceStream(uint offset) { /// Custom attribute rid /// A new instance or null if /// is invalid - public CustomAttribute ReadCustomAttribute(uint caRid) { - return ReadCustomAttribute(caRid, new GenericParamContext()); - } + public CustomAttribute ReadCustomAttribute(uint caRid) => ReadCustomAttribute(caRid, new GenericParamContext()); /// /// Reads a @@ -1807,63 +1620,49 @@ public IManagedEntryPoint GetManagedEntryPoint() { /// /// Row ID /// A new instance - internal FieldDefMD ReadField(uint rid) { - return new FieldDefMD(this, rid); - } + internal FieldDefMD ReadField(uint rid) => new FieldDefMD(this, rid); /// /// Reads a new instance. This one is not cached. /// /// Row ID /// A new instance - internal MethodDefMD ReadMethod(uint rid) { - return new MethodDefMD(this, rid); - } + internal MethodDefMD ReadMethod(uint rid) => new MethodDefMD(this, rid); /// /// Reads a new instance. This one is not cached. /// /// Row ID /// A new instance - internal EventDefMD ReadEvent(uint rid) { - return new EventDefMD(this, rid); - } + internal EventDefMD ReadEvent(uint rid) => new EventDefMD(this, rid); /// /// Reads a new instance. This one is not cached. /// /// Row ID /// A new instance - internal PropertyDefMD ReadProperty(uint rid) { - return new PropertyDefMD(this, rid); - } + internal PropertyDefMD ReadProperty(uint rid) => new PropertyDefMD(this, rid); /// /// Reads a new instance. This one is not cached. /// /// Row ID /// A new instance - internal ParamDefMD ReadParam(uint rid) { - return new ParamDefMD(this, rid); - } + internal ParamDefMD ReadParam(uint rid) => new ParamDefMD(this, rid); /// /// Reads a new instance. This one is not cached. /// /// Row ID /// A new instance - internal GenericParamMD ReadGenericParam(uint rid) { - return new GenericParamMD(this, rid); - } + internal GenericParamMD ReadGenericParam(uint rid) => new GenericParamMD(this, rid); /// /// Reads a new instance. This one is not cached. /// /// Row ID /// A new instance - internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid) { - return new GenericParamConstraintMD(this, rid, new GenericParamContext()); - } + internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid) => new GenericParamConstraintMD(this, rid, new GenericParamContext()); /// /// Reads a new instance. This one is not cached. @@ -1871,9 +1670,7 @@ internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid) { /// Row ID /// Generic parameter context /// A new instance - internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid, GenericParamContext gpContext) { - return new GenericParamConstraintMD(this, rid, gpContext); - } + internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid, GenericParamContext gpContext) => new GenericParamConstraintMD(this, rid, gpContext); /// /// Reads a method body @@ -1884,11 +1681,9 @@ internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid, GenericPa /// Generic parameter context /// A or null if none internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, GenericParamContext gpContext) { - MethodBody mb; var mDec = methodDecrypter; - if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out mb)) { - var cilBody = mb as CilBody; - if (cilBody != null) + if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out var mb)) { + if (mb is CilBody cilBody) return InitializeBodyFromPdb(method, cilBody); return mb; } @@ -1946,18 +1741,15 @@ internal MethodExportInfo GetExportInfo(uint methodRid) { return methodExportInfoProvider.GetMethodExportInfo(0x06000000 + methodRid); } - void InitializeMethodExportInfoProvider() { + void InitializeMethodExportInfoProvider() => Interlocked.CompareExchange(ref methodExportInfoProvider, new MethodExportInfoProvider(this), null); - } MethodExportInfoProvider methodExportInfoProvider; /// /// Writes the mixed-mode module to a file on disk. If the file exists, it will be overwritten. /// /// Filename - public void NativeWrite(string filename) { - NativeWrite(filename, null); - } + public void NativeWrite(string filename) => NativeWrite(filename, null); /// /// Writes the mixed-mode module to a file on disk. If the file exists, it will be overwritten. @@ -1973,9 +1765,7 @@ public void NativeWrite(string filename, DNW.NativeModuleWriterOptions options) /// Writes the mixed-mode module to a stream. /// /// Destination stream - public void NativeWrite(Stream dest) { - NativeWrite(dest, null); - } + public void NativeWrite(Stream dest) => NativeWrite(dest, null); /// /// Writes the mixed-mode module to a stream. diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index 57595edc5..4584a7932 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -12,7 +12,7 @@ using dnlib.W32Resources; namespace dnlib.DotNet { - struct ModuleLoader { + readonly struct ModuleLoader { readonly ModuleDef module; readonly ICancellationToken cancellationToken; readonly Dictionary seen; @@ -22,13 +22,12 @@ struct ModuleLoader { const int CAPACITY = 0x4000; this.module = module; this.cancellationToken = cancellationToken; - this.seen = new Dictionary(CAPACITY); - this.stack = new Stack(CAPACITY); + seen = new Dictionary(CAPACITY); + stack = new Stack(CAPACITY); } - public static void LoadAll(ModuleDef module, ICancellationToken cancellationToken) { + public static void LoadAll(ModuleDef module, ICancellationToken cancellationToken) => new ModuleLoader(module, cancellationToken).Load(); - } void Add(UTF8String a) { } void Add(Guid? a) { } @@ -90,56 +89,47 @@ void LoadAllTables() { } void LoadObj(object o) { - var ts = o as TypeSig; - if (ts != null) { + if (o is TypeSig ts) { Load(ts); return; } - var mdt = o as IMDTokenProvider; - if (mdt != null) { + if (o is IMDTokenProvider mdt) { Load(mdt); return; } - var ca = o as CustomAttribute; - if (ca != null) { + if (o is CustomAttribute ca) { Load(ca); return; } - var sa = o as SecurityAttribute; - if (sa != null) { + if (o is SecurityAttribute sa) { Load(sa); return; } - var na = o as CANamedArgument; - if (na != null) { + if (o is CANamedArgument na) { Load(na); return; } - var p = o as Parameter; - if (p != null) { + if (o is Parameter p) { Load(p); return; } - var pdbMethod = o as PdbMethod; - if (pdbMethod != null) { + if (o is PdbMethod pdbMethod) { Load(pdbMethod); return; } - var rd = o as ResourceDirectory; - if (rd != null) { + if (o is ResourceDirectory rd) { Load(rd); return; } - var rdata = o as ResourceData; - if (rdata != null) { + if (o is ResourceData rdata) { Load(rdata); return; } @@ -298,7 +288,7 @@ void Load(IMDTokenProvider mdt) { } void Load(ModuleDef obj) { - if (obj == null || obj != this.module) + if (obj == null || obj != module) return; Add(obj.Generation); Add(obj.Name); @@ -658,14 +648,12 @@ void AddCAValue(object obj) { return; } - var list = obj as IList; - if (list != null) { + if (obj is IList list) { Add(list); return; } - var md = obj as IMDTokenProvider; - if (md != null) { + if (obj is IMDTokenProvider md) { Add(md); return; } @@ -702,39 +690,15 @@ void AddToStack(T t) where T : class { stack.Push(t); } - void Add(CustomAttribute obj) { - AddToStack(obj); - } - - void Add(SecurityAttribute obj) { - AddToStack(obj); - } - - void Add(CANamedArgument obj) { - AddToStack(obj); - } - - void Add(Parameter obj) { - AddToStack(obj); - } - - void Add(IMDTokenProvider o) { - AddToStack(o); - } - + void Add(CustomAttribute obj) => AddToStack(obj); + void Add(SecurityAttribute obj) => AddToStack(obj); + void Add(CANamedArgument obj) => AddToStack(obj); + void Add(Parameter obj) => AddToStack(obj); + void Add(IMDTokenProvider o) => AddToStack(o); void Add(PdbMethod pdbMethod) { } - - void Add(TypeSig ts) { - AddToStack(ts); - } - - void Add(ResourceDirectory rd) { - AddToStack(rd); - } - - void Add(ResourceData rd) { - AddToStack(rd); - } + void Add(TypeSig ts) => AddToStack(ts); + void Add(ResourceDirectory rd) => AddToStack(rd); + void Add(ResourceData rd) => AddToStack(rd); void Add(IList list) where T : IMDTokenProvider { if (list == null) @@ -843,26 +807,22 @@ void Add(Win32Resources vtf) { } void Add(CallingConventionSig sig) { - var msig = sig as MethodBaseSig; - if (msig != null) { + if (sig is MethodBaseSig msig) { Add(msig); return; } - var fsig = sig as FieldSig; - if (fsig != null) { + if (sig is FieldSig fsig) { Add(fsig); return; } - var lsig = sig as LocalSig; - if (lsig != null) { + if (sig is LocalSig lsig) { Add(lsig); return; } - var gsig = sig as GenericInstMethodSig; - if (gsig != null) { + if (sig is GenericInstMethodSig gsig) { Add(gsig); return; } @@ -907,14 +867,12 @@ void Add(MarshalType mt) { } void Add(MethodBody mb) { - var cilBody = mb as CilBody; - if (cilBody != null) { + if (mb is CilBody cilBody) { Add(cilBody); return; } - var nb = mb as NativeMethodBody; - if (nb != null) { + if (mb is NativeMethodBody nb) { Add(nb); return; } @@ -941,26 +899,22 @@ void Add(Instruction instr) { if (instr == null) return; - var mdt = instr.Operand as IMDTokenProvider; - if (mdt != null) { + if (instr.Operand is IMDTokenProvider mdt) { Add(mdt); return; } - var p = instr.Operand as Parameter; - if (p != null) { + if (instr.Operand is Parameter p) { Add(p); return; } - var l = instr.Operand as Local; - if (l != null) { + if (instr.Operand is Local l) { Add(l); return; } - var csig = instr.Operand as CallingConventionSig; - if (csig != null) { + if (instr.Operand is CallingConventionSig csig) { Add(csig); return; } diff --git a/src/DotNet/ModuleRef.cs b/src/DotNet/ModuleRef.cs index f59786728..45f601433 100644 --- a/src/DotNet/ModuleRef.cs +++ b/src/DotNet/ModuleRef.cs @@ -28,47 +28,35 @@ public abstract class ModuleRef : IHasCustomAttribute, IMemberRefParent, IHasCus protected ModuleDef module; /// - public MDToken MDToken { - get { return new MDToken(Table.ModuleRef, rid); } - } + public MDToken MDToken => new MDToken(Table.ModuleRef, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 12; } - } + public int HasCustomAttributeTag => 12; /// - public int MemberRefParentTag { - get { return 2; } - } + public int MemberRefParentTag => 2; /// - public int ResolutionScopeTag { - get { return 1; } - } + public int ResolutionScopeTag => 1; /// - public ScopeType ScopeType { - get { return ScopeType.ModuleRef; } - } + public ScopeType ScopeType => ScopeType.ModuleRef; /// - public string ScopeName { - get { return FullName; } - } + public string ScopeName => FullName; /// /// From column ModuleRef.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -86,24 +74,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 12; } - } + public int HasCustomDebugInformationTag => 12; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -118,14 +99,11 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// - public ModuleDef Module { - get { return module; } - } + public ModuleDef Module => module; /// /// Gets the definition module, i.e., the module which it references, or null @@ -138,8 +116,7 @@ public ModuleDef DefinitionModule { var n = name; if (UTF8String.CaseInsensitiveEquals(n, module.Name)) return module; - var asm = DefinitionAssembly; - return asm == null ? null : asm.FindModule(n); + return DefinitionAssembly?.FindModule(n); } } @@ -147,19 +124,13 @@ public ModuleDef DefinitionModule { /// Gets the definition assembly, i.e., the assembly of the module it references, or /// null if the assembly can't be found. /// - public AssemblyDef DefinitionAssembly { - get { return module == null ? null : module.Assembly; } - } + public AssemblyDef DefinitionAssembly => module?.Assembly; /// - public string FullName { - get { return UTF8String.ToSystemStringOrEmpty(name); } - } + public string FullName => UTF8String.ToSystemStringOrEmpty(name); /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -195,9 +166,7 @@ sealed class ModuleRefMD : ModuleRef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -225,12 +194,12 @@ public ModuleRefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ModuleRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("ModuleRef rid {0} does not exist", rid)); + throw new BadImageFormatException($"ModuleRef rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - this.module = readerModule; + module = readerModule; uint name = readerModule.TablesStream.ReadModuleRefRow2(origRid); this.name = readerModule.StringsStream.ReadNoNull(name); } diff --git a/src/DotNet/NullResolver.cs b/src/DotNet/NullResolver.cs index c06cb553a..d95653d63 100644 --- a/src/DotNet/NullResolver.cs +++ b/src/DotNet/NullResolver.cs @@ -14,32 +14,22 @@ public sealed class NullResolver : IAssemblyResolver, IResolver { } /// - public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { - return null; - } + public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) => null; /// - public bool AddToCache(AssemblyDef asm) { - return true; - } + public bool AddToCache(AssemblyDef asm) => true; /// - public bool Remove(AssemblyDef asm) { - return false; - } + public bool Remove(AssemblyDef asm) => false; /// public void Clear() { } /// - public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { - return null; - } + public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) => null; /// - public IMemberForwarded Resolve(MemberRef memberRef) { - return null; - } + public IMemberForwarded Resolve(MemberRef memberRef) => null; } } diff --git a/src/DotNet/ParamDef.cs b/src/DotNet/ParamDef.cs index a5b098322..9b3f4622f 100644 --- a/src/DotNet/ParamDef.cs +++ b/src/DotNet/ParamDef.cs @@ -29,37 +29,29 @@ public abstract class ParamDef : IHasConstant, IHasCustomAttribute, IHasFieldMar #endif /// - public MDToken MDToken { - get { return new MDToken(Table.Param, rid); } - } + public MDToken MDToken => new MDToken(Table.Param, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasConstantTag { - get { return 1; } - } + public int HasConstantTag => 1; /// - public int HasCustomAttributeTag { - get { return 4; } - } + public int HasCustomAttributeTag => 4; /// - public int HasFieldMarshalTag { - get { return 1; } - } + public int HasFieldMarshalTag => 1; /// /// Gets the declaring method /// public MethodDef DeclaringMethod { - get { return declaringMethod; } - internal set { declaringMethod = value; } + get => declaringMethod; + internal set => declaringMethod = value; } /// protected MethodDef declaringMethod; @@ -68,8 +60,8 @@ public MethodDef DeclaringMethod { /// From column Param.Flags /// public ParamAttributes Attributes { - get { return (ParamAttributes)attributes; } - set { attributes = (int)value; } + get => (ParamAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -78,8 +70,8 @@ public ParamAttributes Attributes { /// From column Param.Sequence /// public ushort Sequence { - get { return sequence; } - set { sequence = value; } + get => sequence; + set => sequence = value; } /// protected ushort sequence; @@ -88,8 +80,8 @@ public ushort Sequence { /// From column Param.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -131,14 +123,10 @@ void InitializeMarshalType() { } /// Called to initialize - protected virtual MarshalType GetMarshalType_NoLock() { - return null; - } + protected virtual MarshalType GetMarshalType_NoLock() => null; /// Reset - protected void ResetMarshalType() { - marshalType_isInitialized = false; - } + protected void ResetMarshalType() => marshalType_isInitialized = false; /// public Constant Constant { @@ -177,14 +165,10 @@ void InitializeConstant() { } /// Called to initialize - protected virtual Constant GetConstant_NoLock() { - return null; - } + protected virtual Constant GetConstant_NoLock() => null; /// Reset - protected void ResetConstant() { - constant_isInitialized = false; - } + protected void ResetConstant() => constant_isInitialized = false; /// /// Gets all custom attributes @@ -199,24 +183,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 4; } - } + public int HasCustomDebugInformationTag => 4; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -231,16 +208,13 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// true if is not null /// - public bool HasConstant { - get { return Constant != null; } - } + public bool HasConstant => Constant != null; /// /// Gets the constant element type or if there's no constant @@ -255,16 +229,14 @@ public ElementType ElementType { /// /// true if is not null /// - public bool HasMarshalType { - get { return MarshalType != null; } - } + public bool HasMarshalType => MarshalType != null; /// public string FullName { get { var n = name; if (UTF8String.IsNullOrEmpty(n)) - return string.Format("A_{0}", sequence); + return $"A_{sequence}"; return n.String; } } @@ -297,56 +269,56 @@ void ModifyAttributes(bool set, ParamAttributes flags) { /// Gets/sets the bit /// public bool IsIn { - get { return ((ParamAttributes)attributes & ParamAttributes.In) != 0; } - set { ModifyAttributes(value, ParamAttributes.In); } + get => ((ParamAttributes)attributes & ParamAttributes.In) != 0; + set => ModifyAttributes(value, ParamAttributes.In); } /// /// Gets/sets the bit /// public bool IsOut { - get { return ((ParamAttributes)attributes & ParamAttributes.Out) != 0; } - set { ModifyAttributes(value, ParamAttributes.Out); } + get => ((ParamAttributes)attributes & ParamAttributes.Out) != 0; + set => ModifyAttributes(value, ParamAttributes.Out); } /// /// Gets/sets the bit /// public bool IsLcid { - get { return ((ParamAttributes)attributes & ParamAttributes.Lcid) != 0; } - set { ModifyAttributes(value, ParamAttributes.Lcid); } + get => ((ParamAttributes)attributes & ParamAttributes.Lcid) != 0; + set => ModifyAttributes(value, ParamAttributes.Lcid); } /// /// Gets/sets the bit /// public bool IsRetval { - get { return ((ParamAttributes)attributes & ParamAttributes.Retval) != 0; } - set { ModifyAttributes(value, ParamAttributes.Retval); } + get => ((ParamAttributes)attributes & ParamAttributes.Retval) != 0; + set => ModifyAttributes(value, ParamAttributes.Retval); } /// /// Gets/sets the bit /// public bool IsOptional { - get { return ((ParamAttributes)attributes & ParamAttributes.Optional) != 0; } - set { ModifyAttributes(value, ParamAttributes.Optional); } + get => ((ParamAttributes)attributes & ParamAttributes.Optional) != 0; + set => ModifyAttributes(value, ParamAttributes.Optional); } /// /// Gets/sets the bit /// public bool HasDefault { - get { return ((ParamAttributes)attributes & ParamAttributes.HasDefault) != 0; } - set { ModifyAttributes(value, ParamAttributes.HasDefault); } + get => ((ParamAttributes)attributes & ParamAttributes.HasDefault) != 0; + set => ModifyAttributes(value, ParamAttributes.HasDefault); } /// /// Gets/sets the bit /// public bool HasFieldMarshal { - get { return ((ParamAttributes)attributes & ParamAttributes.HasFieldMarshal) != 0; } - set { ModifyAttributes(value, ParamAttributes.HasFieldMarshal); } + get => ((ParamAttributes)attributes & ParamAttributes.HasFieldMarshal) != 0; + set => ModifyAttributes(value, ParamAttributes.HasFieldMarshal); } } @@ -386,7 +358,7 @@ public ParamDefUser(UTF8String name, ushort sequence) public ParamDefUser(UTF8String name, ushort sequence, ParamAttributes flags) { this.name = name; this.sequence = sequence; - this.attributes = (int)flags; + attributes = (int)flags; } } @@ -400,19 +372,15 @@ sealed class ParamDefMD : ParamDef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// - protected override MarshalType GetMarshalType_NoLock() { - return readerModule.ReadMarshalType(Table.Param, origRid, GenericParamContext.Create(declaringMethod)); - } + protected override MarshalType GetMarshalType_NoLock() => + readerModule.ReadMarshalType(Table.Param, origRid, GenericParamContext.Create(declaringMethod)); /// - protected override Constant GetConstant_NoLock() { - return readerModule.ResolveConstant(readerModule.MetaData.GetConstantRid(Table.Param, origRid)); - } + protected override Constant GetConstant_NoLock() => + readerModule.ResolveConstant(readerModule.MetaData.GetConstantRid(Table.Param, origRid)); /// protected override void InitializeCustomAttributes() { @@ -440,14 +408,14 @@ public ParamDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ParamTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Param rid {0} does not exist", rid)); + throw new BadImageFormatException($"Param rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name = readerModule.TablesStream.ReadParamRow(origRid, out this.attributes, out this.sequence); + uint name = readerModule.TablesStream.ReadParamRow(origRid, out attributes, out sequence); this.name = readerModule.StringsStream.ReadNoNull(name); - this.declaringMethod = readerModule.GetOwner(this); + declaringMethod = readerModule.GetOwner(this); } internal ParamDefMD InitializeAll() { diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index bacc6978c..e72cb8020 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -30,9 +30,7 @@ public sealed class ParameterList : ThreadSafe.IList { /// /// Gets the owner method /// - public MethodDef Method { - get { return method; } - } + public MethodDef Method => method; /// /// Gets the number of parameters, including a possible hidden 'this' parameter @@ -80,7 +78,7 @@ public Parameter this[int index] { return parameters[index]; #endif } - set { throw new NotSupportedException(); } + set => throw new NotSupportedException(); } /// @@ -105,10 +103,10 @@ public Parameter ReturnParameter { /// 's declaring type public ParameterList(MethodDef method, TypeDef declaringType) { this.method = method; - this.parameters = new List(); - this.methodSigIndexBase = -1; - this.hiddenThisParameter = new Parameter(this, 0, Parameter.HIDDEN_THIS_METHOD_SIG_INDEX); - this.returnParameter = new Parameter(this, -1, Parameter.RETURN_TYPE_METHOD_SIG_INDEX); + parameters = new List(); + methodSigIndexBase = -1; + hiddenThisParameter = new Parameter(this, 0, Parameter.HIDDEN_THIS_METHOD_SIG_INDEX); + returnParameter = new Parameter(this, -1, Parameter.RETURN_TYPE_METHOD_SIG_INDEX); UpdateThisParameterType(declaringType); UpdateParameterTypes(); } @@ -267,21 +265,10 @@ public int IndexOf(Parameter item) { #endif } - void IList.Insert(int index, Parameter item) { - throw new NotSupportedException(); - } - - void IList.RemoveAt(int index) { - throw new NotSupportedException(); - } - - void ICollection.Add(Parameter item) { - throw new NotSupportedException(); - } - - void ICollection.Clear() { - throw new NotSupportedException(); - } + void IList.Insert(int index, Parameter item) => throw new NotSupportedException(); + void IList.RemoveAt(int index) => throw new NotSupportedException(); + void ICollection.Add(Parameter item) => throw new NotSupportedException(); + void ICollection.Clear() => throw new NotSupportedException(); bool ICollection.Contains(Parameter item) { #if THREAD_SAFE @@ -303,13 +290,8 @@ void ICollection.CopyTo(Parameter[] array, int arrayIndex) { #endif } - bool ICollection.IsReadOnly { - get { return true; } - } - - bool ICollection.Remove(Parameter item) { - throw new NotSupportedException(); - } + bool ICollection.IsReadOnly => true; + bool ICollection.Remove(Parameter item) => throw new NotSupportedException(); IEnumerator IEnumerable.GetEnumerator() { #if THREAD_SAFE @@ -321,63 +303,22 @@ IEnumerator IEnumerable.GetEnumerator() { #endif } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return ((IEnumerable)this).GetEnumerator(); - } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => ((IEnumerable)this).GetEnumerator(); #if THREAD_SAFE - int ThreadSafe.IList.IndexOf_NoLock(Parameter item) { - return parameters.IndexOf(item); - } - - void ThreadSafe.IList.Insert_NoLock(int index, Parameter item) { - throw new NotSupportedException(); - } - - void ThreadSafe.IList.RemoveAt_NoLock(int index) { - throw new NotSupportedException(); - } - - Parameter ThreadSafe.IList.Get_NoLock(int index) { - return parameters[index]; - } - - void ThreadSafe.IList.Set_NoLock(int index, Parameter value) { - throw new NotSupportedException(); - } - - void ThreadSafe.IList.Add_NoLock(Parameter item) { - throw new NotSupportedException(); - } - - void ThreadSafe.IList.Clear_NoLock() { - throw new NotSupportedException(); - } - - bool ThreadSafe.IList.Contains_NoLock(Parameter item) { - return parameters.Contains(item); - } - - void ThreadSafe.IList.CopyTo_NoLock(Parameter[] array, int arrayIndex) { - parameters.CopyTo(array, arrayIndex); - } - - bool ThreadSafe.IList.Remove_NoLock(Parameter item) { - throw new NotSupportedException(); - } - - IEnumerator ThreadSafe.IList.GetEnumerator_NoLock() { - return parameters.GetEnumerator(); - } - - int ThreadSafe.IList.Count_NoLock { - get { return parameters.Count; } - } - - bool ThreadSafe.IList.IsReadOnly_NoLock { - get { return true; } - } - + int ThreadSafe.IList.IndexOf_NoLock(Parameter item) => parameters.IndexOf(item); + void ThreadSafe.IList.Insert_NoLock(int index, Parameter item) => throw new NotSupportedException(); + void ThreadSafe.IList.RemoveAt_NoLock(int index) => throw new NotSupportedException(); + Parameter ThreadSafe.IList.Get_NoLock(int index) => parameters[index]; + void ThreadSafe.IList.Set_NoLock(int index, Parameter value) => throw new NotSupportedException(); + void ThreadSafe.IList.Add_NoLock(Parameter item) => throw new NotSupportedException(); + void ThreadSafe.IList.Clear_NoLock() => throw new NotSupportedException(); + bool ThreadSafe.IList.Contains_NoLock(Parameter item) => parameters.Contains(item); + void ThreadSafe.IList.CopyTo_NoLock(Parameter[] array, int arrayIndex) => parameters.CopyTo(array, arrayIndex); + bool ThreadSafe.IList.Remove_NoLock(Parameter item) => throw new NotSupportedException(); + IEnumerator ThreadSafe.IList.GetEnumerator_NoLock() => parameters.GetEnumerator(); + int ThreadSafe.IList.Count_NoLock => parameters.Count; + bool ThreadSafe.IList.IsReadOnly_NoLock => true; TRetType ThreadSafe.IList.ExecuteLocked(TArgType arg, ExecuteLockedDelegate handler) { theLock.EnterWriteLock(); try { return handler(this, arg); @@ -410,45 +351,35 @@ public sealed class Parameter : IVariable { /// has index 0 and the remaining parameters in the method signature start from index 1. /// The method return parameter has index -1. /// - public int Index { - get { return paramIndex; } - } + public int Index => paramIndex; /// /// Gets the index of the parameter in the method signature. See also /// and /// - public int MethodSigIndex { - get { return methodSigIndex; } - } + public int MethodSigIndex => methodSigIndex; /// /// true if it's a normal visible method parameter, i.e., it's not the hidden /// 'this' parameter and it's not the method return type parameter. /// - public bool IsNormalMethodParameter { - get { return methodSigIndex >= 0; } - } + public bool IsNormalMethodParameter => methodSigIndex >= 0; /// /// true if it's the hidden 'this' parameter /// - public bool IsHiddenThisParameter { - get { return methodSigIndex == HIDDEN_THIS_METHOD_SIG_INDEX; } - } + public bool IsHiddenThisParameter => methodSigIndex == HIDDEN_THIS_METHOD_SIG_INDEX; /// /// true if it's the method return type parameter /// - public bool IsReturnTypeParameter { - get { return methodSigIndex == RETURN_TYPE_METHOD_SIG_INDEX; } - } + public bool IsReturnTypeParameter => methodSigIndex == RETURN_TYPE_METHOD_SIG_INDEX; /// /// Gets the parameter type /// public TypeSig Type { - get { return typeSig; } + get => typeSig; set { typeSig = value; if (parameterList != null) @@ -472,23 +403,17 @@ internal void SetType(bool noParamsLock, TypeSig type) { /// /// Gets the owner method /// - public MethodDef Method { - get { return parameterList == null ? null : parameterList.Method; } - } + public MethodDef Method => parameterList?.Method; /// /// Gets the or null if not present /// - public ParamDef ParamDef { - get { return parameterList == null ? null : parameterList.FindParamDef(this); } - } + public ParamDef ParamDef => parameterList?.FindParamDef(this); /// /// true if it has a /// - public bool HasParamDef { - get { return ParamDef != null; } - } + public bool HasParamDef => ParamDef != null; /// /// Gets the name from . If is null, @@ -512,7 +437,7 @@ public string Name { /// Parameter index public Parameter(int paramIndex) { this.paramIndex = paramIndex; - this.methodSigIndex = paramIndex; + methodSigIndex = paramIndex; } /// @@ -522,8 +447,8 @@ public Parameter(int paramIndex) { /// Parameter type public Parameter(int paramIndex, TypeSig type) { this.paramIndex = paramIndex; - this.methodSigIndex = paramIndex; - this.typeSig = type; + methodSigIndex = paramIndex; + typeSig = type; } /// @@ -545,7 +470,7 @@ public Parameter(int paramIndex, int methodSigIndex) { public Parameter(int paramIndex, int methodSigIndex, TypeSig type) { this.paramIndex = paramIndex; this.methodSigIndex = methodSigIndex; - this.typeSig = type; + typeSig = type; } internal Parameter(ParameterList parameterList, int paramIndex, int methodSigIndex) { @@ -568,7 +493,7 @@ public override string ToString() { if (string.IsNullOrEmpty(name)) { if (IsReturnTypeParameter) return "RET_PARAM"; - return string.Format("A_{0}", paramIndex); + return $"A_{paramIndex}"; } return name; } diff --git a/src/DotNet/Pdb/Dss/ImageStreamIStream.cs b/src/DotNet/Pdb/Dss/ImageStreamIStream.cs index 8ed512a02..66fa98fb8 100644 --- a/src/DotNet/Pdb/Dss/ImageStreamIStream.cs +++ b/src/DotNet/Pdb/Dss/ImageStreamIStream.cs @@ -38,9 +38,7 @@ public ImageStreamIStream(IImageStream stream) /// Source stream /// Name of original file or null if unknown. public ImageStreamIStream(IImageStream stream, string name) { - if (stream == null) - throw new ArgumentNullException("stream"); - this.stream = stream; + this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); this.name = name ?? string.Empty; } @@ -76,9 +74,7 @@ public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { } /// - public void LockRegion(long libOffset, long cb, int dwLockType) { - Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - } + public void LockRegion(long libOffset, long cb, int dwLockType) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); /// public void Read(byte[] pv, int cb, IntPtr pcbRead) { @@ -122,9 +118,7 @@ public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) { } /// - public void SetSize(long libNewSize) { - Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - } + public void SetSize(long libNewSize) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); enum STATFLAG { DEFAULT = 0, @@ -160,20 +154,15 @@ public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, i } /// - public void UnlockRegion(long libOffset, long cb, int dwLockType) { - Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - } + public void UnlockRegion(long libOffset, long cb, int dwLockType) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); /// - public void Write(byte[] pv, int cb, IntPtr pcbWritten) { - Marshal.ThrowExceptionForHR(STG_E_CANTSAVE); - } + public void Write(byte[] pv, int cb, IntPtr pcbWritten) => Marshal.ThrowExceptionForHR(STG_E_CANTSAVE); /// public void Dispose() { stream.Dispose(); - var id = UserData as IDisposable; - if (id != null) + if (UserData is IDisposable id) id.Dispose(); } } diff --git a/src/DotNet/Pdb/Dss/MDEmitter.cs b/src/DotNet/Pdb/Dss/MDEmitter.cs index 5622ed120..cef102590 100644 --- a/src/DotNet/Pdb/Dss/MDEmitter.cs +++ b/src/DotNet/Pdb/Dss/MDEmitter.cs @@ -106,436 +106,113 @@ unsafe void IMetaDataImport.GetNestedClassProps(uint tdNestedClass, uint* ptdEnc // The rest of the methods aren't called - void IMetaDataImport.CloseEnum(IntPtr hEnum) { - throw new NotImplementedException(); - } - - void IMetaDataImport.CountEnum(IntPtr hEnum, ref uint pulCount) { - throw new NotImplementedException(); - } - - void IMetaDataImport.ResetEnum(IntPtr hEnum, uint ulPos) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumTypeDefs(IntPtr phEnum, uint[] rTypeDefs, uint cMax, out uint pcTypeDefs) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumInterfaceImpls(ref IntPtr phEnum, uint td, uint[] rImpls, uint cMax, ref uint pcImpls) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumTypeRefs(ref IntPtr phEnum, uint[] rTypeRefs, uint cMax, ref uint pcTypeRefs) { - throw new NotImplementedException(); - } - - void IMetaDataImport.FindTypeDefByName(string szTypeDef, uint tkEnclosingClass, out uint ptd) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetScopeProps(IntPtr szName, uint cchName, out uint pchName, out Guid pmvid) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetModuleFromScope(out uint pmd) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetInterfaceImplProps(uint iiImpl, out uint pClass, out uint ptkIface) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetTypeRefProps(uint tr, out uint ptkResolutionScope, IntPtr szName, uint cchName, out uint pchName) { - throw new NotImplementedException(); - } - - void IMetaDataImport.ResolveTypeRef(uint tr, ref Guid riid, out object ppIScope, out uint ptd) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMembers(ref IntPtr phEnum, uint cl, uint[] rMembers, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMembersWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMembers, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMethods(ref IntPtr phEnum, uint cl, uint[] rMethods, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMethodsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMethods, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumFields(ref IntPtr phEnum, uint cl, uint[] rFields, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumFieldsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rFields, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumParams(ref IntPtr phEnum, uint mb, uint[] rParams, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMemberRefs(ref IntPtr phEnum, uint tkParent, uint[] rMemberRefs, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMethodImpls(ref IntPtr phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumPermissionSets(ref IntPtr phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.FindMember(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) { - throw new NotImplementedException(); - } - - void IMetaDataImport.FindMethod(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) { - throw new NotImplementedException(); - } - - void IMetaDataImport.FindField(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) { - throw new NotImplementedException(); - } - - void IMetaDataImport.FindMemberRef(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmr) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetMemberRefProps(uint mr, out uint ptk, IntPtr szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob, out uint pbSig) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumProperties(ref IntPtr phEnum, uint td, uint[] rProperties, uint cMax, out uint pcProperties) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumEvents(ref IntPtr phEnum, uint td, uint[] rEvents, uint cMax, out uint pcEvents) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetEventProps(uint ev, out uint pClass, string szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumMethodSemantics(ref IntPtr phEnum, uint mb, uint[] rEventProp, uint cMax, out uint pcEventProp) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetMethodSemantics(uint mb, uint tkEventProp, out uint pdwSemanticsFlags) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetClassLayout(uint td, out uint pdwPackSize, out IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset, out uint pulClassSize) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetFieldMarshal(uint tk, out IntPtr ppvNativeType, out uint pcbNativeType) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetRVA(uint tk, out uint pulCodeRVA, out uint pdwImplFlags) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission, out uint pcbPermission) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetSigFromToken(uint mdSig, out IntPtr ppvSig, out uint pcbSig) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetModuleRefProps(uint mur, IntPtr szName, uint cchName, out uint pchName) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumModuleRefs(ref IntPtr phEnum, uint[] rModuleRefs, uint cmax, out uint pcModuleRefs) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig, out uint pcbSig) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetNameFromToken(uint tk, out IntPtr pszUtf8NamePtr) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumUnresolvedMethods(ref IntPtr phEnum, uint[] rMethods, uint cMax, out uint pcTokens) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetUserString(uint stk, IntPtr szString, uint cchString, out uint pchString) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetPinvokeMap(uint tk, out uint pdwMappingFlags, IntPtr szImportName, uint cchImportName, out uint pchImportName, out uint pmrImportDLL) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumSignatures(ref IntPtr phEnum, uint[] rSignatures, uint cmax, out uint pcSignatures) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumTypeSpecs(ref IntPtr phEnum, uint[] rTypeSpecs, uint cmax, out uint pcTypeSpecs) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumUserStrings(ref IntPtr phEnum, uint[] rStrings, uint cmax, out uint pcStrings) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetParamForMethodIndex(uint md, uint ulParamSeq, out uint ppd) { - throw new NotImplementedException(); - } - - void IMetaDataImport.EnumCustomAttributes(IntPtr phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax, out uint pcCustomAttributes) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob, out uint pcbSize) { - throw new NotImplementedException(); - } - - void IMetaDataImport.FindTypeRef(uint tkResolutionScope, string szName, out uint ptr) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetMemberProps(uint mb, out uint pClass, IntPtr szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetFieldProps(uint mb, out uint pClass, IntPtr szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetPropertyProps(uint prop, out uint pClass, IntPtr szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetParamProps(uint tk, out uint pmd, out uint pulSequence, IntPtr szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData, out uint pcbData) { - throw new NotImplementedException(); - } - - bool IMetaDataImport.IsValidToken(uint tk) { - throw new NotImplementedException(); - } - - void IMetaDataImport.GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig, out uint pCallConv) { - throw new NotImplementedException(); - } - - void IMetaDataImport.IsGlobal(uint pd, out int pbGlobal) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetModuleProps(string szName) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.Save(string szFile, uint dwSaveFlags) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SaveToStream(IStream pIStream, uint dwSaveFlags) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.GetSaveSize(int fSave, out uint pdwSaveSize) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineTypeDef(string szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint[] rtkImplements, out uint ptd) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineNestedType(string szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint[] rtkImplements, uint tdEncloser, out uint ptd) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetHandler(object pUnk) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineMethod(uint td, string szName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags, out uint pmd) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineMethodImpl(uint td, uint tkBody, uint tkDecl) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineTypeRefByName(uint tkResolutionScope, string szName, out uint ptr) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineImportType(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit, out uint ptr) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineMemberRef(uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmr) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineImportMember(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent, out uint pmr) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint[] rmdOtherMethods, out uint pmdEvent) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetClassLayout(uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DeleteClassLayout(uint td) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetFieldMarshal(uint tk, IntPtr pvNativeType, uint cbNativeType) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DeleteFieldMarshal(uint tk) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission, out uint ppm) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetRVA(uint md, uint ulRVA) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.GetTokenFromSig(IntPtr pvSig, uint cbSig, out uint pmsig) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineModuleRef(string szName, out uint pmur) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetParent(uint mr, uint tk) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig, out uint ptypespec) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SaveToMemory(out IntPtr pbData, uint cbData) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineUserString(string szString, uint cchString, out uint pstk) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DeleteToken(uint tkObj) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, uint[] rtkImplements) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint[] rmdOtherMethods) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetPermissionSetProps(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission, out uint ppm) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DeletePinvokeMap(uint tk) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineCustomAttribute(uint tkOwner, uint tkCtor, IntPtr pCustomAttribute, uint cbCustomAttribute, out uint pcv) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetCustomAttributeValue(uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineField(uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, out uint pmd) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineProperty(uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, uint[] rmdOtherMethods, out uint pmdProp) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, out uint ppd) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, uint[] rmdOtherMethods) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs, out uint pulErrorAttr) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.ApplyEditAndContinue(object pImport) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.TranslateSigWithScope(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax, out uint pcbTranslatedSig) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetMethodImplFlags(uint md, uint dwImplFlags) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.SetFieldRVA(uint fd, uint ulRVA) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.Merge(IMetaDataImport pImport, IntPtr pHostMapToken, object pHandler) { - throw new NotImplementedException(); - } - - void IMetaDataEmit.MergeEnd() { - throw new NotImplementedException(); - } + void IMetaDataImport.CloseEnum(IntPtr hEnum) => throw new NotImplementedException(); + void IMetaDataImport.CountEnum(IntPtr hEnum, ref uint pulCount) => throw new NotImplementedException(); + void IMetaDataImport.ResetEnum(IntPtr hEnum, uint ulPos) => throw new NotImplementedException(); + void IMetaDataImport.EnumTypeDefs(IntPtr phEnum, uint[] rTypeDefs, uint cMax, out uint pcTypeDefs) => throw new NotImplementedException(); + void IMetaDataImport.EnumInterfaceImpls(ref IntPtr phEnum, uint td, uint[] rImpls, uint cMax, ref uint pcImpls) => throw new NotImplementedException(); + void IMetaDataImport.EnumTypeRefs(ref IntPtr phEnum, uint[] rTypeRefs, uint cMax, ref uint pcTypeRefs) => throw new NotImplementedException(); + void IMetaDataImport.FindTypeDefByName(string szTypeDef, uint tkEnclosingClass, out uint ptd) => throw new NotImplementedException(); + void IMetaDataImport.GetScopeProps(IntPtr szName, uint cchName, out uint pchName, out Guid pmvid) => throw new NotImplementedException(); + void IMetaDataImport.GetModuleFromScope(out uint pmd) => throw new NotImplementedException(); + void IMetaDataImport.GetInterfaceImplProps(uint iiImpl, out uint pClass, out uint ptkIface) => throw new NotImplementedException(); + void IMetaDataImport.GetTypeRefProps(uint tr, out uint ptkResolutionScope, IntPtr szName, uint cchName, out uint pchName) => throw new NotImplementedException(); + void IMetaDataImport.ResolveTypeRef(uint tr, ref Guid riid, out object ppIScope, out uint ptd) => throw new NotImplementedException(); + void IMetaDataImport.EnumMembers(ref IntPtr phEnum, uint cl, uint[] rMembers, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMembersWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMembers, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethods(ref IntPtr phEnum, uint cl, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethodsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumFields(ref IntPtr phEnum, uint cl, uint[] rFields, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumFieldsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rFields, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumParams(ref IntPtr phEnum, uint mb, uint[] rParams, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMemberRefs(ref IntPtr phEnum, uint tkParent, uint[] rMemberRefs, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethodImpls(ref IntPtr phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumPermissionSets(ref IntPtr phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.FindMember(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); + void IMetaDataImport.FindMethod(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); + void IMetaDataImport.FindField(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); + void IMetaDataImport.FindMemberRef(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmr) => throw new NotImplementedException(); + void IMetaDataImport.GetMemberRefProps(uint mr, out uint ptk, IntPtr szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob, out uint pbSig) => throw new NotImplementedException(); + void IMetaDataImport.EnumProperties(ref IntPtr phEnum, uint td, uint[] rProperties, uint cMax, out uint pcProperties) => throw new NotImplementedException(); + void IMetaDataImport.EnumEvents(ref IntPtr phEnum, uint td, uint[] rEvents, uint cMax, out uint pcEvents) => throw new NotImplementedException(); + void IMetaDataImport.GetEventProps(uint ev, out uint pClass, string szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethodSemantics(ref IntPtr phEnum, uint mb, uint[] rEventProp, uint cMax, out uint pcEventProp) => throw new NotImplementedException(); + void IMetaDataImport.GetMethodSemantics(uint mb, uint tkEventProp, out uint pdwSemanticsFlags) => throw new NotImplementedException(); + void IMetaDataImport.GetClassLayout(uint td, out uint pdwPackSize, out IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset, out uint pulClassSize) => throw new NotImplementedException(); + void IMetaDataImport.GetFieldMarshal(uint tk, out IntPtr ppvNativeType, out uint pcbNativeType) => throw new NotImplementedException(); + void IMetaDataImport.GetRVA(uint tk, out uint pulCodeRVA, out uint pdwImplFlags) => throw new NotImplementedException(); + void IMetaDataImport.GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission, out uint pcbPermission) => throw new NotImplementedException(); + void IMetaDataImport.GetSigFromToken(uint mdSig, out IntPtr ppvSig, out uint pcbSig) => throw new NotImplementedException(); + void IMetaDataImport.GetModuleRefProps(uint mur, IntPtr szName, uint cchName, out uint pchName) => throw new NotImplementedException(); + void IMetaDataImport.EnumModuleRefs(ref IntPtr phEnum, uint[] rModuleRefs, uint cmax, out uint pcModuleRefs) => throw new NotImplementedException(); + void IMetaDataImport.GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig, out uint pcbSig) => throw new NotImplementedException(); + void IMetaDataImport.GetNameFromToken(uint tk, out IntPtr pszUtf8NamePtr) => throw new NotImplementedException(); + void IMetaDataImport.EnumUnresolvedMethods(ref IntPtr phEnum, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.GetUserString(uint stk, IntPtr szString, uint cchString, out uint pchString) => throw new NotImplementedException(); + void IMetaDataImport.GetPinvokeMap(uint tk, out uint pdwMappingFlags, IntPtr szImportName, uint cchImportName, out uint pchImportName, out uint pmrImportDLL) => throw new NotImplementedException(); + void IMetaDataImport.EnumSignatures(ref IntPtr phEnum, uint[] rSignatures, uint cmax, out uint pcSignatures) => throw new NotImplementedException(); + void IMetaDataImport.EnumTypeSpecs(ref IntPtr phEnum, uint[] rTypeSpecs, uint cmax, out uint pcTypeSpecs) => throw new NotImplementedException(); + void IMetaDataImport.EnumUserStrings(ref IntPtr phEnum, uint[] rStrings, uint cmax, out uint pcStrings) => throw new NotImplementedException(); + void IMetaDataImport.GetParamForMethodIndex(uint md, uint ulParamSeq, out uint ppd) => throw new NotImplementedException(); + void IMetaDataImport.EnumCustomAttributes(IntPtr phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax, out uint pcCustomAttributes) => throw new NotImplementedException(); + void IMetaDataImport.GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob, out uint pcbSize) => throw new NotImplementedException(); + void IMetaDataImport.FindTypeRef(uint tkResolutionScope, string szName, out uint ptr) => throw new NotImplementedException(); + void IMetaDataImport.GetMemberProps(uint mb, out uint pClass, IntPtr szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); + void IMetaDataImport.GetFieldProps(uint mb, out uint pClass, IntPtr szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); + void IMetaDataImport.GetPropertyProps(uint prop, out uint pClass, IntPtr szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) => throw new NotImplementedException(); + void IMetaDataImport.GetParamProps(uint tk, out uint pmd, out uint pulSequence, IntPtr szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); + void IMetaDataImport.GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData, out uint pcbData) => throw new NotImplementedException(); + bool IMetaDataImport.IsValidToken(uint tk) => throw new NotImplementedException(); + void IMetaDataImport.GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig, out uint pCallConv) => throw new NotImplementedException(); + void IMetaDataImport.IsGlobal(uint pd, out int pbGlobal) => throw new NotImplementedException(); + void IMetaDataEmit.SetModuleProps(string szName) => throw new NotImplementedException(); + void IMetaDataEmit.Save(string szFile, uint dwSaveFlags) => throw new NotImplementedException(); + void IMetaDataEmit.SaveToStream(IStream pIStream, uint dwSaveFlags) => throw new NotImplementedException(); + void IMetaDataEmit.GetSaveSize(int fSave, out uint pdwSaveSize) => throw new NotImplementedException(); + void IMetaDataEmit.DefineTypeDef(string szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint[] rtkImplements, out uint ptd) => throw new NotImplementedException(); + void IMetaDataEmit.DefineNestedType(string szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint[] rtkImplements, uint tdEncloser, out uint ptd) => throw new NotImplementedException(); + void IMetaDataEmit.SetHandler(object pUnk) => throw new NotImplementedException(); + void IMetaDataEmit.DefineMethod(uint td, string szName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags, out uint pmd) => throw new NotImplementedException(); + void IMetaDataEmit.DefineMethodImpl(uint td, uint tkBody, uint tkDecl) => throw new NotImplementedException(); + void IMetaDataEmit.DefineTypeRefByName(uint tkResolutionScope, string szName, out uint ptr) => throw new NotImplementedException(); + void IMetaDataEmit.DefineImportType(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit, out uint ptr) => throw new NotImplementedException(); + void IMetaDataEmit.DefineMemberRef(uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmr) => throw new NotImplementedException(); + void IMetaDataEmit.DefineImportMember(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent, out uint pmr) => throw new NotImplementedException(); + void IMetaDataEmit.DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint[] rmdOtherMethods, out uint pmdEvent) => throw new NotImplementedException(); + void IMetaDataEmit.SetClassLayout(uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize) => throw new NotImplementedException(); + void IMetaDataEmit.DeleteClassLayout(uint td) => throw new NotImplementedException(); + void IMetaDataEmit.SetFieldMarshal(uint tk, IntPtr pvNativeType, uint cbNativeType) => throw new NotImplementedException(); + void IMetaDataEmit.DeleteFieldMarshal(uint tk) => throw new NotImplementedException(); + void IMetaDataEmit.DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission, out uint ppm) => throw new NotImplementedException(); + void IMetaDataEmit.SetRVA(uint md, uint ulRVA) => throw new NotImplementedException(); + void IMetaDataEmit.GetTokenFromSig(IntPtr pvSig, uint cbSig, out uint pmsig) => throw new NotImplementedException(); + void IMetaDataEmit.DefineModuleRef(string szName, out uint pmur) => throw new NotImplementedException(); + void IMetaDataEmit.SetParent(uint mr, uint tk) => throw new NotImplementedException(); + void IMetaDataEmit.GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig, out uint ptypespec) => throw new NotImplementedException(); + void IMetaDataEmit.SaveToMemory(out IntPtr pbData, uint cbData) => throw new NotImplementedException(); + void IMetaDataEmit.DefineUserString(string szString, uint cchString, out uint pstk) => throw new NotImplementedException(); + void IMetaDataEmit.DeleteToken(uint tkObj) => throw new NotImplementedException(); + void IMetaDataEmit.SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags) => throw new NotImplementedException(); + void IMetaDataEmit.SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, uint[] rtkImplements) => throw new NotImplementedException(); + void IMetaDataEmit.SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint[] rmdOtherMethods) => throw new NotImplementedException(); + void IMetaDataEmit.SetPermissionSetProps(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission, out uint ppm) => throw new NotImplementedException(); + void IMetaDataEmit.DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) => throw new NotImplementedException(); + void IMetaDataEmit.SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) => throw new NotImplementedException(); + void IMetaDataEmit.DeletePinvokeMap(uint tk) => throw new NotImplementedException(); + void IMetaDataEmit.DefineCustomAttribute(uint tkOwner, uint tkCtor, IntPtr pCustomAttribute, uint cbCustomAttribute, out uint pcv) => throw new NotImplementedException(); + void IMetaDataEmit.SetCustomAttributeValue(uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute) => throw new NotImplementedException(); + void IMetaDataEmit.DefineField(uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, out uint pmd) => throw new NotImplementedException(); + void IMetaDataEmit.DefineProperty(uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, uint[] rmdOtherMethods, out uint pmdProp) => throw new NotImplementedException(); + void IMetaDataEmit.DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, out uint ppd) => throw new NotImplementedException(); + void IMetaDataEmit.SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) => throw new NotImplementedException(); + void IMetaDataEmit.SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, uint[] rmdOtherMethods) => throw new NotImplementedException(); + void IMetaDataEmit.SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) => throw new NotImplementedException(); + void IMetaDataEmit.DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs, out uint pulErrorAttr) => throw new NotImplementedException(); + void IMetaDataEmit.ApplyEditAndContinue(object pImport) => throw new NotImplementedException(); + void IMetaDataEmit.TranslateSigWithScope(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax, out uint pcbTranslatedSig) => throw new NotImplementedException(); + void IMetaDataEmit.SetMethodImplFlags(uint md, uint dwImplFlags) => throw new NotImplementedException(); + void IMetaDataEmit.SetFieldRVA(uint fd, uint ulRVA) => throw new NotImplementedException(); + void IMetaDataEmit.Merge(IMetaDataImport pImport, IntPtr pHostMapToken, object pHandler) => throw new NotImplementedException(); + void IMetaDataEmit.MergeEnd() => throw new NotImplementedException(); } } diff --git a/src/DotNet/Pdb/Dss/PinnedMetaData.cs b/src/DotNet/Pdb/Dss/PinnedMetaData.cs index 38ce738e4..136a4f5cc 100644 --- a/src/DotNet/Pdb/Dss/PinnedMetaData.cs +++ b/src/DotNet/Pdb/Dss/PinnedMetaData.cs @@ -17,16 +17,12 @@ sealed class PinnedMetaData : IDisposable { /// /// Gets the address /// - public IntPtr Address { - get { return address; } - } + public IntPtr Address => address; /// /// Gets the size /// - public int Size { - get { return (int)stream.Length; } - } + public int Size => (int)stream.Length; /// /// Constructor @@ -35,22 +31,20 @@ public int Size { public PinnedMetaData(IImageStream stream) { this.stream = stream; - var umStream = stream as UnmanagedMemoryImageStream; - if (umStream != null) { - this.address = umStream.StartAddress; + if (stream is UnmanagedMemoryImageStream umStream) { + address = umStream.StartAddress; GC.SuppressFinalize(this); // no GCHandle so finalizer isn't needed } else { - var memStream = stream as MemoryImageStream; - if (memStream != null) { - this.streamData = memStream.DataArray; - this.gcHandle = GCHandle.Alloc(this.streamData, GCHandleType.Pinned); - this.address = new IntPtr(this.gcHandle.AddrOfPinnedObject().ToInt64() + memStream.DataOffset); + if (stream is MemoryImageStream memStream) { + streamData = memStream.DataArray; + gcHandle = GCHandle.Alloc(streamData, GCHandleType.Pinned); + address = new IntPtr(gcHandle.AddrOfPinnedObject().ToInt64() + memStream.DataOffset); } else { - this.streamData = stream.ReadAllBytes(); - this.gcHandle = GCHandle.Alloc(this.streamData, GCHandleType.Pinned); - this.address = this.gcHandle.AddrOfPinnedObject(); + streamData = stream.ReadAllBytes(); + gcHandle = GCHandle.Alloc(streamData, GCHandleType.Pinned); + address = gcHandle.AddrOfPinnedObject(); } } } diff --git a/src/DotNet/Pdb/Dss/StreamIStream.cs b/src/DotNet/Pdb/Dss/StreamIStream.cs index 279a5246a..45b621ec9 100644 --- a/src/DotNet/Pdb/Dss/StreamIStream.cs +++ b/src/DotNet/Pdb/Dss/StreamIStream.cs @@ -30,9 +30,7 @@ public StreamIStream(Stream stream) /// Source stream /// Name of original file or null if unknown. public StreamIStream(Stream stream, string name) { - if (stream == null) - throw new ArgumentNullException("stream"); - this.stream = stream; + this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); this.name = name ?? string.Empty; } @@ -43,9 +41,7 @@ public void Clone(out IStream ppstm) { } /// - public void Commit(int grfCommitFlags) { - stream.Flush(); - } + public void Commit(int grfCommitFlags) => stream.Flush(); /// public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { @@ -68,9 +64,8 @@ public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { } /// - public void LockRegion(long libOffset, long cb, int dwLockType) { + public void LockRegion(long libOffset, long cb, int dwLockType) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - } /// public void Read(byte[] pv, int cb, IntPtr pcbRead) { @@ -114,9 +109,7 @@ public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) { } /// - public void SetSize(long libNewSize) { - stream.SetLength(libNewSize); - } + public void SetSize(long libNewSize) => stream.SetLength(libNewSize); enum STATFLAG { DEFAULT = 0, @@ -152,9 +145,8 @@ public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, i } /// - public void UnlockRegion(long libOffset, long cb, int dwLockType) { + public void UnlockRegion(long libOffset, long cb, int dwLockType) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - } /// public void Write(byte[] pv, int cb, IntPtr pcbWritten) { diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index 5de138e4c..387a76140 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -6,51 +6,40 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolDocumentImpl : SymbolDocument { readonly ISymUnmanagedDocument document; - - public ISymUnmanagedDocument SymUnmanagedDocument { - get { return document; } - } - - public SymbolDocumentImpl(ISymUnmanagedDocument document) { - this.document = document; - } + public ISymUnmanagedDocument SymUnmanagedDocument => document; + public SymbolDocumentImpl(ISymUnmanagedDocument document) => this.document = document; public override Guid CheckSumAlgorithmId { get { - Guid guid; - document.GetCheckSumAlgorithmId(out guid); + document.GetCheckSumAlgorithmId(out var guid); return guid; } } public override Guid DocumentType { get { - Guid guid; - document.GetDocumentType(out guid); + document.GetDocumentType(out var guid); return guid; } } public override Guid Language { get { - Guid guid; - document.GetLanguage(out guid); + document.GetLanguage(out var guid); return guid; } } public override Guid LanguageVendor { get { - Guid guid; - document.GetLanguageVendor(out guid); + document.GetLanguageVendor(out var guid); return guid; } } public override string URL { get { - uint count; - document.GetURL(0, out count, null); + document.GetURL(0, out uint count, null); var chars = new char[count]; document.GetURL((uint)chars.Length, out count, chars); if (chars.Length == 0) @@ -61,17 +50,14 @@ public override string URL { public override byte[] CheckSum { get { - uint bufSize; - document.GetCheckSum(0, out bufSize, null); + document.GetCheckSum(0, out uint bufSize, null); var buffer = new byte[bufSize]; document.GetCheckSum((uint)buffer.Length, out bufSize, buffer); return buffer; } } - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { return emptyPdbCustomDebugInfos; } - } + public override PdbCustomDebugInfo[] CustomDebugInfos => emptyPdbCustomDebugInfos; static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; } } diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs index 9ba6e5d08..ca02ca7a2 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs @@ -6,21 +6,9 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolDocumentWriter : ISymbolDocumentWriter { readonly ISymUnmanagedDocumentWriter writer; - - public ISymUnmanagedDocumentWriter SymUnmanagedDocumentWriter { - get { return writer; } - } - - public SymbolDocumentWriter(ISymUnmanagedDocumentWriter writer) { - this.writer = writer; - } - - public void SetCheckSum(Guid algorithmId, byte[] checkSum) { - writer.SetCheckSum(algorithmId, (uint)(checkSum == null ? 0 : checkSum.Length), checkSum); - } - - public void SetSource(byte[] source) { - writer.SetSource((uint)source.Length, source); - } + public ISymUnmanagedDocumentWriter SymUnmanagedDocumentWriter => writer; + public SymbolDocumentWriter(ISymUnmanagedDocumentWriter writer) => this.writer = writer; + public void SetCheckSum(Guid algorithmId, byte[] checkSum) => writer.SetCheckSum(algorithmId, (uint)(checkSum == null ? 0 : checkSum.Length), checkSum); + public void SetSource(byte[] source) => writer.SetSource((uint)source.Length, source); } } diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index 3c1142db7..1f75488e4 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -20,8 +20,7 @@ public SymbolMethodImpl(SymbolReaderImpl reader, ISymUnmanagedMethod method) { public override int Token { get { - uint result; - method.GetToken(out result); + method.GetToken(out uint result); return (int)result; } } @@ -29,8 +28,7 @@ public override int Token { public override SymbolScope RootScope { get { if (rootScope == null) { - ISymUnmanagedScope scope; - method.GetRootScope(out scope); + method.GetRootScope(out var scope); Interlocked.CompareExchange(ref rootScope, scope == null ? null : new SymbolScopeImpl(scope, this, null), null); } return rootScope; @@ -41,21 +39,18 @@ public override SymbolScope RootScope { public override IList SequencePoints { get { if (sequencePoints == null) { - uint seqPointCount; - method.GetSequencePointCount(out seqPointCount); + method.GetSequencePointCount(out uint seqPointCount); var seqPoints = new SymbolSequencePoint[seqPointCount]; - int[] offsets = new int[seqPoints.Length]; - ISymbolDocument[] documents = new ISymbolDocument[seqPoints.Length]; - int[] lines = new int[seqPoints.Length]; - int[] columns = new int[seqPoints.Length]; - int[] endLines = new int[seqPoints.Length]; - int[] endColumns = new int[seqPoints.Length]; + var offsets = new int[seqPoints.Length]; + var documents = new ISymbolDocument[seqPoints.Length]; + var lines = new int[seqPoints.Length]; + var columns = new int[seqPoints.Length]; + var endLines = new int[seqPoints.Length]; + var endColumns = new int[seqPoints.Length]; var unDocs = new ISymUnmanagedDocument[seqPoints.Length]; - if (seqPoints.Length != 0) { - uint size; - method.GetSequencePoints((uint)seqPoints.Length, out size, offsets, unDocs, lines, columns, endLines, endColumns); - } + if (seqPoints.Length != 0) + method.GetSequencePoints((uint)seqPoints.Length, out uint size, offsets, unDocs, lines, columns, endLines, endColumns); for (int i = 0; i < seqPoints.Length; i++) { seqPoints[i] = new SymbolSequencePoint { Offset = offsets[i], @@ -111,8 +106,7 @@ public IList AsyncStepInfos { } volatile SymbolAsyncStepInfo[] asyncStepInfos; - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) => reader.GetCustomDebugInfos(this, method, body, result); - } } } diff --git a/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs b/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs index e6c5cd4de..ec5750de6 100644 --- a/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs @@ -6,14 +6,11 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolNamespaceImpl : SymbolNamespace { readonly ISymUnmanagedNamespace ns; - public SymbolNamespaceImpl(ISymUnmanagedNamespace @namespace) { - this.ns = @namespace; - } + public SymbolNamespaceImpl(ISymUnmanagedNamespace @namespace) => ns = @namespace; public override string Name { get { - uint count; - ns.GetName(0, out count, null); + ns.GetName(0, out uint count, null); var chars = new char[count]; ns.GetName((uint)chars.Length, out count, chars); if (chars.Length == 0) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs index 035ea6739..50cfe81a6 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs @@ -27,22 +27,19 @@ static class SymbolReaderCreator { /// file on disk or if any of the COM methods fail. public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { try { - object mdDispObj; - Guid CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); - Guid IID_IMetaDataDispenser = new Guid(0x809C652E, 0x7396, 0x11D2, 0x97, 0x71, 0x00, 0xA0, 0xC9, 0xB4, 0xD5, 0x0C); - int hr = CoCreateInstance(ref CLSID_CorMetaDataDispenser, IntPtr.Zero, 1, ref IID_IMetaDataDispenser, out mdDispObj); + var CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); + var IID_IMetaDataDispenser = new Guid(0x809C652E, 0x7396, 0x11D2, 0x97, 0x71, 0x00, 0xA0, 0xC9, 0xB4, 0xD5, 0x0C); + int hr = CoCreateInstance(ref CLSID_CorMetaDataDispenser, IntPtr.Zero, 1, ref IID_IMetaDataDispenser, out object mdDispObj); if (hr < 0) return null; - object mdImportObj; var mdDisp = (IMetaDataDispenser)mdDispObj; - Guid IID_IMetaDataImport = new Guid(0x7DAC8207, 0xD3AE, 0x4C75, 0x9B, 0x67, 0x92, 0x80, 0x1A, 0x49, 0x7D, 0x44); - mdDisp.OpenScope(assemblyFileName, 0, ref IID_IMetaDataImport, out mdImportObj); + var IID_IMetaDataImport = new Guid(0x7DAC8207, 0xD3AE, 0x4C75, 0x9B, 0x67, 0x92, 0x80, 0x1A, 0x49, 0x7D, 0x44); + mdDisp.OpenScope(assemblyFileName, 0, ref IID_IMetaDataImport, out object mdImportObj); Marshal.FinalReleaseComObject(mdDispObj); - ISymUnmanagedReader symReader; var binder = (ISymUnmanagedBinder)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymBinder_SxS)); - hr = binder.GetReaderForFile((IMetaDataImport)mdImportObj, assemblyFileName, null, out symReader); + hr = binder.GetReaderForFile((IMetaDataImport)mdImportObj, assemblyFileName, null, out var symReader); Marshal.FinalReleaseComObject(mdImportObj); Marshal.FinalReleaseComObject(binder); if (hr >= 0) @@ -175,24 +172,21 @@ public static SymbolReader Create(IImageStream mdStream, IImageStream pdbStream) if (pdbStream == null || mdStream == null) return null; - object mdDispObj; - Guid CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); - Guid IID_IMetaDataDispenser = new Guid(0x809C652E, 0x7396, 0x11D2, 0x97, 0x71, 0x00, 0xA0, 0xC9, 0xB4, 0xD5, 0x0C); - int hr = CoCreateInstance(ref CLSID_CorMetaDataDispenser, IntPtr.Zero, 1, ref IID_IMetaDataDispenser, out mdDispObj); + var CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); + var IID_IMetaDataDispenser = new Guid(0x809C652E, 0x7396, 0x11D2, 0x97, 0x71, 0x00, 0xA0, 0xC9, 0xB4, 0xD5, 0x0C); + int hr = CoCreateInstance(ref CLSID_CorMetaDataDispenser, IntPtr.Zero, 1, ref IID_IMetaDataDispenser, out object mdDispObj); if (hr < 0) return null; - object mdImportObj; var mdDisp = (IMetaDataDispenser)mdDispObj; - Guid IID_IMetaDataImport = new Guid(0x7DAC8207, 0xD3AE, 0x4C75, 0x9B, 0x67, 0x92, 0x80, 0x1A, 0x49, 0x7D, 0x44); + var IID_IMetaDataImport = new Guid(0x7DAC8207, 0xD3AE, 0x4C75, 0x9B, 0x67, 0x92, 0x80, 0x1A, 0x49, 0x7D, 0x44); pinnedMd = new PinnedMetaData(mdStream); - mdDisp.OpenScopeOnMemory(pinnedMd.Address, (uint)pinnedMd.Size, 0x10, ref IID_IMetaDataImport, out mdImportObj); + mdDisp.OpenScopeOnMemory(pinnedMd.Address, (uint)pinnedMd.Size, 0x10, ref IID_IMetaDataImport, out object mdImportObj); Marshal.FinalReleaseComObject(mdDispObj); - ISymUnmanagedReader symReader; var binder = (ISymUnmanagedBinder)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymBinder_SxS)); stream = new ImageStreamIStream(pdbStream, null) { UserData = pinnedMd }; - hr = binder.GetReaderFromStream((IMetaDataImport)mdImportObj, stream, out symReader); + hr = binder.GetReaderFromStream((IMetaDataImport)mdImportObj, stream, out var symReader); Marshal.FinalReleaseComObject(mdImportObj); Marshal.FinalReleaseComObject(binder); if (hr >= 0) { diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 5f0d2b7e1..c2534bfa7 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -18,20 +18,14 @@ sealed class SymbolReaderImpl : SymbolReader { /// Constructor /// /// An unmanaged symbol reader - public SymbolReaderImpl(ISymUnmanagedReader reader) { - if (reader == null) - throw new ArgumentNullException("reader"); - this.reader = reader; - } + public SymbolReaderImpl(ISymUnmanagedReader reader) => + this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); - public override PdbFileKind PdbFileKind { - get { return PdbFileKind.WindowsPDB; } - } + public override PdbFileKind PdbFileKind => PdbFileKind.WindowsPDB; public override int UserEntryPoint { get { - uint token; - int hr = reader.GetUserEntryPoint(out token); + int hr = reader.GetUserEntryPoint(out uint token); if (hr == E_FAIL) token = 0; else @@ -43,8 +37,7 @@ public override int UserEntryPoint { public override IList Documents { get { if (documents == null) { - uint numDocs; - reader.GetDocuments(0, out numDocs, null); + reader.GetDocuments(0, out uint numDocs, null); var unDocs = new ISymUnmanagedDocument[numDocs]; reader.GetDocuments((uint)unDocs.Length, out numDocs, unDocs); var docs = new SymbolDocument[numDocs]; @@ -57,13 +50,10 @@ public override IList Documents { } volatile SymbolDocument[] documents; - public override void Initialize(ModuleDef module) { - this.module = module; - } + public override void Initialize(ModuleDef module) => this.module = module; public override SymbolMethod GetMethod(MethodDef method, int version) { - ISymUnmanagedMethod unMethod; - int hr = reader.GetMethodByVersion(method.MDToken.Raw, version, out unMethod); + int hr = reader.GetMethodByVersion(method.MDToken.Raw, version, out var unMethod); if (hr == E_FAIL) return null; Marshal.ThrowExceptionForHR(hr); @@ -76,8 +66,7 @@ internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, result.Add(asyncMethod); const string CDI_NAME = "MD2"; - uint bufSize; - reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, 0, out bufSize, null); + reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, 0, out uint bufSize, null); if (bufSize == 0) return; var cdiData = new byte[bufSize]; diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs index daeb695e9..18b560591 100644 --- a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -16,26 +16,19 @@ public SymbolScopeImpl(ISymUnmanagedScope scope, SymbolMethod method, SymbolScop this.parent = parent; } - public override SymbolMethod Method { - get { return method; } - } - - public override SymbolScope Parent { - get { return parent; } - } + public override SymbolMethod Method => method; + public override SymbolScope Parent => parent; public override int StartOffset { get { - uint result; - scope.GetStartOffset(out result); + scope.GetStartOffset(out uint result); return (int)result; } } public override int EndOffset { get { - uint result; - scope.GetEndOffset(out result); + scope.GetEndOffset(out uint result); return (int)result; } } @@ -43,8 +36,7 @@ public override int EndOffset { public override IList Children { get { if (children == null) { - uint numScopes; - scope.GetChildren(0, out numScopes, null); + scope.GetChildren(0, out uint numScopes, null); var unScopes = new ISymUnmanagedScope[numScopes]; scope.GetChildren((uint)unScopes.Length, out numScopes, unScopes); var scopes = new SymbolScope[numScopes]; @@ -60,8 +52,7 @@ public override IList Children { public override IList Locals { get { if (locals == null) { - uint numVars; - scope.GetLocals(0, out numVars, null); + scope.GetLocals(0, out uint numVars, null); var unVars = new ISymUnmanagedVariable[numVars]; scope.GetLocals((uint)unVars.Length, out numVars, unVars); var vars = new SymbolVariable[numVars]; @@ -77,8 +68,7 @@ public override IList Locals { public override IList Namespaces { get { if (namespaces == null) { - uint numNss; - scope.GetNamespaces(0, out numNss, null); + scope.GetNamespaces(0, out uint numNss, null); var unNss = new ISymUnmanagedNamespace[numNss]; scope.GetNamespaces((uint)unNss.Length, out numNss, unNss); var nss = new SymbolNamespace[numNss]; @@ -91,21 +81,15 @@ public override IList Namespaces { } volatile SymbolNamespace[] namespaces; - public override IList CustomDebugInfos { - get { return emptyPdbCustomDebugInfos; } - } + public override IList CustomDebugInfos => emptyPdbCustomDebugInfos; static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; - - public override PdbImportScope ImportScope { - get { return null; } - } + public override PdbImportScope ImportScope => null; public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { var scope2 = scope as ISymUnmanagedScope2; if (scope2 == null) return emptySymbolConstants; - uint numCs; - scope2.GetConstants(0, out numCs, null); + scope2.GetConstants(0, out uint numCs, null); if (numCs == 0) return emptySymbolConstants; var unCs = new ISymUnmanagedConstant[numCs]; @@ -114,8 +98,7 @@ public override IList GetConstants(ModuleDef module, GenericParamCo for (uint i = 0; i < numCs; i++) { var unc = unCs[i]; var name = GetName(unc); - object value; - unc.GetValue(out value); + unc.GetValue(out object value); var sigBytes = GetSignatureBytes(unc); TypeSig signature; if (sigBytes.Length == 0) @@ -129,8 +112,7 @@ public override IList GetConstants(ModuleDef module, GenericParamCo static readonly PdbConstant[] emptySymbolConstants = new PdbConstant[0]; string GetName(ISymUnmanagedConstant unc) { - uint count; - unc.GetName(0, out count, null); + unc.GetName(0, out uint count, null); var chars = new char[count]; unc.GetName((uint)chars.Length, out count, chars); if (chars.Length == 0) @@ -141,8 +123,7 @@ string GetName(ISymUnmanagedConstant unc) { byte[] GetSignatureBytes(ISymUnmanagedConstant unc) { const int E_FAIL = unchecked((int)0x80004005); const int E_NOTIMPL = unchecked((int)0x80004001); - uint bufSize; - int hr = unc.GetSignature(0, out bufSize, null); + int hr = unc.GetSignature(0, out uint bufSize, null); if (bufSize == 0 || (hr < 0 && hr != E_FAIL && hr != E_NOTIMPL)) return emptyByteArray; var buffer = new byte[bufSize]; diff --git a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs index 8c4649648..2d511ed7b 100644 --- a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs @@ -7,22 +7,18 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolVariableImpl : SymbolVariable { readonly ISymUnmanagedVariable variable; - public SymbolVariableImpl(ISymUnmanagedVariable variable) { - this.variable = variable; - } + public SymbolVariableImpl(ISymUnmanagedVariable variable) => this.variable = variable; public override int Index { get { - uint result; - variable.GetAddressField1(out result); + variable.GetAddressField1(out uint result); return (int)result; } } public override PdbLocalAttributes Attributes { get { - uint result; - variable.GetAttributes(out result); + variable.GetAttributes(out uint result); if ((result & (uint)CorSymVarFlag.VAR_IS_COMP_GEN) != 0) return PdbLocalAttributes.DebuggerHidden; return PdbLocalAttributes.None; @@ -31,8 +27,7 @@ public override PdbLocalAttributes Attributes { public override string Name { get { - uint count; - variable.GetName(0, out count, null); + variable.GetName(0, out uint count, null); var chars = new char[count]; variable.GetName((uint)chars.Length, out count, chars); if (chars.Length == 0) @@ -41,9 +36,7 @@ public override string Name { } } - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { return emptyPdbCustomDebugInfos; } - } + public override PdbCustomDebugInfo[] CustomDebugInfos => emptyPdbCustomDebugInfos; static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; } } diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index 7af579b35..5f6da7407 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -16,9 +16,7 @@ sealed class SymbolWriter : ISymbolWriter3 { readonly Stream pdbStream; bool closeCalled; - public bool SupportsAsyncMethods { - get { return asyncMethodWriter != null; } - } + public bool SupportsAsyncMethods => asyncMethodWriter != null; /// /// Constructor @@ -26,13 +24,9 @@ public bool SupportsAsyncMethods { /// Writer /// PDB file name public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName) { - if (writer == null) - throw new ArgumentNullException("writer"); - if (pdbFileName == null) - throw new ArgumentNullException("pdbFileName"); - this.writer = writer; - this.asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; - this.pdbFileName = pdbFileName; + this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); + asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; + this.pdbFileName = pdbFileName ?? throw new ArgumentNullException(nameof(pdbFileName)); } /// @@ -42,19 +36,13 @@ public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName) { /// PDB file name /// PDB output stream public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream) { - if (writer == null) - throw new ArgumentNullException("writer"); - if (pdbStream == null) - throw new ArgumentNullException("pdbStream"); - this.writer = writer; - this.asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; - this.pdbStream = pdbStream; + this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); + asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; + this.pdbStream = pdbStream ?? throw new ArgumentNullException(nameof(pdbStream)); this.pdbFileName = pdbFileName; } - public void Abort() { - writer.Abort(); - } + public void Abort() => writer.Abort(); public void Close() { if (closeCalled) @@ -63,17 +51,9 @@ public void Close() { writer.Close(); } - public void CloseMethod() { - writer.CloseMethod(); - } - - public void CloseNamespace() { - writer.CloseNamespace(); - } - - public void CloseScope(int endOffset) { - writer.CloseScope((uint)endOffset); - } + public void CloseMethod() => writer.CloseMethod(); + public void CloseNamespace() => writer.CloseNamespace(); + public void CloseScope(int endOffset) => writer.CloseScope((uint)endOffset); public void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod) { if (asyncMethodWriter == null) @@ -89,31 +69,22 @@ public void DefineCatchHandlerILOffset(uint catchHandlerOffset) { asyncMethodWriter.DefineCatchHandlerILOffset(catchHandlerOffset); } - public void DefineConstant(string name, object value, byte[] signature) { - writer.DefineConstant(name, value, (uint)signature.Length, signature); - } - - public void DefineConstant2(string name, object value, uint sigToken) { - writer.DefineConstant2(name, value, sigToken); - } + public void DefineConstant(string name, object value, byte[] signature) => writer.DefineConstant(name, value, (uint)signature.Length, signature); + public void DefineConstant2(string name, object value, uint sigToken) => writer.DefineConstant2(name, value, sigToken); public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { - ISymUnmanagedDocumentWriter unDocWriter; - writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out unDocWriter); + writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out var unDocWriter); return unDocWriter == null ? null : new SymbolDocumentWriter(unDocWriter); } - public void DefineField(SymbolToken parent, string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) { + public void DefineField(SymbolToken parent, string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) => writer.DefineField((uint)parent.GetToken(), name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); - } - public void DefineGlobalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) { + public void DefineGlobalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) => writer.DefineGlobalVariable(name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); - } - public void DefineGlobalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3) { + public void DefineGlobalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3) => writer.DefineGlobalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3); - } public void DefineKickoffMethod(uint kickoffMethod) { if (asyncMethodWriter == null) @@ -121,13 +92,11 @@ public void DefineKickoffMethod(uint kickoffMethod) { asyncMethodWriter.DefineKickoffMethod(kickoffMethod); } - public void DefineLocalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) { + public void DefineLocalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) => writer.DefineLocalVariable(name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3, (uint)startOffset, (uint)endOffset); - } - public void DefineParameter(string name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3) { + public void DefineParameter(string name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3) => writer.DefineParameter(name, (uint)attributes, (uint)sequence, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); - } public void DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) { var doc = document as SymbolDocumentWriter; @@ -150,27 +119,16 @@ public void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, writer.DefineSequencePoints(doc.SymUnmanagedDocumentWriter, arraySize, offsets, lines, columns, endLines, endColumns); } - public void Initialize(IntPtr emitter, string filename, bool fFullBuild) { - writer.Initialize(emitter, filename, null, fFullBuild); - } - - public void OpenMethod(SymbolToken method) { - writer.OpenMethod((uint)method.GetToken()); - } - - public void OpenNamespace(string name) { - writer.OpenNamespace(name); - } + public void Initialize(IntPtr emitter, string filename, bool fFullBuild) => writer.Initialize(emitter, filename, null, fFullBuild); + public void OpenMethod(SymbolToken method) => writer.OpenMethod((uint)method.GetToken()); + public void OpenNamespace(string name) => writer.OpenNamespace(name); public int OpenScope(int startOffset) { - uint result; - writer.OpenScope((uint)startOffset, out result); + writer.OpenScope((uint)startOffset, out uint result); return (int)result; } - public void RemapToken(uint oldToken, uint newToken) { - writer.RemapToken(oldToken, newToken); - } + public void RemapToken(uint oldToken, uint newToken) => writer.RemapToken(oldToken, newToken); public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn) { var sdoc = startDoc as SymbolDocumentWriter; @@ -182,37 +140,21 @@ public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, writer.SetMethodSourceRange(sdoc.SymUnmanagedDocumentWriter, (uint)startLine, (uint)startColumn, edoc.SymUnmanagedDocumentWriter, (uint)endLine, (uint)endColumn); } - public void SetScopeRange(int scopeID, int startOffset, int endOffset) { - writer.SetScopeRange((uint)scopeID, (uint)startOffset, (uint)endOffset); - } - - public void SetSymAttribute(SymbolToken parent, string name, byte[] data) { - writer.SetSymAttribute((uint)parent.GetToken(), name, (uint)data.Length, data); - } - - public void SetUnderlyingWriter(IntPtr underlyingWriter) { - throw new NotSupportedException(); - } - - public void SetUserEntryPoint(SymbolToken entryMethod) { - writer.SetUserEntryPoint((uint)entryMethod.GetToken()); - } - - public void UsingNamespace(string fullName) { - writer.UsingNamespace(fullName); - } + public void SetScopeRange(int scopeID, int startOffset, int endOffset) => writer.SetScopeRange((uint)scopeID, (uint)startOffset, (uint)endOffset); + public void SetSymAttribute(SymbolToken parent, string name, byte[] data) => writer.SetSymAttribute((uint)parent.GetToken(), name, (uint)data.Length, data); + public void SetUnderlyingWriter(IntPtr underlyingWriter) => throw new NotSupportedException(); + public void SetUserEntryPoint(SymbolToken entryMethod) => writer.SetUserEntryPoint((uint)entryMethod.GetToken()); + public void UsingNamespace(string fullName) => writer.UsingNamespace(fullName); public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY pIDD) { - uint size; - writer.GetDebugInfo(out pIDD, 0, out size, null); + writer.GetDebugInfo(out pIDD, 0, out uint size, null); var buffer = new byte[size]; writer.GetDebugInfo(out pIDD, size, out size, buffer); return buffer; } - public void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset) { + public void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset) => writer.DefineLocalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3, startOffset, endOffset); - } public void Initialize(MetaData metaData) { if (pdbStream != null) @@ -223,8 +165,6 @@ public void Initialize(MetaData metaData) { throw new InvalidOperationException(); } - public void Dispose() { - Marshal.FinalReleaseComObject(writer); - } + public void Dispose() => Marshal.FinalReleaseComObject(writer); } } diff --git a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs index e834219d3..2d76baa5e 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs @@ -15,9 +15,8 @@ static class SymbolWriterCreator { /// Creates a instance /// /// A new instance - public static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2() { - return (ISymUnmanagedWriter2)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS)); - } + public static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2() => + (ISymUnmanagedWriter2)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS)); /// /// Creates a new instance @@ -36,8 +35,7 @@ public static ISymbolWriter2 Create(string pdbFileName) { /// PDB output stream /// PDB file name /// A new instance - public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) { - return new SymbolWriter(CreateSymUnmanagedWriter2(), pdbFileName, pdbStream); - } + public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) => + new SymbolWriter(CreateSymUnmanagedWriter2(), pdbFileName, pdbStream); } } diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index e3757883b..4f77650ad 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -14,27 +14,13 @@ sealed class DbiDocument : SymbolDocument { Guid checkSumAlgorithmId; byte[] checkSum; - public override string URL { - get { return url; } - } - public override Guid Language { - get { return language; } - } - public override Guid LanguageVendor { - get { return languageVendor; } - } - public override Guid DocumentType { - get { return documentType; } - } - public override Guid CheckSumAlgorithmId { - get { return checkSumAlgorithmId; } - } - public override byte[] CheckSum { - get { return checkSum; } - } - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { return emptyPdbCustomDebugInfos; } - } + public override string URL => url; + public override Guid Language => language; + public override Guid LanguageVendor => languageVendor; + public override Guid DocumentType => documentType; + public override Guid CheckSumAlgorithmId => checkSumAlgorithmId; + public override byte[] CheckSum => checkSum; + public override PdbCustomDebugInfo[] CustomDebugInfos => emptyPdbCustomDebugInfos; static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; public DbiDocument(string url) { diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index 11ba5e28f..f6a0c65bf 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -8,9 +8,7 @@ namespace dnlib.DotNet.Pdb.Managed { sealed class DbiFunction : SymbolMethod { - public override int Token { - get { return token; } - } + public override int Token => token; internal int token; internal PdbReader reader; @@ -19,8 +17,8 @@ public override int Token { public PdbAddress Address { get; private set; } public DbiScope Root { get; private set; } public List Lines { - get { return lines; } - set { lines = value; } + get => lines; + set => lines = value; } List lines; @@ -53,9 +51,7 @@ void FixOffsets(RecursionCounter counter, DbiScope scope) { counter.Decrement(); } - public override SymbolScope RootScope { - get { return Root; } - } + public override SymbolScope RootScope => Root; public override IList SequencePoints { get { @@ -116,8 +112,7 @@ SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { } static readonly SymbolAsyncStepInfo[] emptySymbolAsyncStepInfos = new SymbolAsyncStepInfo[0]; - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) => reader.GetCustomDebugInfos(this, method, body, result); - } } } diff --git a/src/DotNet/Pdb/Managed/DbiNamespace.cs b/src/DotNet/Pdb/Managed/DbiNamespace.cs index 75a5d2399..961c75c6c 100644 --- a/src/DotNet/Pdb/Managed/DbiNamespace.cs +++ b/src/DotNet/Pdb/Managed/DbiNamespace.cs @@ -4,13 +4,9 @@ namespace dnlib.DotNet.Pdb.Managed { sealed class DbiNamespace : SymbolNamespace { - public override string Name { - get { return name; } - } + public override string Name => name; readonly string name; - public DbiNamespace(string ns) { - name = ns; - } + public DbiNamespace(string ns) => name = ns; } } diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 652c8c524..4664acbfc 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -16,42 +16,16 @@ sealed class DbiScope : SymbolScope { readonly List localsList; readonly List namespacesList; - public override SymbolMethod Method { - get { return method; } - } - - public override SymbolScope Parent { - get { return parent; } - } - - public override int StartOffset { - get { return startOffset; } - } - - public override int EndOffset { - get { return endOffset; } - } - - public override IList Children { - get { return childrenList; } - } - - public override IList Locals { - get { return localsList; } - } - - public override IList Namespaces { - get { return namespacesList; } - } - - public override IList CustomDebugInfos { - get { return emptyPdbCustomDebugInfos; } - } + public override SymbolMethod Method => method; + public override SymbolScope Parent => parent; + public override int StartOffset => startOffset; + public override int EndOffset => endOffset; + public override IList Children => childrenList; + public override IList Locals => localsList; + public override IList Namespaces => namespacesList; + public override IList CustomDebugInfos => emptyPdbCustomDebugInfos; static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; - - public override PdbImportScope ImportScope { - get { return null; } - } + public override PdbImportScope ImportScope => null; public DbiScope(SymbolMethod method, SymbolScope parent, string name, uint offset, uint length) { this.method = method; @@ -70,10 +44,10 @@ public DbiScope(SymbolMethod method, SymbolScope parent, string name, uint offse List oemInfos; List constants; - struct ConstantInfo { - public string Name; - public uint SignatureToken; - public object Value; + readonly struct ConstantInfo { + public readonly string Name; + public readonly uint SignatureToken; + public readonly object Value; public ConstantInfo(string name, uint signatureToken, object value) { Name = name; SignatureToken = signatureToken; @@ -81,16 +55,14 @@ public ConstantInfo(string name, uint signatureToken, object value) { } } - internal struct OemInfo { + internal readonly struct OemInfo { public readonly string Name; public readonly byte[] Data; public OemInfo(string name, byte[] data) { Name = name; Data = data; } - public override string ToString() { - return Name + " = (" + Data.Length.ToString() + " bytes)"; - } + public override string ToString() => Name + " = (" + Data.Length.ToString() + " bytes)"; } static readonly byte[] dotNetOemGuid = new byte[] { diff --git a/src/DotNet/Pdb/Managed/DbiVariable.cs b/src/DotNet/Pdb/Managed/DbiVariable.cs index 7d490f356..33c01df5d 100644 --- a/src/DotNet/Pdb/Managed/DbiVariable.cs +++ b/src/DotNet/Pdb/Managed/DbiVariable.cs @@ -5,24 +5,16 @@ namespace dnlib.DotNet.Pdb.Managed { sealed class DbiVariable : SymbolVariable { - public override string Name { - get { return name; } - } + public override string Name => name; string name; - public override PdbLocalAttributes Attributes { - get { return attributes; } - } + public override PdbLocalAttributes Attributes => attributes; PdbLocalAttributes attributes; - public override int Index { - get { return index; } - } + public override int Index => index; int index; - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { return emptyPdbCustomDebugInfos; } - } + public override PdbCustomDebugInfo[] CustomDebugInfos => emptyPdbCustomDebugInfos; static readonly PdbCustomDebugInfo[] emptyPdbCustomDebugInfos = new PdbCustomDebugInfo[0]; public void Read(IImageStream stream) { diff --git a/src/DotNet/Pdb/Managed/MsfStream.cs b/src/DotNet/Pdb/Managed/MsfStream.cs index 0ada419a6..1d4121f94 100644 --- a/src/DotNet/Pdb/Managed/MsfStream.cs +++ b/src/DotNet/Pdb/Managed/MsfStream.cs @@ -6,7 +6,7 @@ namespace dnlib.DotNet.Pdb.Managed { sealed class MsfStream { public MsfStream(IImageStream[] pages, uint length) { - byte[] buf = new byte[length]; + var buf = new byte[length]; int offset = 0; foreach (var page in pages) { page.Position = 0; @@ -18,4 +18,4 @@ public MsfStream(IImageStream[] pages, uint length) { public IImageStream Content { get; set; } } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/PdbAddress.cs b/src/DotNet/Pdb/Managed/PdbAddress.cs index 1c884c48e..2530a7ed3 100644 --- a/src/DotNet/Pdb/Managed/PdbAddress.cs +++ b/src/DotNet/Pdb/Managed/PdbAddress.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.Pdb.Managed { /// An address in the image /// [DebuggerDisplay("{Section}:{Offset}")] - struct PdbAddress : IEquatable, IComparable { + readonly struct PdbAddress : IEquatable, IComparable { /// /// Section /// @@ -26,8 +26,8 @@ struct PdbAddress : IEquatable, IComparable { /// Section /// Offset in public PdbAddress(ushort section, int offset) { - this.Section = section; - this.Offset = (uint)offset; + Section = section; + Offset = (uint)offset; } /// @@ -36,8 +36,8 @@ public PdbAddress(ushort section, int offset) { /// Section /// Offset in public PdbAddress(ushort section, uint offset) { - this.Section = section; - this.Offset = offset; + Section = section; + Offset = offset; } /// @@ -46,9 +46,7 @@ public PdbAddress(ushort section, uint offset) { /// First /// Second /// - public static bool operator <=(PdbAddress a, PdbAddress b) { - return a.CompareTo(b) <= 0; - } + public static bool operator <=(PdbAddress a, PdbAddress b) => a.CompareTo(b) <= 0; /// /// Returns true if is less than @@ -56,9 +54,7 @@ public PdbAddress(ushort section, uint offset) { /// First /// Second /// - public static bool operator <(PdbAddress a, PdbAddress b) { - return a.CompareTo(b) < 0; - } + public static bool operator <(PdbAddress a, PdbAddress b) => a.CompareTo(b) < 0; /// /// Returns true if is greater than or equal to @@ -66,9 +62,7 @@ public PdbAddress(ushort section, uint offset) { /// First /// Second /// - public static bool operator >=(PdbAddress a, PdbAddress b) { - return a.CompareTo(b) >= 0; - } + public static bool operator >=(PdbAddress a, PdbAddress b) => a.CompareTo(b) >= 0; /// /// Returns true if is greater than @@ -76,9 +70,7 @@ public PdbAddress(ushort section, uint offset) { /// First /// Second /// - public static bool operator >(PdbAddress a, PdbAddress b) { - return a.CompareTo(b) > 0; - } + public static bool operator >(PdbAddress a, PdbAddress b) => a.CompareTo(b) > 0; /// /// Returns true if is equal to @@ -86,9 +78,7 @@ public PdbAddress(ushort section, uint offset) { /// First /// Second /// - public static bool operator ==(PdbAddress a, PdbAddress b) { - return a.Equals(b); - } + public static bool operator ==(PdbAddress a, PdbAddress b) => a.Equals(b); /// /// Returns true if is not equal to @@ -96,9 +86,7 @@ public PdbAddress(ushort section, uint offset) { /// First /// Second /// - public static bool operator !=(PdbAddress a, PdbAddress b) { - return !a.Equals(b); - } + public static bool operator !=(PdbAddress a, PdbAddress b) => !a.Equals(b); /// /// Compares this instance with and returns less than 0 if it's @@ -118,10 +106,7 @@ public int CompareTo(PdbAddress other) { /// /// The other one /// true if they're equal - public bool Equals(PdbAddress other) { - return Section == other.Section && - Offset == other.Offset; - } + public bool Equals(PdbAddress other) => Section == other.Section && Offset == other.Offset; /// /// Compares this to another instance @@ -138,17 +123,13 @@ public override bool Equals(object obj) { /// Gets the hash code /// /// Hash code - public override int GetHashCode() { - return (Section << 16) ^ (int)Offset; - } + public override int GetHashCode() => (Section << 16) ^ (int)Offset; /// /// ToString() override /// /// - public override string ToString() { - return string.Format("{0:X4}:{1:X8}", Section, Offset); - } + public override string ToString() => $"{Section:X4}:{Offset:X8}"; /// /// Reads a 32-bit offset followed by a 16-bit section and creates a new diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 54504d870..8f692fb51 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -30,9 +30,7 @@ sealed class PdbReader : SymbolReader { Dictionary functions; uint entryPt; - public override PdbFileKind PdbFileKind { - get { return PdbFileKind.WindowsPDB; } - } + public override PdbFileKind PdbFileKind => PdbFileKind.WindowsPDB; /// /// The age of PDB file. @@ -43,9 +41,7 @@ public override PdbFileKind PdbFileKind { /// public Guid Guid { get; private set; } - public override void Initialize(ModuleDef module) { - this.module = module; - } + public override void Initialize(ModuleDef module) => this.module = module; /// /// Read the PDB in the specified stream. @@ -68,9 +64,7 @@ public void Read(IImageStream stream) { } } - static uint RoundUpDiv(uint value, uint divisor) { - return (value + divisor - 1) / divisor; - } + static uint RoundUpDiv(uint value, uint divisor) => (value + divisor - 1) / divisor; void ReadInternal(IImageStream stream) { stream.Position = 0; @@ -137,13 +131,11 @@ void ReadInternal(IImageStream stream) { } } - bool IsValidStreamIndex(ushort index) { - return index != STREAM_INVALID_INDEX && index < streams.Length; - } + bool IsValidStreamIndex(ushort index) => index != STREAM_INVALID_INDEX && index < streams.Length; void ReadRootDirectory(MsfStream stream, IImageStream[] pages, uint pageSize) { uint streamNum = stream.Content.ReadUInt32(); - uint[] streamSizes = new uint[streamNum]; + var streamSizes = new uint[streamNum]; for (int i = 0; i < streamSizes.Length; i++) streamSizes[i] = stream.Content.ReadUInt32(); @@ -193,8 +185,7 @@ void ReadNames() { } void ReadStringTable() { - uint streamId; - if (!names.TryGetValue("/names", out streamId)) + if (!names.TryGetValue("/names", out uint streamId)) throw new PdbException("String table not found"); var stream = streams[streamId].Content; @@ -261,12 +252,10 @@ static uint ReadSizeField(IBinaryReader reader) { internal DbiDocument GetDocument(uint nameId) { var name = strings[nameId]; - DbiDocument doc; - if (!documents.TryGetValue(name, out doc)) { + if (!documents.TryGetValue(name, out var doc)) { doc = new DbiDocument(name); - uint streamId; - if (names.TryGetValue("/src/files/" + name, out streamId)) + if (names.TryGetValue("/src/files/" + name, out uint streamId)) doc.Read(streams[streamId].Content); documents.Add(name, doc); } @@ -327,8 +316,7 @@ internal static string ReadCString(IImageStream stream) { } public override SymbolMethod GetMethod(MethodDef method, int version) { - DbiFunction symMethod; - if (functions.TryGetValue(method.MDToken.ToInt32(), out symMethod)) + if (functions.TryGetValue(method.MDToken.ToInt32(), out var symMethod)) return symMethod; return null; } @@ -347,9 +335,7 @@ public override IList Documents { } volatile SymbolDocument[] documentsResult; - public override int UserEntryPoint { - get { return (int)entryPt; } - } + public override int UserEntryPoint => (int)entryPt; internal void GetCustomDebugInfos(DbiFunction symMethod, MethodDef method, CilBody body, IList result) { const string CDI_NAME = "MD2"; diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs index 1865e7dbc..9bc5d2ae2 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs @@ -15,9 +15,7 @@ static class SymbolReaderCreator { /// Path to assembly /// A new instance or null if there's no PDB /// file. - public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { - return Create(Path.ChangeExtension(assemblyFileName, "pdb")); - } + public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) => Create(Path.ChangeExtension(assemblyFileName, "pdb")); /// /// Creates a new instance @@ -25,18 +23,14 @@ public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { /// Path to PDB file /// A new instance or null if there's no PDB /// file on disk. - public static SymbolReader Create(string pdbFileName) { - return Create(ImageStreamUtils.OpenImageStream(pdbFileName)); - } + public static SymbolReader Create(string pdbFileName) => Create(ImageStreamUtils.OpenImageStream(pdbFileName)); /// /// Creates a new instance /// /// PDB file data /// A new instance or null. - public static SymbolReader Create(byte[] pdbData) { - return Create(MemoryImageStream.Create(pdbData)); - } + public static SymbolReader Create(byte[] pdbData) => Create(MemoryImageStream.Create(pdbData)); /// /// Creates a new instance diff --git a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs index 9ad8375f4..9103a1e28 100644 --- a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs +++ b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs @@ -7,17 +7,14 @@ namespace dnlib.DotNet.Pdb { static class ManagedSymbolReaderCreator { - public static SymbolReader CreateFromAssemblyFile(IMetaData metaData, string assemblyFileName) { - return Create(metaData, Path.ChangeExtension(assemblyFileName, "pdb")); - } + public static SymbolReader CreateFromAssemblyFile(IMetaData metaData, string assemblyFileName) => + Create(metaData, Path.ChangeExtension(assemblyFileName, "pdb")); - public static SymbolReader Create(IMetaData metaData, string pdbFileName) { - return Create(metaData, ImageStreamUtils.OpenImageStream(pdbFileName)); - } + public static SymbolReader Create(IMetaData metaData, string pdbFileName) => + Create(metaData, ImageStreamUtils.OpenImageStream(pdbFileName)); - public static SymbolReader Create(IMetaData metaData, byte[] pdbData) { - return Create(metaData, MemoryImageStream.Create(pdbData)); - } + public static SymbolReader Create(IMetaData metaData, byte[] pdbData) => + Create(metaData, MemoryImageStream.Create(pdbData)); public static SymbolReader Create(IMetaData metaData, IImageStream pdbStream) { try { @@ -55,8 +52,6 @@ static SymbolReader CreateCore(IImageStream pdbStream) { return null; } - internal static SymbolReader Create(IMetaData metaData) { - return Portable.SymbolReaderCreator.TryCreate(metaData); - } + internal static SymbolReader Create(IMetaData metaData) => Portable.SymbolReaderCreator.TryCreate(metaData); } } diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs index 2f5cb4ca1..bd52a0386 100644 --- a/src/DotNet/Pdb/PdbConstant.cs +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -21,24 +21,24 @@ public sealed class PdbConstant : IHasCustomDebugInformation { /// Gets/sets the name /// public string Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets/sets the type of the constant /// public TypeSig Type { - get { return type; } - set { type = value; } + get => type; + set => type = value; } /// /// Gets/sets the value of the constant /// public object Value { - get { return value; } - set { this.value = value; } + get => value; + set => this.value = value; } /// @@ -60,21 +60,15 @@ public PdbConstant(string name, TypeSig type, object value) { } /// - public int HasCustomDebugInformationTag { - get { return 25; } - } + public int HasCustomDebugInformationTag => 25; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos /// - public ThreadSafe.IList CustomDebugInfos { - get { return customDebugInfos; } - } + public ThreadSafe.IList CustomDebugInfos => customDebugInfos; readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); /// diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 356eb422a..566c8ede3 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -131,23 +131,17 @@ public sealed class PdbUnknownCustomDebugInfo : PdbCustomDebugInfo { /// /// Gets the custom debug info kind /// - public override PdbCustomDebugInfoKind Kind { - get { return kind; } - } + public override PdbCustomDebugInfoKind Kind => kind; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return guid; } - } + public override Guid Guid => guid; /// /// Gets the data /// - public byte[] Data { - get { return data; } - } + public byte[] Data => data; /// /// Constructor @@ -155,10 +149,8 @@ public byte[] Data { /// Custom debug info kind /// Raw custom debug info data public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data) { - if (data == null) - throw new ArgumentNullException("data"); this.kind = kind; - this.data = data; + this.data = data ?? throw new ArgumentNullException(nameof(data)); guid = Guid.Empty; } @@ -168,10 +160,8 @@ public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data) { /// Custom debug info guid /// Raw custom debug info data public PdbUnknownCustomDebugInfo(Guid guid, byte[] data) { - if (data == null) - throw new ArgumentNullException("data"); - this.kind = PdbCustomDebugInfoKind.Unknown; - this.data = data; + kind = PdbCustomDebugInfoKind.Unknown; + this.data = data ?? throw new ArgumentNullException(nameof(data)); this.guid = guid; } } @@ -185,38 +175,28 @@ public sealed class PdbUsingGroupsCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.UsingGroups; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.UsingGroups; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets the using counts /// - public ThreadSafe.IList UsingCounts { - get { return usingCounts; } - } + public ThreadSafe.IList UsingCounts => usingCounts; /// /// Constructor /// - public PdbUsingGroupsCustomDebugInfo() { - usingCounts = ThreadSafeListCreator.Create(); - } + public PdbUsingGroupsCustomDebugInfo() => usingCounts = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PdbUsingGroupsCustomDebugInfo(int capacity) { - usingCounts = ThreadSafeListCreator.Create(capacity); - } + public PdbUsingGroupsCustomDebugInfo(int capacity) => usingCounts = ThreadSafeListCreator.Create(capacity); } /// @@ -228,23 +208,19 @@ public sealed class PdbForwardMethodInfoCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.ForwardMethodInfo; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.ForwardMethodInfo; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets/sets the referenced method /// public IMethodDefOrRef Method { - get { return method; } - set { method = value; } + get => method; + set => method = value; } /// @@ -257,9 +233,7 @@ public PdbForwardMethodInfoCustomDebugInfo() { /// Constructor /// /// The referenced method - public PdbForwardMethodInfoCustomDebugInfo(IMethodDefOrRef method) { - this.method = method; - } + public PdbForwardMethodInfoCustomDebugInfo(IMethodDefOrRef method) => this.method = method; } /// @@ -271,23 +245,19 @@ public sealed class PdbForwardModuleInfoCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.ForwardModuleInfo; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.ForwardModuleInfo; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets/sets the referenced method /// public IMethodDefOrRef Method { - get { return method; } - set { method = value; } + get => method; + set => method = value; } /// @@ -300,9 +270,7 @@ public PdbForwardModuleInfoCustomDebugInfo() { /// Constructor /// /// The referenced method - public PdbForwardModuleInfoCustomDebugInfo(IMethodDefOrRef method) { - this.method = method; - } + public PdbForwardModuleInfoCustomDebugInfo(IMethodDefOrRef method) => this.method = method; } /// @@ -312,9 +280,7 @@ public struct StateMachineHoistedLocalScope { /// /// true if it's a syntesized local ( and are both null) /// - public bool IsSynthesizedLocal { - get { return Start == null && End == null; } - } + public bool IsSynthesizedLocal => Start == null && End == null; /// /// The instruction of the first operation in the scope. Can be null if it's a synthesized local @@ -347,38 +313,28 @@ public sealed class PdbStateMachineHoistedLocalScopesCustomDebugInfo : PdbCustom /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.StateMachineHoistedLocalScopes; } - } + public override Guid Guid => CustomDebugInfoGuids.StateMachineHoistedLocalScopes; /// /// Gets the scopes /// - public ThreadSafe.IList Scopes { - get { return scopes; } - } + public ThreadSafe.IList Scopes => scopes; /// /// Constructor /// - public PdbStateMachineHoistedLocalScopesCustomDebugInfo() { - scopes = ThreadSafeListCreator.Create(); - } + public PdbStateMachineHoistedLocalScopesCustomDebugInfo() => scopes = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PdbStateMachineHoistedLocalScopesCustomDebugInfo(int capacity) { - scopes = ThreadSafeListCreator.Create(capacity); - } + public PdbStateMachineHoistedLocalScopesCustomDebugInfo(int capacity) => scopes = ThreadSafeListCreator.Create(capacity); } /// @@ -388,16 +344,12 @@ public sealed class PdbStateMachineTypeNameCustomDebugInfo : PdbCustomDebugInfo /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.StateMachineTypeName; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.StateMachineTypeName; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets/sets the state machine type @@ -414,9 +366,7 @@ public PdbStateMachineTypeNameCustomDebugInfo() { /// Constructor /// /// State machine type - public PdbStateMachineTypeNameCustomDebugInfo(TypeDef type) { - Type = type; - } + public PdbStateMachineTypeNameCustomDebugInfo(TypeDef type) => Type = type; } /// @@ -428,38 +378,28 @@ public sealed class PdbDynamicLocalsCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.DynamicLocals; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DynamicLocals; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets the dynamic locals /// - public ThreadSafe.IList Locals { - get { return locals; } - } + public ThreadSafe.IList Locals => locals; /// /// Constructor /// - public PdbDynamicLocalsCustomDebugInfo() { - locals = ThreadSafeListCreator.Create(); - } + public PdbDynamicLocalsCustomDebugInfo() => locals = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PdbDynamicLocalsCustomDebugInfo(int capacity) { - locals = ThreadSafeListCreator.Create(capacity); - } + public PdbDynamicLocalsCustomDebugInfo(int capacity) => locals = ThreadSafeListCreator.Create(capacity); } /// @@ -473,9 +413,7 @@ public sealed class PdbDynamicLocal { /// /// Gets the dynamic flags /// - public ThreadSafe.IList Flags { - get { return flags; } - } + public ThreadSafe.IList Flags => flags; /// /// Gets/sets the name of the local. The name must have at most 64 characters and no char can be NUL (0x0000). @@ -486,48 +424,39 @@ public string Name { var n = name; if (n != null) return n; - var l = local; - return l == null ? null : l.Name; + return local?.Name; } - set { name = value; } + set => name = value; } /// /// true if it's a constant and not a variable ( is null) /// - public bool IsConstant { - get { return Local == null; } - } + public bool IsConstant => Local == null; /// /// true if it's a variable ( is not null) /// - public bool IsVariable { - get { return Local != null; } - } + public bool IsVariable => Local != null; /// /// Gets/sets the local. Could be null if there's no local (it's a 'const' local). /// public Local Local { - get { return local; } - set { local = value; } + get => local; + set => local = value; } /// /// Constructor /// - public PdbDynamicLocal() { - flags = ThreadSafeListCreator.Create(); - } + public PdbDynamicLocal() => flags = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PdbDynamicLocal(int capacity) { - flags = ThreadSafeListCreator.Create(capacity); - } + public PdbDynamicLocal(int capacity) => flags = ThreadSafeListCreator.Create(capacity); } /// @@ -539,33 +468,23 @@ public sealed class PdbEditAndContinueLocalSlotMapCustomDebugInfo : PdbCustomDeb /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.EncLocalSlotMap; } - } + public override Guid Guid => CustomDebugInfoGuids.EncLocalSlotMap; /// /// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLocalSlotMap /// - public byte[] Data { - get { return data; } - } + public byte[] Data => data; /// /// Constructor /// /// Raw custom debug info data - public PdbEditAndContinueLocalSlotMapCustomDebugInfo(byte[] data) { - if (data == null) - throw new ArgumentNullException("data"); - this.data = data; - } + public PdbEditAndContinueLocalSlotMapCustomDebugInfo(byte[] data) => this.data = data ?? throw new ArgumentNullException(nameof(data)); } /// @@ -577,33 +496,23 @@ public sealed class PdbEditAndContinueLambdaMapCustomDebugInfo : PdbCustomDebugI /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.EditAndContinueLambdaMap; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueLambdaMap; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.EncLambdaAndClosureMap; } - } + public override Guid Guid => CustomDebugInfoGuids.EncLambdaAndClosureMap; /// /// Gets the data. Spec: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#EditAndContinueLambdaAndClosureMap /// - public byte[] Data { - get { return data; } - } + public byte[] Data => data; /// /// Constructor /// /// Raw custom debug info data - public PdbEditAndContinueLambdaMapCustomDebugInfo(byte[] data) { - if (data == null) - throw new ArgumentNullException("data"); - this.data = data; - } + public PdbEditAndContinueLambdaMapCustomDebugInfo(byte[] data) => this.data = data ?? throw new ArgumentNullException(nameof(data)); } /// @@ -615,38 +524,28 @@ public sealed class PdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.TupleElementNames; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TupleElementNames; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets the tuple element names /// - public ThreadSafe.IList Names { - get { return names; } - } + public ThreadSafe.IList Names => names; /// /// Constructor /// - public PdbTupleElementNamesCustomDebugInfo() { - names = ThreadSafeListCreator.Create(); - } + public PdbTupleElementNamesCustomDebugInfo() => names = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PdbTupleElementNamesCustomDebugInfo(int capacity) { - names = ThreadSafeListCreator.Create(capacity); - } + public PdbTupleElementNamesCustomDebugInfo(int capacity) => names = ThreadSafeListCreator.Create(capacity); } /// @@ -666,71 +565,60 @@ public string Name { var n = name; if (n != null) return n; - var l = local; - return l == null ? null : l.Name; + return local?.Name; } - set { name = value; } + set => name = value; } /// /// Gets/sets the local. It's null if it's a constant, and non-null if it's a variable /// public Local Local { - get { return local; } - set { local = value; } + get => local; + set => local = value; } /// /// true if it's a constant. Constants have a scope ( and ) /// - public bool IsConstant { - get { return local == null; } - } + public bool IsConstant => local == null; /// /// true if it's a variable. Variables don't have a scope ( and ) /// - public bool IsVariable { - get { return local != null; } - } + public bool IsVariable => local != null; /// /// Gets/sets the start of the scope or null. Only constants have a scope. /// public Instruction ScopeStart { - get { return scopeStart; } - set { scopeStart = value; } + get => scopeStart; + set => scopeStart = value; } /// /// Gets/sets the end of the scope or null if it has no scope or if the scope ends at the end of the body. Only constants have a scope. /// public Instruction ScopeEnd { - get { return scopeEnd; } - set { scopeEnd = value; } + get => scopeEnd; + set => scopeEnd = value; } /// /// Gets the tuple element names /// - public ThreadSafe.IList TupleElementNames { - get { return tupleElementNames; } - } + public ThreadSafe.IList TupleElementNames => tupleElementNames; /// /// Constructor /// - public PdbTupleElementNames() { - tupleElementNames = ThreadSafeListCreator.Create(); - } + public PdbTupleElementNames() => tupleElementNames = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PdbTupleElementNames(int capacity) { - tupleElementNames = ThreadSafeListCreator.Create(capacity); - } + public PdbTupleElementNames(int capacity) => tupleElementNames = ThreadSafeListCreator.Create(capacity); } /// @@ -742,38 +630,28 @@ public sealed class PortablePdbTupleElementNamesCustomDebugInfo : PdbCustomDebug /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.TupleElementNames_PortablePdb; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TupleElementNames_PortablePdb; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.TupleElementNames; } - } + public override Guid Guid => CustomDebugInfoGuids.TupleElementNames; /// /// Gets the tuple element names /// - public ThreadSafe.IList Names { - get { return names; } - } + public ThreadSafe.IList Names => names; /// /// Constructor /// - public PortablePdbTupleElementNamesCustomDebugInfo() { - names = ThreadSafeListCreator.Create(); - } + public PortablePdbTupleElementNamesCustomDebugInfo() => names = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Initial capacity of - public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) { - names = ThreadSafeListCreator.Create(capacity); - } + public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) => names = ThreadSafeListCreator.Create(capacity); } /// @@ -787,16 +665,12 @@ sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugIn /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.Unknown; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.Unknown; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob; } - } + public override Guid Guid => CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob; /// /// Gets the catch handler instruction or null @@ -806,16 +680,12 @@ public override Guid Guid { /// /// Gets all async step infos /// - public ThreadSafe.IList AsyncStepInfos { - get { return asyncStepInfos; } - } + public ThreadSafe.IList AsyncStepInfos => asyncStepInfos; /// /// Constructor /// - public PdbAsyncMethodSteppingInformationCustomDebugInfo() { - asyncStepInfos = ThreadSafeListCreator.Create(); - } + public PdbAsyncMethodSteppingInformationCustomDebugInfo() => asyncStepInfos = ThreadSafeListCreator.Create(); } /// @@ -825,16 +695,12 @@ public sealed class PdbDefaultNamespaceCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.DefaultNamespace; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DefaultNamespace; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.DefaultNamespace; } - } + public override Guid Guid => CustomDebugInfoGuids.DefaultNamespace; /// /// Gets the default namespace @@ -851,9 +717,7 @@ public PdbDefaultNamespaceCustomDebugInfo() { /// Constructor /// /// Default namespace - public PdbDefaultNamespaceCustomDebugInfo(string defaultNamespace) { - Namespace = defaultNamespace; - } + public PdbDefaultNamespaceCustomDebugInfo(string defaultNamespace) => Namespace = defaultNamespace; } /// @@ -863,16 +727,12 @@ public sealed class PdbDynamicLocalVariablesCustomDebugInfo : PdbCustomDebugInfo /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.DynamicLocalVariables; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DynamicLocalVariables; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.DynamicLocalVariables; } - } + public override Guid Guid => CustomDebugInfoGuids.DynamicLocalVariables; /// /// Gets/sets the dynamic flags @@ -889,9 +749,7 @@ public PdbDynamicLocalVariablesCustomDebugInfo() { /// Constructor /// /// Dynamic flags - public PdbDynamicLocalVariablesCustomDebugInfo(bool[] flags) { - Flags = flags; - } + public PdbDynamicLocalVariablesCustomDebugInfo(bool[] flags) => Flags = flags; } /// @@ -901,16 +759,12 @@ public sealed class PdbEmbeddedSourceCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.EmbeddedSource; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EmbeddedSource; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.EmbeddedSource; } - } + public override Guid Guid => CustomDebugInfoGuids.EmbeddedSource; /// /// Gets the source code blob. @@ -931,9 +785,7 @@ public PdbEmbeddedSourceCustomDebugInfo() { /// Constructor /// /// Source code blob - public PdbEmbeddedSourceCustomDebugInfo(byte[] sourceCodeBlob) { - SourceCodeBlob = sourceCodeBlob; - } + public PdbEmbeddedSourceCustomDebugInfo(byte[] sourceCodeBlob) => SourceCodeBlob = sourceCodeBlob; } /// @@ -943,16 +795,12 @@ public sealed class PdbSourceLinkCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.SourceLink; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.SourceLink; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return CustomDebugInfoGuids.SourceLink; } - } + public override Guid Guid => CustomDebugInfoGuids.SourceLink; /// /// Gets the source link file contents @@ -969,9 +817,7 @@ public PdbSourceLinkCustomDebugInfo() { /// Constructor /// /// Source link file contents - public PdbSourceLinkCustomDebugInfo(byte[] sourceLinkBlob) { - SourceLinkBlob = sourceLinkBlob; - } + public PdbSourceLinkCustomDebugInfo(byte[] sourceLinkBlob) => SourceLinkBlob = sourceLinkBlob; } /// @@ -981,16 +827,12 @@ public sealed class PdbAsyncMethodCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.AsyncMethod; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.AsyncMethod; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; readonly ThreadSafe.IList asyncStepInfos; @@ -1008,24 +850,18 @@ public override Guid Guid { /// /// Gets all step infos used by the debugger /// - public ThreadSafe.IList StepInfos { - get { return asyncStepInfos; } - } + public ThreadSafe.IList StepInfos => asyncStepInfos; /// /// Constructor /// - public PdbAsyncMethodCustomDebugInfo() { - asyncStepInfos = ThreadSafeListCreator.Create(); - } + public PdbAsyncMethodCustomDebugInfo() => asyncStepInfos = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Default capacity for - public PdbAsyncMethodCustomDebugInfo(int stepInfosCapacity) { - asyncStepInfos = ThreadSafeListCreator.Create(stepInfosCapacity); - } + public PdbAsyncMethodCustomDebugInfo(int stepInfosCapacity) => asyncStepInfos = ThreadSafeListCreator.Create(stepInfosCapacity); } /// @@ -1067,16 +903,12 @@ public sealed class PdbIteratorMethodCustomDebugInfo : PdbCustomDebugInfo { /// /// Returns /// - public override PdbCustomDebugInfoKind Kind { - get { return PdbCustomDebugInfoKind.IteratorMethod; } - } + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.IteratorMethod; /// /// Gets the custom debug info guid, see /// - public override Guid Guid { - get { return Guid.Empty; } - } + public override Guid Guid => Guid.Empty; /// /// Gets the kickoff method @@ -1093,8 +925,6 @@ public PdbIteratorMethodCustomDebugInfo() { /// Constructor /// /// Kickoff method - public PdbIteratorMethodCustomDebugInfo(MethodDef kickoffMethod) { - KickoffMethod = kickoffMethod; - } + public PdbIteratorMethodCustomDebugInfo(MethodDef kickoffMethod) => KickoffMethod = kickoffMethod; } } diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index 234026009..f4fd7addc 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -48,21 +48,15 @@ public sealed class PdbDocument : IHasCustomDebugInformation { public byte[] CheckSum { get; set; } /// - public int HasCustomDebugInformationTag { - get { return 22; } - } + public int HasCustomDebugInformationTag => 22; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos /// - public ThreadSafe.IList CustomDebugInfos { - get { return customDebugInfos; } - } + public ThreadSafe.IList CustomDebugInfos => customDebugInfos; readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); /// @@ -77,13 +71,13 @@ public PdbDocument() { /// A instance public PdbDocument(SymbolDocument symDoc) { if (symDoc == null) - throw new ArgumentNullException("symDoc"); - this.Url = symDoc.URL; - this.Language = symDoc.Language; - this.LanguageVendor = symDoc.LanguageVendor; - this.DocumentType = symDoc.DocumentType; - this.CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId; - this.CheckSum = symDoc.CheckSum; + throw new ArgumentNullException(nameof(symDoc)); + Url = symDoc.URL; + Language = symDoc.Language; + LanguageVendor = symDoc.LanguageVendor; + DocumentType = symDoc.DocumentType; + CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId; + CheckSum = symDoc.CheckSum; foreach (var cdi in symDoc.CustomDebugInfos) customDebugInfos.Add(cdi); } @@ -98,18 +92,16 @@ public PdbDocument(SymbolDocument symDoc) { /// Checksum algorithm ID. See /// Checksum public PdbDocument(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum) { - this.Url = url; - this.Language = language; - this.LanguageVendor = languageVendor; - this.DocumentType = documentType; - this.CheckSumAlgorithmId = checkSumAlgorithmId; - this.CheckSum = checkSum; + Url = url; + Language = language; + LanguageVendor = languageVendor; + DocumentType = documentType; + CheckSumAlgorithmId = checkSumAlgorithmId; + CheckSum = checkSum; } /// - public override int GetHashCode() { - return (Url ?? string.Empty).ToUpperInvariant().GetHashCode(); - } + public override int GetHashCode() => (Url ?? string.Empty).ToUpperInvariant().GetHashCode(); /// public override bool Equals(object obj) { diff --git a/src/DotNet/Pdb/PdbImport.cs b/src/DotNet/Pdb/PdbImport.cs index aac151615..c244a6952 100644 --- a/src/DotNet/Pdb/PdbImport.cs +++ b/src/DotNet/Pdb/PdbImport.cs @@ -30,33 +30,23 @@ public PdbImportScope() { /// /// Gets all imports /// - public ThreadSafe.IList Imports { - get { return imports; } - } + public ThreadSafe.IList Imports => imports; /// /// true if is not empty /// - public bool HasImports { - get { return imports.Count > 0; } - } + public bool HasImports => imports.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 26; } - } + public int HasCustomDebugInformationTag => 26; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos /// - public ThreadSafe.IList CustomDebugInfos { - get { return customDebugInfos; } - } + public ThreadSafe.IList CustomDebugInfos => customDebugInfos; readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); } @@ -97,9 +87,7 @@ public sealed class PdbImportNamespace : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.ImportNamespace; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.ImportNamespace; /// /// Gets the target namespace @@ -116,15 +104,11 @@ public PdbImportNamespace() { /// Constructor /// /// - public PdbImportNamespace(string targetNamespace) { - TargetNamespace = targetNamespace; - } + public PdbImportNamespace(string targetNamespace) => TargetNamespace = targetNamespace; internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1}", Kind, TargetNamespace); - } + string GetDebuggerString() => $"{Kind}: {TargetNamespace}"; } /// @@ -135,9 +119,7 @@ public sealed class PdbImportAssemblyNamespace : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.ImportAssemblyNamespace; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.ImportAssemblyNamespace; /// /// Gets the target assembly @@ -167,9 +149,7 @@ public PdbImportAssemblyNamespace(AssemblyRef targetAssembly, string targetNames internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1} {2}", Kind, TargetAssembly, TargetNamespace); - } + string GetDebuggerString() => $"{Kind}: {TargetAssembly} {TargetNamespace}"; } /// @@ -180,9 +160,7 @@ public sealed class PdbImportType : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.ImportType; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.ImportType; /// /// Gets the target type @@ -199,15 +177,11 @@ public PdbImportType() { /// Constructor /// /// - public PdbImportType(ITypeDefOrRef targetType) { - TargetType = targetType; - } + public PdbImportType(ITypeDefOrRef targetType) => TargetType = targetType; internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1}", Kind, TargetType); - } + string GetDebuggerString() => $"{Kind}: {TargetType}"; } /// @@ -218,9 +192,7 @@ public sealed class PdbImportXmlNamespace : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.ImportXmlNamespace; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.ImportXmlNamespace; /// /// Gets the alias @@ -250,9 +222,7 @@ public PdbImportXmlNamespace(string alias, string targetNamespace) { internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1} = {2}", Kind, Alias, TargetNamespace); - } + string GetDebuggerString() => $"{Kind}: {Alias} = {TargetNamespace}"; } /// @@ -263,9 +233,7 @@ public sealed class PdbImportAssemblyReferenceAlias : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.ImportAssemblyReferenceAlias; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.ImportAssemblyReferenceAlias; /// /// Gets the alias @@ -282,15 +250,11 @@ public PdbImportAssemblyReferenceAlias() { /// Constructor /// /// - public PdbImportAssemblyReferenceAlias(string alias) { - Alias = alias; - } + public PdbImportAssemblyReferenceAlias(string alias) => Alias = alias; internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1}", Kind, Alias); - } + string GetDebuggerString() => $"{Kind}: {Alias}"; } /// @@ -301,9 +265,7 @@ public sealed class PdbAliasAssemblyReference : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.AliasAssemblyReference; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.AliasAssemblyReference; /// /// Gets the alias @@ -333,9 +295,7 @@ public PdbAliasAssemblyReference(string alias, AssemblyRef targetAssembly) { internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1} = {2}", Kind, Alias, TargetAssembly); - } + string GetDebuggerString() => $"{Kind}: {Alias} = {TargetAssembly}"; } /// @@ -346,9 +306,7 @@ public sealed class PdbAliasNamespace : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.AliasNamespace; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.AliasNamespace; /// /// Gets the alias @@ -378,9 +336,7 @@ public PdbAliasNamespace(string alias, string targetNamespace) { internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1} = {2}", Kind, Alias, TargetNamespace); - } + string GetDebuggerString() => $"{Kind}: {Alias} = {TargetNamespace}"; } /// @@ -391,9 +347,7 @@ public sealed class PdbAliasAssemblyNamespace : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.AliasAssemblyNamespace; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.AliasAssemblyNamespace; /// /// Gets the alias @@ -430,9 +384,7 @@ public PdbAliasAssemblyNamespace(string alias, AssemblyRef targetAssembly, strin internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1} = {2} {3}", Kind, Alias, TargetAssembly, TargetNamespace); - } + string GetDebuggerString() => $"{Kind}: {Alias} = {TargetAssembly} {TargetNamespace}"; } /// @@ -443,9 +395,7 @@ public sealed class PdbAliasType : PdbImport { /// /// Returns /// - public sealed override PdbImportDefinitionKind Kind { - get { return PdbImportDefinitionKind.AliasType; } - } + public sealed override PdbImportDefinitionKind Kind => PdbImportDefinitionKind.AliasType; /// /// Gets the alias @@ -475,8 +425,6 @@ public PdbAliasType(string alias, ITypeDefOrRef targetType) { internal sealed override void PreventNewClasses() { } - string GetDebuggerString() { - return string.Format("{0}: {1} = {2}", Kind, Alias, TargetType); - } + string GetDebuggerString() => $"{Kind}: {Alias} = {TargetType}"; } } diff --git a/src/DotNet/Pdb/PdbLocal.cs b/src/DotNet/Pdb/PdbLocal.cs index 92edca881..6044ba9b1 100644 --- a/src/DotNet/Pdb/PdbLocal.cs +++ b/src/DotNet/Pdb/PdbLocal.cs @@ -50,15 +50,13 @@ public PdbLocal(Local local, string name, PdbLocalAttributes attributes) { /// /// Gets the index of the local /// - public int Index { - get { return Local.Index; } - } + public int Index => Local.Index; /// /// true if it should be hidden in debugger variables windows. Not all compiler generated locals have this flag set. /// public bool IsDebuggerHidden { - get { return (Attributes & PdbLocalAttributes.DebuggerHidden) != 0; } + get => (Attributes & PdbLocalAttributes.DebuggerHidden) != 0; set { if (value) Attributes |= PdbLocalAttributes.DebuggerHidden; @@ -68,21 +66,15 @@ public bool IsDebuggerHidden { } /// - public int HasCustomDebugInformationTag { - get { return 24; } - } + public int HasCustomDebugInformationTag => 24; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos /// - public ThreadSafe.IList CustomDebugInfos { - get { return customDebugInfos; } - } + public ThreadSafe.IList CustomDebugInfos => customDebugInfos; readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); } } diff --git a/src/DotNet/Pdb/PdbScope.cs b/src/DotNet/Pdb/PdbScope.cs index 53536ad4e..f75795c9f 100644 --- a/src/DotNet/Pdb/PdbScope.cs +++ b/src/DotNet/Pdb/PdbScope.cs @@ -40,44 +40,32 @@ public PdbScope() { /// /// Gets all child scopes /// - public ThreadSafe.IList Scopes { - get { return scopes; } - } + public ThreadSafe.IList Scopes => scopes; /// /// true if is not empty /// - public bool HasScopes { - get { return scopes.Count > 0; } - } + public bool HasScopes => scopes.Count > 0; /// /// Gets all locals in this scope /// - public ThreadSafe.IList Variables { - get { return locals; } - } + public ThreadSafe.IList Variables => locals; /// /// true if is not empty /// - public bool HasVariables { - get { return locals.Count > 0; } - } + public bool HasVariables => locals.Count > 0; /// /// Gets all namespaces (Windows PDBs). Portable PDBs use /// - public ThreadSafe.IList Namespaces { - get { return namespaces; } - } + public ThreadSafe.IList Namespaces => namespaces; /// /// true if is not empty /// - public bool HasNamespaces { - get { return namespaces.Count > 0; } - } + public bool HasNamespaces => namespaces.Count > 0; /// /// Gets/sets the import scope (Portable PDBs). Windows PDBs use @@ -87,33 +75,23 @@ public bool HasNamespaces { /// /// Gets all constants /// - public ThreadSafe.IList Constants { - get { return constants; } - } + public ThreadSafe.IList Constants => constants; /// /// true if is not empty /// - public bool HasConstants { - get { return constants.Count > 0; } - } + public bool HasConstants => constants.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 23; } - } + public int HasCustomDebugInformationTag => 23; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos /// - public ThreadSafe.IList CustomDebugInfos { - get { return customDebugInfos; } - } + public ThreadSafe.IList CustomDebugInfos => customDebugInfos; readonly ThreadSafe.IList customDebugInfos = ThreadSafeListCreator.Create(); } } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 0321bf362..b82b93ea5 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -32,8 +32,8 @@ public sealed class PdbState { /// Gets/sets the user entry point method. /// public MethodDef UserEntryPoint { - get { return userEntryPoint; } - set { userEntryPoint = value; } + get => userEntryPoint; + set => userEntryPoint = value; } /// @@ -74,8 +74,8 @@ public bool HasDocuments { /// PDB file kind public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { if (module == null) - throw new ArgumentNullException("module"); - this.compiler = CalculateCompiler(module); + throw new ArgumentNullException(nameof(module)); + compiler = CalculateCompiler(module); PdbFileKind = pdbFileKind; } @@ -85,16 +85,14 @@ public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { /// A instance /// Owner module public PdbState(SymbolReader reader, ModuleDefMD module) { - if (reader == null) - throw new ArgumentNullException("reader"); if (module == null) - throw new ArgumentNullException("module"); - this.reader = reader; + throw new ArgumentNullException(nameof(module)); + this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); reader.Initialize(module); PdbFileKind = reader.PdbFileKind; - this.compiler = CalculateCompiler(module); + compiler = CalculateCompiler(module); - this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; + userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; foreach (var doc in reader.Documents) Add_NoLock(new PdbDocument(doc)); @@ -117,8 +115,7 @@ public PdbDocument Add(PdbDocument doc) { } PdbDocument Add_NoLock(PdbDocument doc) { - PdbDocument orig; - if (docDict.TryGetValue(doc, out orig)) + if (docDict.TryGetValue(doc, out var orig)) return orig; docDict.Add(doc, doc); return doc; @@ -149,8 +146,7 @@ public PdbDocument GetExisting(PdbDocument doc) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - PdbDocument orig; - docDict.TryGetValue(doc, out orig); + docDict.TryGetValue(doc, out var orig); return orig; #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } @@ -161,9 +157,7 @@ public PdbDocument GetExisting(PdbDocument doc) { /// Removes all documents /// /// - public void RemoveAllDocuments() { - RemoveAllDocuments(false); - } + public void RemoveAllDocuments() => RemoveAllDocuments(false); /// /// Removes all documents and optionally returns them @@ -184,9 +178,7 @@ public List RemoveAllDocuments(bool returnDocs) { #endif } - internal Compiler Compiler { - get { return compiler; } - } + internal Compiler Compiler => compiler; internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { if (reader == null) diff --git a/src/DotNet/Pdb/Portable/DocumentNameReader.cs b/src/DotNet/Pdb/Portable/DocumentNameReader.cs index bad77acad..a287b8053 100644 --- a/src/DotNet/Pdb/Portable/DocumentNameReader.cs +++ b/src/DotNet/Pdb/Portable/DocumentNameReader.cs @@ -31,8 +31,7 @@ public DocumentNameReader(BlobStream blobStream) { public string ReadDocumentName(uint offset) { sb.Length = 0; using (var stream = blobStream.CreateStream(offset)) { - int sepCharsLength; - var sepChars = ReadSeparatorChar(stream, out sepCharsLength); + var sepChars = ReadSeparatorChar(stream, out int sepCharsLength); bool needSep = false; while (stream.Position < stream.Length) { if (needSep) @@ -50,8 +49,7 @@ public string ReadDocumentName(uint offset) { } string ReadDocumentNamePart(uint offset) { - string name; - if (docNamePartDict.TryGetValue(offset, out name)) + if (docNamePartDict.TryGetValue(offset, out var name)) return name; var data = blobStream.ReadNoNull(offset); name = Encoding.UTF8.GetString(data); @@ -88,9 +86,7 @@ char[] ReadSeparatorChar(IImageStream stream, out int charLength) { prevSepCharBytes[i] = b; bytes[0] = b; bool isLastByte = stream.Position + 1 == stream.Length; - int bytesUsed; - bool completed; - decoder.Convert(bytes, 0, 1, prevSepChars, 0, prevSepChars.Length, isLastByte, out bytesUsed, out prevSepCharsLength, out completed); + decoder.Convert(bytes, 0, 1, prevSepChars, 0, prevSepChars.Length, isLastByte, out int bytesUsed, out prevSepCharsLength, out bool completed); if (prevSepCharsLength > 0) break; } diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index ad41cf60d..04543bbce 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Pdb.Portable { // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#imports-blob - struct ImportScopeBlobReader { + readonly struct ImportScopeBlobReader { readonly ModuleDef module; readonly BlobStream blobStream; @@ -111,8 +111,7 @@ public void Read(uint imports, IList result) { } ITypeDefOrRef TryReadType(uint codedToken) { - uint token; - bool b = CodedToken.TypeDefOrRef.Decode(codedToken, out token); + bool b = CodedToken.TypeDefOrRef.Decode(codedToken, out uint token); Debug.Assert(b); if (!b) return null; diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index 4b1bad56d..0dad730f1 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet.Pdb.Portable { // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#imports-blob - struct ImportScopeBlobWriter { + readonly struct ImportScopeBlobWriter { readonly IWriterError helper; readonly MetaData systemMetaData; readonly BlobHeap blobHeap; @@ -34,8 +34,7 @@ uint WriteUTF8(string s) { void Write(BinaryWriter writer, IList imports) { foreach (var import in imports) { - uint rawKind; - if (!ImportDefinitionKindUtils.ToImportDefinitionKind(import.Kind, out rawKind)) { + if (!ImportDefinitionKindUtils.ToImportDefinitionKind(import.Kind, out uint rawKind)) { helper.Error("Unknown import definition kind: " + import.Kind.ToString()); return; } @@ -106,10 +105,9 @@ uint GetTypeDefOrRefEncodedToken(ITypeDefOrRef tdr) { return 0; } var token = systemMetaData.GetToken(tdr); - uint codedToken; - if (MD.CodedToken.TypeDefOrRef.Encode(token, out codedToken)) + if (MD.CodedToken.TypeDefOrRef.Encode(token, out uint codedToken)) return codedToken; - helper.Error(string.Format("Could not encode token 0x{0:X8}", token.Raw)); + helper.Error($"Could not encode token 0x{token.Raw:X8}"); return 0; } } diff --git a/src/DotNet/Pdb/Portable/ListCache.cs b/src/DotNet/Pdb/Portable/ListCache.cs index 2ba38974b..97b40b287 100644 --- a/src/DotNet/Pdb/Portable/ListCache.cs +++ b/src/DotNet/Pdb/Portable/ListCache.cs @@ -6,9 +6,7 @@ namespace dnlib.DotNet.Pdb.Portable { static class ListCache { static volatile List cachedList; - public static List AllocList() { - return Interlocked.Exchange(ref cachedList, null) ?? new List(); - } + public static List AllocList() => Interlocked.Exchange(ref cachedList, null) ?? new List(); public static void Free(ref List list) { list.Clear(); cachedList = list; diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index 53925b102..b5d2439dc 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -9,14 +9,14 @@ namespace dnlib.DotNet.Pdb.Portable { struct LocalConstantSigBlobReader { readonly ModuleDef module; readonly IImageStream reader; - /*readonly*/ GenericParamContext gpContext; + readonly GenericParamContext gpContext; RecursionCounter recursionCounter; public LocalConstantSigBlobReader(ModuleDef module, IImageStream reader, GenericParamContext gpContext) { this.module = module; this.reader = reader; this.gpContext = gpContext; - recursionCounter = default(RecursionCounter); + recursionCounter = default; } public bool Read(out TypeSig type, out object value) { @@ -243,15 +243,13 @@ bool ReadCore(out TypeSig type, out object value) { static readonly UTF8String stringDateTime = new UTF8String("DateTime"); static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String name) { - var tr = tdr as TypeRef; - if (tr != null) { + if (tdr is TypeRef tr) { @namespace = tr.Namespace; name = tr.Name; return true; } - var td = tdr as TypeDef; - if (td != null) { + if (tdr is TypeDef td) { @namespace = td.Namespace; name = td.Name; return true; diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index 5b088e907..8915fcc9d 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -6,7 +6,7 @@ using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Portable { - struct LocalConstantSigBlobWriter { + readonly struct LocalConstantSigBlobWriter { readonly IWriterError helper; readonly MetaData systemMetaData; @@ -80,7 +80,7 @@ void Write(BinaryWriter writer, TypeSig type, object value) { var tdr = ((ValueTypeSig)type).TypeDefOrRef; var td = tdr.ResolveTypeDef(); if (td == null) - helper.Error(string.Format("Couldn't resolve type 0x{0:X8}", tdr == null ? 0 : tdr.MDToken.Raw)); + helper.Error($"Couldn't resolve type 0x{tdr?.MDToken.Raw ?? 0:X8}"); else if (td.IsEnum) { var underlyingType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers(); switch (underlyingType.GetElementType()) { @@ -106,9 +106,8 @@ void Write(BinaryWriter writer, TypeSig type, object value) { } else { WriteTypeDefOrRef(writer, tdr); - UTF8String ns, name; bool valueWritten = false; - if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib()) { + if (GetName(tdr, out var ns, out var name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib()) { if (name == stringDecimal) { if (value is decimal) { var bits = decimal.GetBits((decimal)value); @@ -188,15 +187,13 @@ void Write(BinaryWriter writer, TypeSig type, object value) { static readonly UTF8String stringDateTime = new UTF8String("DateTime"); static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String name) { - var tr = tdr as TypeRef; - if (tr != null) { + if (tdr is TypeRef tr) { @namespace = tr.Namespace; name = tr.Name; return true; } - var td = tdr as TypeDef; - if (td != null) { + if (tdr is TypeDef td) { @namespace = td.Namespace; name = td.Name; return true; @@ -305,8 +302,7 @@ void WritePrimitiveValue(BinaryWriter writer, ElementType et, object value) { } void WriteTypeDefOrRef(BinaryWriter writer, ITypeDefOrRef tdr) { - uint codedToken; - if (!MD.CodedToken.TypeDefOrRef.Encode(systemMetaData.GetToken(tdr), out codedToken)) { + if (!MD.CodedToken.TypeDefOrRef.Encode(systemMetaData.GetToken(tdr), out uint codedToken)) { helper.Error("Couldn't encode a TypeDefOrRef"); return; } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index c3c043837..5521f2331 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -11,7 +11,7 @@ using dnlib.IO; namespace dnlib.DotNet.Pdb.Portable { - struct PortablePdbCustomDebugInfoReader : IDisposable { + readonly struct PortablePdbCustomDebugInfoReader : IDisposable { public static PdbCustomDebugInfo Read(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, Guid kind, byte[] data) { try { using (var reader = new PortablePdbCustomDebugInfoReader(module, typeOpt, bodyOpt, gpContext, MemoryImageStream.Create(data))) { @@ -126,9 +126,7 @@ PdbCustomDebugInfo ReadDynamicLocalVariables(long recPosEnd) { return new PdbDynamicLocalVariablesCustomDebugInfo(flags); } - PdbCustomDebugInfo ReadEmbeddedSource() { - return new PdbEmbeddedSourceCustomDebugInfo(reader.ReadRemainingBytes()); - } + PdbCustomDebugInfo ReadEmbeddedSource() => new PdbEmbeddedSourceCustomDebugInfo(reader.ReadRemainingBytes()); PdbCustomDebugInfo ReadEncLambdaAndClosureMap(long recPosEnd) { var data = reader.ReadBytes((int)(recPosEnd - reader.Position)); @@ -140,9 +138,7 @@ PdbCustomDebugInfo ReadEncLocalSlotMap(long recPosEnd) { return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); } - PdbCustomDebugInfo ReadSourceLink() { - return new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); - } + PdbCustomDebugInfo ReadSourceLink() => new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { if (bodyOpt == null) @@ -223,8 +219,6 @@ static Instruction GetInstruction(MethodDef method, uint offset) { return null; } - public void Dispose() { - reader.Dispose(); - } + public void Dispose() => reader.Dispose(); } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index f8038d6bf..dfd2a52ee 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.Pdb.Portable { interface IPortablePdbCustomDebugInfoWriterHelper : IWriterError { } - struct PortablePdbCustomDebugInfoWriter { + readonly struct PortablePdbCustomDebugInfoWriter { readonly IPortablePdbCustomDebugInfoWriterHelper helper; readonly SerializerMethodContext methodContext; readonly MetaData systemMetaData; @@ -25,8 +25,8 @@ public static byte[] Write(IPortablePdbCustomDebugInfoWriterHelper helper, Seria this.helper = helper; this.methodContext = methodContext; this.systemMetaData = systemMetaData; - this.outStream = context.OutStream; - this.writer = context.Writer; + outStream = context.OutStream; + writer = context.Writer; outStream.SetLength(0); outStream.Position = 0; } diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index f5ff1068c..f6f370e6b 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -17,17 +17,9 @@ sealed class PortablePdbReader : SymbolReader { readonly IMetaData pdbMetaData; SymbolDocument[] documents; - public override PdbFileKind PdbFileKind { - get { return pdbFileKind; } - } - - public override int UserEntryPoint { - get { return pdbMetaData.PdbStream.EntryPoint.ToInt32(); } - } - - public override IList Documents { - get { return documents; } - } + public override PdbFileKind PdbFileKind => pdbFileKind; + public override int UserEntryPoint => pdbMetaData.PdbStream.EntryPoint.ToInt32(); + public override IList Documents => documents; public PortablePdbReader(IImageStream pdbStream, PdbFileKind pdbFileKind) { this.pdbFileKind = pdbFileKind; @@ -53,8 +45,7 @@ SymbolDocument[] ReadDocuments() { var custInfos = ListCache.AllocList(); var gpContext = new GenericParamContext(); for (int i = 0; i < docs.Length; i++) { - uint nameOffset, hashAlgorithmIndex, hashOffset; - uint languageIndex = pdbMetaData.TablesStream.ReadDocumentRow2((uint)i + 1, out nameOffset, out hashAlgorithmIndex, out hashOffset); + uint languageIndex = pdbMetaData.TablesStream.ReadDocumentRow2((uint)i + 1, out uint nameOffset, out uint hashAlgorithmIndex, out uint hashOffset); var url = nameReader.ReadDocumentName(nameOffset); var language = pdbMetaData.GuidStream.Read(languageIndex) ?? Guid.Empty; var languageVendor = GetLanguageVendor(language); @@ -114,8 +105,7 @@ int GetKickoffMethod(uint methodRid) { SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { if (!pdbMetaData.TablesStream.MethodDebugInformationTable.IsValidRID(methodRid)) return null; - uint documentRid; - uint sequencePointsOffset = pdbMetaData.TablesStream.ReadMethodDebugInformationRow2(methodRid, out documentRid); + uint sequencePointsOffset = pdbMetaData.TablesStream.ReadMethodDebugInformationRow2(methodRid, out uint documentRid); if (sequencePointsOffset == 0) return null; @@ -125,8 +115,7 @@ SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { if (documentRid == 0) documentRid = seqPointsStream.ReadCompressedUInt32(); - SymbolDocument document; - TryGetSymbolDocument(documentRid, out document); + TryGetSymbolDocument(documentRid, out var document); uint ilOffset = uint.MaxValue; int line = -1, column = 0; @@ -210,9 +199,8 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { var importScopeBlobReader = new ImportScopeBlobReader(module, pdbMetaData.BlobStream); for (int i = 0; i < scopesRidList.Count; i++) { var rid = scopesRidList[i]; - uint importScope, variableList, constantList, startOffset; int token = new MDToken(Table.LocalScope, rid).ToInt32(); - uint length = pdbMetaData.TablesStream.ReadLocalScopeRow2(rid, out importScope, out variableList, out constantList, out startOffset); + uint length = pdbMetaData.TablesStream.ReadLocalScopeRow2(rid, out uint importScope, out uint variableList, out uint constantList, out uint startOffset); uint endOffset = startOffset + length; SymbolScopeImpl parent = null; @@ -237,8 +225,7 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { parent.childrenList.Add(scope); scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, importScope, gpContext); - uint variableListEnd, constantListEnd; - GetEndOfLists(rid, out variableListEnd, out constantListEnd); + GetEndOfLists(rid, out uint variableListEnd, out uint constantListEnd); ReadVariables(scope, gpContext, variableList, variableListEnd); ReadConstants(scope, constantList, constantListEnd); } @@ -257,8 +244,7 @@ void GetEndOfLists(uint scopeRid, out uint variableListEnd, out uint constantLis constantListEnd = pdbMetaData.TablesStream.LocalConstantTable.Rows + 1; } else { - uint nextImportScope, nextVariableList, nextConstantList, nextStartOffset; - pdbMetaData.TablesStream.ReadLocalScopeRow2(nextRid, out nextImportScope, out nextVariableList, out nextConstantList, out nextStartOffset); + pdbMetaData.TablesStream.ReadLocalScopeRow2(nextRid, out uint nextImportScope, out uint nextVariableList, out uint nextConstantList, out uint nextStartOffset); variableListEnd = nextVariableList; constantListEnd = nextConstantList; } @@ -310,8 +296,7 @@ void ReadVariables(SymbolScopeImpl scope, GenericParamContext gpContext, uint va custInfos.Clear(); GetCustomDebugInfos(token, gpContext, custInfos); var customDebugInfos = custInfos.Count == 0 ? emptyPdbCustomDebugInfos : custInfos.ToArray(); - ushort attributes, index; - var nameOffset = pdbMetaData.TablesStream.ReadLocalVariableRow2(rid, out attributes, out index); + var nameOffset = pdbMetaData.TablesStream.ReadLocalVariableRow2(rid, out ushort attributes, out ushort index); var name = pdbMetaData.StringsStream.Read(nameOffset); scope.localsList.Add(new SymbolVariableImpl(name, ToSymbolVariableAttributes(attributes), index, customDebugInfos)); } @@ -344,8 +329,7 @@ void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEn internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { Debug.Assert(method.Module == module); - PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo; - GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out asyncStepInfo); + GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out var asyncStepInfo); if (asyncStepInfo != null) { var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); Debug.Assert(asyncMethod != null); @@ -382,8 +366,7 @@ PdbIteratorMethodCustomDebugInfo TryCreateIteratorMethod(ModuleDef module, int i } public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { - PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo; - GetCustomDebugInfos(token, gpContext, result, null, null, out asyncStepInfo); + GetCustomDebugInfos(token, gpContext, result, null, null, out var asyncStepInfo); Debug.Assert(asyncStepInfo == null); } @@ -393,11 +376,10 @@ void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList pdbMetaData.Dispose(); } } diff --git a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs index 1d0331b22..b1c6a674b 100644 --- a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs @@ -38,33 +38,13 @@ string GetDebuggerString() { return sb.ToString(); } - public override string URL { - get { return url; } - } - - public override Guid Language { - get { return language; } - } - - public override Guid LanguageVendor { - get { return languageVendor; } - } - - public override Guid DocumentType { - get { return documentType; } - } - - public override Guid CheckSumAlgorithmId { - get { return checkSumAlgorithmId; } - } - - public override byte[] CheckSum { - get { return checkSum; } - } - - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { return customDebugInfos; } - } + public override string URL => url; + public override Guid Language => language; + public override Guid LanguageVendor => languageVendor; + public override Guid DocumentType => documentType; + public override Guid CheckSumAlgorithmId => checkSumAlgorithmId; + public override byte[] CheckSum => checkSum; + public override PdbCustomDebugInfo[] CustomDebugInfos => customDebugInfos; public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum, PdbCustomDebugInfo[] customDebugInfos) { this.url = url; diff --git a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs index e9549f07d..10385fa6b 100644 --- a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs @@ -12,21 +12,10 @@ sealed class SymbolMethodImpl : SymbolMethod { readonly SymbolSequencePoint[] sequencePoints; readonly int kickoffMethod; - public override int Token { - get { return token; } - } - - public override SymbolScope RootScope { - get { return rootScope; } - } - - public override IList SequencePoints { - get { return sequencePoints; } - } - - public int KickoffMethod { - get { return kickoffMethod; } - } + public override int Token => token; + public override SymbolScope RootScope => rootScope; + public override IList SequencePoints => sequencePoints; + public int KickoffMethod => kickoffMethod; public SymbolMethodImpl(PortablePdbReader reader, int token, SymbolScope rootScope, SymbolSequencePoint[] sequencePoints, int kickoffMethod) { this.reader = reader; @@ -36,8 +25,7 @@ public SymbolMethodImpl(PortablePdbReader reader, int token, SymbolScope rootSco this.kickoffMethod = kickoffMethod; } - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) { + public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) => reader.GetCustomDebugInfos(this, method, body, result); - } } } diff --git a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs index 4e09d4f1d..d20185ce9 100644 --- a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs @@ -33,38 +33,15 @@ public override SymbolMethod Method { } } - public override SymbolScope Parent { - get { return parent; } - } - - public override int StartOffset { - get { return startOffset; } - } - - public override int EndOffset { - get { return endOffset; } - } - - public override IList Children { - get { return childrenList; } - } - - public override IList Locals { - get { return localsList; } - } - - public override IList Namespaces { - get { return emptySymbolNamespaces; } - } + public override SymbolScope Parent => parent; + public override int StartOffset => startOffset; + public override int EndOffset => endOffset; + public override IList Children => childrenList; + public override IList Locals => localsList; + public override IList Namespaces => emptySymbolNamespaces; static readonly SymbolNamespace[] emptySymbolNamespaces = new SymbolNamespace[0]; - - public override IList CustomDebugInfos { - get { return customDebugInfos; } - } - - public override PdbImportScope ImportScope { - get { return importScope; } - } + public override IList CustomDebugInfos => customDebugInfos; + public override PdbImportScope ImportScope => importScope; public SymbolScopeImpl(PortablePdbReader owner, SymbolScopeImpl parent, int startOffset, int endOffset, PdbCustomDebugInfo[] customDebugInfos) { this.owner = owner; @@ -96,14 +73,11 @@ public override IList GetConstants(ModuleDef module, GenericParamCo int w = 0; for (int i = 0; i < res.Length; i++) { uint rid = constantList + (uint)i; - uint nameOffset; - uint signature = constantsMetaData.TablesStream.ReadLocalConstantRow2(rid, out nameOffset); + uint signature = constantsMetaData.TablesStream.ReadLocalConstantRow2(rid, out uint nameOffset); var name = constantsMetaData.StringsStream.Read(nameOffset); using (var stream = constantsMetaData.BlobStream.CreateStream(signature)) { var localConstantSigBlobReader = new LocalConstantSigBlobReader(module, stream, gpContext); - TypeSig type; - object value; - bool b = localConstantSigBlobReader.Read(out type, out value); + bool b = localConstantSigBlobReader.Read(out var type, out object value); Debug.Assert(b); if (b) { var pdbConstant = new PdbConstant(name, type, value); diff --git a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs index 3600054bc..1762fb1b2 100644 --- a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs @@ -9,21 +9,10 @@ sealed class SymbolVariableImpl : SymbolVariable { readonly int index; readonly PdbCustomDebugInfo[] customDebugInfos; - public override string Name { - get { return name; } - } - - public override PdbLocalAttributes Attributes { - get { return attributes; } - } - - public override int Index { - get { return index; } - } - - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { return customDebugInfos; } - } + public override string Name => name; + public override PdbLocalAttributes Attributes => attributes; + public override int Index => index; + public override PdbCustomDebugInfo[] CustomDebugInfos => customDebugInfos; public SymbolVariableImpl(string name, PdbLocalAttributes attributes, int index, PdbCustomDebugInfo[] customDebugInfos) { this.name = name; diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index ace39d842..d10797892 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using dnlib.DotNet.Emit; namespace dnlib.DotNet.Pdb.Symbols { /// diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index 4068df3bf..fa4bbb207 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -17,7 +17,7 @@ namespace dnlib.DotNet.Pdb.WindowsPdb { /// Reads custom debug infos produced by the C# and Visual Basic compilers. They're stored in PDB files /// as PDB method custom attributes with the name "MD2". /// - struct PdbCustomDebugInfoReader : IDisposable { + readonly struct PdbCustomDebugInfoReader : IDisposable { /// /// Reads custom debug info /// @@ -338,8 +338,6 @@ Instruction GetInstruction(uint offset) { return null; } - public void Dispose() { - reader.Dispose(); - } + public void Dispose() => reader.Dispose(); } } diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs index cbdce637e..93def5bef 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs @@ -54,12 +54,12 @@ public static byte[] Write(MetaData metaData, MethodDef method, PdbCustomDebugIn PdbCustomDebugInfoWriter(MetaData metaData, MethodDef method, PdbCustomDebugInfoWriterContext context) { this.metaData = metaData; this.method = method; - this.logger = context.Logger; - this.memoryStream = context.MemoryStream; - this.writer = context.Writer; - this.instructionToOffsetDict = context.InstructionToOffsetDict; - this.bodySize = 0; - this.instructionToOffsetDictInitd = false; + logger = context.Logger; + memoryStream = context.MemoryStream; + writer = context.Writer; + instructionToOffsetDict = context.InstructionToOffsetDict; + bodySize = 0; + instructionToOffsetDictInitd = false; memoryStream.SetLength(0); memoryStream.Position = 0; } @@ -90,16 +90,13 @@ uint GetInstructionOffset(Instruction instr, bool nullIsEndOfMethod) { Error("Instruction is null"); return uint.MaxValue; } - uint offset; - if (instructionToOffsetDict.TryGetValue(instr, out offset)) + if (instructionToOffsetDict.TryGetValue(instr, out uint offset)) return offset; Error("Instruction is missing in body but it's still being referenced by PDB data. Method {0} (0x{1:X8}), instruction: {2}", method, method.MDToken.Raw, instr); return uint.MaxValue; } - void Error(string message, params object[] args) { - logger.Log(this, LoggerEvent.Error, message, args); - } + void Error(string message, params object[] args) => logger.Log(this, LoggerEvent.Error, message, args); byte[] Write(IList customDebugInfos) { if (customDebugInfos.Count == 0) @@ -383,8 +380,7 @@ uint GetMethodToken(IMethodDefOrRef method) { return 0; } - var md = method as MethodDef; - if (md != null) { + if (method is MethodDef md) { uint rid = metaData.GetRid(md); if (rid == 0) { Error("Method {0} ({1:X8}) is not defined in this module ({2})", method, method.MDToken.Raw, metaData.Module); @@ -393,8 +389,7 @@ uint GetMethodToken(IMethodDefOrRef method) { return new MDToken(md.MDToken.Table, rid).Raw; } - var mr = method as MemberRef; - if (mr != null && mr.IsMethodRef) + if (method is MemberRef mr && mr.IsMethodRef) return metaData.GetToken(mr).Raw; Error("Not a method"); diff --git a/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs b/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs index abb838ac4..ccaed2270 100644 --- a/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs +++ b/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs @@ -12,9 +12,7 @@ static class SymbolWriterCreator { /// /// PDB file name /// A new instance - public static ISymbolWriter2 Create(string pdbFileName) { - return Dss.SymbolWriterCreator.Create(pdbFileName); - } + public static ISymbolWriter2 Create(string pdbFileName) => Dss.SymbolWriterCreator.Create(pdbFileName); /// /// Creates a new instance @@ -22,8 +20,6 @@ public static ISymbolWriter2 Create(string pdbFileName) { /// PDB output stream /// PDB file name /// A new instance - public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) { - return Dss.SymbolWriterCreator.Create(pdbStream, pdbFileName); - } + public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) => Dss.SymbolWriterCreator.Create(pdbStream, pdbFileName); } } diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 2d9b9cd7a..776d974ce 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -37,14 +37,12 @@ public sealed class WindowsPdbWriter : IDisposable { /// Meta data public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaData) : this(pdbState, metaData) { - if (writer == null) - throw new ArgumentNullException("writer"); if (pdbState == null) - throw new ArgumentNullException("pdbState"); + throw new ArgumentNullException(nameof(pdbState)); if (metaData == null) - throw new ArgumentNullException("metaData"); - this.writer = writer; - this.writer3 = writer as ISymbolWriter3; + throw new ArgumentNullException(nameof(metaData)); + this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); + writer3 = writer as ISymbolWriter3; Debug.Assert(writer3 != null, "Symbol writer doesn't implement interface ISymbolWriter3"); writer.Initialize(metaData); } @@ -57,24 +55,22 @@ public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, MetaData metaD /// Meta data public WindowsPdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaData) : this(pdbState, metaData) { - if (writer == null) - throw new ArgumentNullException("writer"); if (pdbState == null) - throw new ArgumentNullException("pdbState"); + throw new ArgumentNullException(nameof(pdbState)); if (metaData == null) - throw new ArgumentNullException("metaData"); - this.writer = writer; - this.writer3 = writer; + throw new ArgumentNullException(nameof(metaData)); + this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); + writer3 = writer; writer.Initialize(metaData); } WindowsPdbWriter(PdbState pdbState, MetaData metaData) { this.pdbState = pdbState; this.metaData = metaData; - this.module = metaData.Module; - this.instrToOffset = new Dictionary(); - this.customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); - this.localsEndScopeIncValue = pdbState.Compiler == Compiler.VisualBasic ? 1 : 0; + module = metaData.Module; + instrToOffset = new Dictionary(); + customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); + localsEndScopeIncValue = pdbState.Compiler == Compiler.VisualBasic ? 1 : 0; } /// @@ -83,8 +79,7 @@ public WindowsPdbWriter(ISymbolWriter3 writer, PdbState pdbState, MetaData metaD /// PDB document /// A instance ISymbolDocumentWriter Add(PdbDocument pdbDoc) { - ISymbolDocumentWriter docWriter; - if (pdbDocs.TryGetValue(pdbDoc, out docWriter)) + if (pdbDocs.TryGetValue(pdbDoc, out var docWriter)) return docWriter; docWriter = writer.DefineDocument(pdbDoc.Url, pdbDoc.Language, pdbDoc.LanguageVendor, pdbDoc.DocumentType); docWriter.SetCheckSum(pdbDoc.CheckSumAlgorithmId, pdbDoc.CheckSum); @@ -216,8 +211,7 @@ public CurrentMethod(WindowsPdbWriter pdbWriter, MethodDef method, Dictionary cdiBuilder) { WriteScope(ref info, scope, 0); } - PdbAsyncMethodCustomDebugInfo asyncMethod; - GetPseudoCustomDebugInfos(method.CustomDebugInfos, cdiBuilder, out asyncMethod); + GetPseudoCustomDebugInfos(method.CustomDebugInfos, cdiBuilder, out var asyncMethod); if (cdiBuilder.Count != 0) { customDebugInfoWriterContext.Logger = GetLogger(); var cdiData = PdbCustomDebugInfoWriter.Write(metaData, method, customDebugInfoWriterContext, cdiBuilder); @@ -443,24 +436,16 @@ int GetUserEntryPointToken() { /// /// Updated with new values /// Debug data - public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY idd) { - return writer.GetDebugInfo(out idd); - } + public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY idd) => writer.GetDebugInfo(out idd); /// /// Closes the PDB writer /// - public void Close() { - writer.Close(); - } + public void Close() => writer.Close(); - ILogger GetLogger() { - return Logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; - } + ILogger GetLogger() => Logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; - void Error(string message, params object[] args) { - GetLogger().Log(this, LoggerEvent.Error, message, args); - } + void Error(string message, params object[] args) => GetLogger().Log(this, LoggerEvent.Error, message, args); /// public void Dispose() { diff --git a/src/DotNet/PropertyDef.cs b/src/DotNet/PropertyDef.cs index 2da3200d7..5c694e459 100644 --- a/src/DotNet/PropertyDef.cs +++ b/src/DotNet/PropertyDef.cs @@ -27,37 +27,29 @@ public abstract class PropertyDef : IHasConstant, IHasCustomAttribute, IHasSeman #endif /// - public MDToken MDToken { - get { return new MDToken(Table.Property, rid); } - } + public MDToken MDToken => new MDToken(Table.Property, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasConstantTag { - get { return 2; } - } + public int HasConstantTag => 2; /// - public int HasCustomAttributeTag { - get { return 9; } - } + public int HasCustomAttributeTag => 9; /// - public int HasSemanticTag { - get { return 1; } - } + public int HasSemanticTag => 1; /// /// From column Property.PropFlags /// public PropertyAttributes Attributes { - get { return (PropertyAttributes)attributes; } - set { attributes = (int)value; } + get => (PropertyAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -66,8 +58,8 @@ public PropertyAttributes Attributes { /// From column Property.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -76,8 +68,8 @@ public UTF8String Name { /// From column Property.Type /// public CallingConventionSig Type { - get { return type; } - set { type = value; } + get => type; + set => type = value; } /// protected CallingConventionSig type; @@ -119,14 +111,10 @@ void InitializeConstant() { } /// Called to initialize - protected virtual Constant GetConstant_NoLock() { - return null; - } + protected virtual Constant GetConstant_NoLock() => null; /// Reset - protected void ResetConstant() { - constant_isInitialized = false; - } + protected void ResetConstant() => constant_isInitialized = false; /// /// Gets all custom attributes @@ -141,19 +129,14 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public int HasCustomDebugInformationTag { - get { return 9; } - } + public int HasCustomDebugInformationTag => 9; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -168,9 +151,8 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Gets/sets the first getter method. Writing null will clear all get methods. @@ -276,40 +258,29 @@ protected virtual void InitializePropertyMethods_NoLock() { protected ThreadSafe.IList otherMethods; /// Reset , , - protected void ResetMethods() { - otherMethods = null; - } + protected void ResetMethods() => otherMethods = null; /// /// true if there are no methods attached to this property /// - public bool IsEmpty { - get { - // The first property access initializes the other fields we access here - return GetMethods.Count == 0 && - setMethods.Count == 0 && - otherMethods.Count == 0; - } - } + public bool IsEmpty => + // The first property access initializes the other fields we access here + GetMethods.Count == 0 && + setMethods.Count == 0 && + otherMethods.Count == 0; /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// /// true if is not empty /// - public bool HasOtherMethods { - get { return OtherMethods.Count > 0; } - } + public bool HasOtherMethods => OtherMethods.Count > 0; /// /// true if is not null /// - public bool HasConstant { - get { return Constant != null; } - } + public bool HasConstant => Constant != null; /// /// Gets the constant element type or if there's no constant @@ -325,15 +296,15 @@ public ElementType ElementType { /// Gets/sets the property sig /// public PropertySig PropertySig { - get { return type as PropertySig; } - set { type = value; } + get => type as PropertySig; + set => type = value; } /// /// Gets/sets the declaring type (owner type) /// public TypeDef DeclaringType { - get { return declaringType2; } + get => declaringType2; set { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) @@ -346,9 +317,7 @@ public TypeDef DeclaringType { } /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return declaringType2; } - } + ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; /// /// Called by and should normally not be called by any user @@ -356,81 +325,33 @@ ITypeDefOrRef IMemberRef.DeclaringType { /// declaring type without inserting it in the declaring type's method list. /// public TypeDef DeclaringType2 { - get { return declaringType2; } - set { declaringType2 = value; } + get => declaringType2; + set => declaringType2 = value; } /// protected TypeDef declaringType2; /// - public ModuleDef Module { - get { - var dt = declaringType2; - return dt == null ? null : dt.Module; - } - } + public ModuleDef Module => declaringType2?.Module; /// /// Gets the full name of the property /// - public string FullName { - get { - var dt = declaringType2; - return FullNameCreator.PropertyFullName(dt == null ? null : dt.FullName, name, type, null, null); - } - } - - bool IIsTypeOrMethod.IsType { - get { return false; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return true; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + public string FullName => FullNameCreator.PropertyFullName(declaringType2?.FullName, name, type, null, null); + + bool IIsTypeOrMethod.IsType => false; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => true; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// /// Set or clear flags in @@ -460,30 +381,28 @@ void ModifyAttributes(bool set, PropertyAttributes flags) { /// Gets/sets the bit /// public bool IsSpecialName { - get { return ((PropertyAttributes)attributes & PropertyAttributes.SpecialName) != 0; } - set { ModifyAttributes(value, PropertyAttributes.SpecialName); } + get => ((PropertyAttributes)attributes & PropertyAttributes.SpecialName) != 0; + set => ModifyAttributes(value, PropertyAttributes.SpecialName); } /// /// Gets/sets the bit /// public bool IsRuntimeSpecialName { - get { return ((PropertyAttributes)attributes & PropertyAttributes.RTSpecialName) != 0; } - set { ModifyAttributes(value, PropertyAttributes.RTSpecialName); } + get => ((PropertyAttributes)attributes & PropertyAttributes.RTSpecialName) != 0; + set => ModifyAttributes(value, PropertyAttributes.RTSpecialName); } /// /// Gets/sets the bit /// public bool HasDefault { - get { return ((PropertyAttributes)attributes & PropertyAttributes.HasDefault) != 0; } - set { ModifyAttributes(value, PropertyAttributes.HasDefault); } + get => ((PropertyAttributes)attributes & PropertyAttributes.HasDefault) != 0; + set => ModifyAttributes(value, PropertyAttributes.HasDefault); } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -521,8 +440,8 @@ public PropertyDefUser(UTF8String name, PropertySig sig) /// Flags public PropertyDefUser(UTF8String name, PropertySig sig, PropertyAttributes flags) { this.name = name; - this.type = sig; - this.attributes = (int)flags; + type = sig; + attributes = (int)flags; } } @@ -536,14 +455,10 @@ sealed class PropertyDefMD : PropertyDef, IMDTokenProviderMD { readonly uint origRid; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// - protected override Constant GetConstant_NoLock() { - return readerModule.ResolveConstant(readerModule.MetaData.GetConstantRid(Table.Property, origRid)); - } + protected override Constant GetConstant_NoLock() => readerModule.ResolveConstant(readerModule.MetaData.GetConstantRid(Table.Property, origRid)); /// protected override void InitializeCustomAttributes() { @@ -571,15 +486,14 @@ public PropertyDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.PropertyTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("Property rid {0} does not exist", rid)); + throw new BadImageFormatException($"Property rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name; - uint type = readerModule.TablesStream.ReadPropertyRow(origRid, out this.attributes, out name); + uint type = readerModule.TablesStream.ReadPropertyRow(origRid, out attributes, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); - this.declaringType2 = readerModule.GetOwnerType(this); + declaringType2 = readerModule.GetOwnerType(this); this.type = readerModule.ReadSignature(type, new GenericParamContext(declaringType2)); } diff --git a/src/DotNet/PublicKey.cs b/src/DotNet/PublicKey.cs index e941dacfb..ac4f832b2 100644 --- a/src/DotNet/PublicKey.cs +++ b/src/DotNet/PublicKey.cs @@ -89,8 +89,6 @@ public override bool Equals(object obj) { } /// - public override int GetHashCode() { - return Utils.GetHashCode(Data); - } + public override int GetHashCode() => Utils.GetHashCode(Data); } } diff --git a/src/DotNet/PublicKeyBase.cs b/src/DotNet/PublicKeyBase.cs index 40490e724..5bde2e721 100644 --- a/src/DotNet/PublicKeyBase.cs +++ b/src/DotNet/PublicKeyBase.cs @@ -13,30 +13,24 @@ public abstract class PublicKeyBase { /// /// Returns true if is null or empty /// - public bool IsNullOrEmpty { - get { return IsNullOrEmpty_NoLock; } - } + public bool IsNullOrEmpty => IsNullOrEmpty_NoLock; /// /// The unlocked version of . /// - protected bool IsNullOrEmpty_NoLock { - get { return data == null || data.Length == 0; } - } + protected bool IsNullOrEmpty_NoLock => data == null || data.Length == 0; /// /// Returns true if is null /// - public bool IsNull { - get { return Data == null; } - } + public bool IsNull => Data == null; /// /// Gets/sets key data /// public virtual byte[] Data { - get { return data; } - set { data = value; } + get => data; + set => data = value; } /// @@ -54,18 +48,14 @@ protected PublicKeyBase() { /// Constructor /// /// Key data - protected PublicKeyBase(byte[] data) { - this.data = data; - } + protected PublicKeyBase(byte[] data) => this.data = data; /// /// Constructor /// /// Key data as a hex string or the string "null" /// to set key data to null - protected PublicKeyBase(string hexString) { - this.data = Parse(hexString); - } + protected PublicKeyBase(string hexString) => data = Parse(hexString); static byte[] Parse(string hexString) { if (hexString == null || hexString == "null") @@ -77,20 +67,16 @@ static byte[] Parse(string hexString) { /// Checks whether a public key or token is null or empty /// /// Public key or token instance - public static bool IsNullOrEmpty2(PublicKeyBase a) { - return a == null || a.IsNullOrEmpty; - } + public static bool IsNullOrEmpty2(PublicKeyBase a) => a == null || a.IsNullOrEmpty; /// /// Returns a /// /// A or a instance public static PublicKeyToken ToPublicKeyToken(PublicKeyBase pkb) { - var pkt = pkb as PublicKeyToken; - if (pkt != null) + if (pkb is PublicKeyToken pkt) return pkt; - var pk = pkb as PublicKey; - if (pk != null) + if (pkb is PublicKey pk) return pk.Token; return null; } @@ -113,9 +99,7 @@ public static int TokenCompareTo(PublicKeyBase a, PublicKeyBase b) { /// First /// Second /// true if same, false otherwise - public static bool TokenEquals(PublicKeyBase a, PublicKeyBase b) { - return TokenCompareTo(a, b) == 0; - } + public static bool TokenEquals(PublicKeyBase a, PublicKeyBase b) => TokenCompareTo(a, b) == 0; static readonly byte[] EmptyByteArray = new byte[0]; /// @@ -127,12 +111,10 @@ public static bool TokenEquals(PublicKeyBase a, PublicKeyBase b) { public static int TokenCompareTo(PublicKeyToken a, PublicKeyToken b) { if (a == b) return 0; - return TokenCompareTo(a == null ? null : a.Data, b == null ? null : b.Data); + return TokenCompareTo(a?.Data, b?.Data); } - static int TokenCompareTo(byte[] a, byte[] b) { - return Utils.CompareTo(a ?? EmptyByteArray, b ?? EmptyByteArray); - } + static int TokenCompareTo(byte[] a, byte[] b) => Utils.CompareTo(a ?? EmptyByteArray, b ?? EmptyByteArray); /// /// Checks whether two public key tokens are equal @@ -140,18 +122,14 @@ static int TokenCompareTo(byte[] a, byte[] b) { /// First /// Second /// true if same, false otherwise - public static bool TokenEquals(PublicKeyToken a, PublicKeyToken b) { - return TokenCompareTo(a, b) == 0; - } + public static bool TokenEquals(PublicKeyToken a, PublicKeyToken b) => TokenCompareTo(a, b) == 0; /// /// Gets the public key token hash code /// /// Public key or token /// The hash code - public static int GetHashCodeToken(PublicKeyBase a) { - return GetHashCode(ToPublicKeyToken(a)); - } + public static int GetHashCodeToken(PublicKeyBase a) => GetHashCode(ToPublicKeyToken(a)); /// /// Gets the public key token hash code diff --git a/src/DotNet/PublicKeyToken.cs b/src/DotNet/PublicKeyToken.cs index 3f5183576..16d744bba 100644 --- a/src/DotNet/PublicKeyToken.cs +++ b/src/DotNet/PublicKeyToken.cs @@ -8,9 +8,7 @@ public sealed class PublicKeyToken : PublicKeyBase { /// /// Gets the /// - public override PublicKeyToken Token { - get { return this; } - } + public override PublicKeyToken Token => this; /// public PublicKeyToken() @@ -38,8 +36,6 @@ public override bool Equals(object obj) { } /// - public override int GetHashCode() { - return Utils.GetHashCode(Data); - } + public override int GetHashCode() => Utils.GetHashCode(Data); } } diff --git a/src/DotNet/RecursionCounter.cs b/src/DotNet/RecursionCounter.cs index 3d428aa0a..556e79515 100644 --- a/src/DotNet/RecursionCounter.cs +++ b/src/DotNet/RecursionCounter.cs @@ -16,9 +16,7 @@ public struct RecursionCounter { /// /// Gets the recursion counter /// - public int Counter { - get { return counter; } - } + public int Counter => counter; /// /// Increments if it's not too high. ALL instance methods @@ -47,8 +45,6 @@ public void Decrement() { } /// - public override string ToString() { - return counter.ToString(); - } + public override string ToString() => counter.ToString(); } } diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index 54c2ca9e3..b1b62d0d6 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -67,9 +67,8 @@ public static ElementType GetElementType2(this Type a) { /// not a generic method definition, i.e., a MethodSpec. /// /// The method - public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) { - return mb != null && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; - } + public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => + mb != null && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; /// /// Checks whether a parameter/prop/event type should be treated as if it is really a @@ -80,21 +79,15 @@ public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) { /// /// Declaring type of method/event/property /// Parameter/property/event type - internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) { - return declaringType != null && - declaringType.IsGenericTypeDefinition && - t == declaringType; - } + internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) => + declaringType != null && declaringType.IsGenericTypeDefinition && t == declaringType; /// /// Checks whether is a type definition and not a type spec /// (eg. pointer or generic type instantiation) /// /// this - public static bool IsTypeDef(this Type type) { - return type != null && - !type.HasElementType && - (!type.IsGenericType || type.IsGenericTypeDefinition); - } + public static bool IsTypeDef(this Type type) => + type != null && !type.HasElementType && (!type.IsGenericType || type.IsGenericTypeDefinition); } } diff --git a/src/DotNet/Resolver.cs b/src/DotNet/Resolver.cs index 776d1fe45..1b5b0a0b6 100644 --- a/src/DotNet/Resolver.cs +++ b/src/DotNet/Resolver.cs @@ -17,8 +17,8 @@ public sealed class Resolver : IResolver { /// by default. /// public bool ProjectWinMDRefs { - get { return projectWinMDRefs; } - set { projectWinMDRefs = value; } + get => projectWinMDRefs; + set => projectWinMDRefs = value; } bool projectWinMDRefs = true; @@ -26,11 +26,8 @@ public bool ProjectWinMDRefs { /// Constructor /// /// The assembly resolver - public Resolver(IAssemblyResolver assemblyResolver) { - if (assemblyResolver == null) - throw new ArgumentNullException("assemblyResolver"); - this.assemblyResolver = assemblyResolver; - } + public Resolver(IAssemblyResolver assemblyResolver) => + this.assemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver)); /// public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { @@ -46,19 +43,15 @@ public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { var nonNestedResolutionScope = nonNestedTypeRef.ResolutionScope; var nonNestedModule = nonNestedTypeRef.Module; - var asmRef = nonNestedResolutionScope as AssemblyRef; - if (asmRef != null) { + if (nonNestedResolutionScope is AssemblyRef asmRef) { var asm = assemblyResolver.Resolve(asmRef, sourceModule ?? nonNestedModule); return asm == null ? null : asm.Find(typeRef) ?? ResolveExportedType(asm.Modules, typeRef, sourceModule); } - var moduleDef = nonNestedResolutionScope as ModuleDef; - if (moduleDef != null) - return moduleDef.Find(typeRef) ?? - ResolveExportedType(new ModuleDef[] { moduleDef }, typeRef, sourceModule); + if (nonNestedResolutionScope is ModuleDef moduleDef) + return moduleDef.Find(typeRef) ?? ResolveExportedType(new ModuleDef[] { moduleDef }, typeRef, sourceModule); - var moduleRef = nonNestedResolutionScope as ModuleRef; - if (moduleRef != null) { + if (nonNestedResolutionScope is ModuleRef moduleRef) { if (nonNestedModule == null) return null; if (new SigComparer().Equals(moduleRef, nonNestedModule)) @@ -115,33 +108,27 @@ public IMemberForwarded Resolve(MemberRef memberRef) { if (ProjectWinMDRefs) memberRef = WinMDHelpers.ToCLR(memberRef.Module, memberRef) ?? memberRef; var parent = memberRef.Class; - var method = parent as MethodDef; - if (method != null) + if (parent is MethodDef method) return method; - var declaringType = GetDeclaringType(memberRef, parent); - return declaringType == null ? null : declaringType.Resolve(memberRef); + return GetDeclaringType(memberRef, parent)?.Resolve(memberRef); } TypeDef GetDeclaringType(MemberRef memberRef, IMemberRefParent parent) { if (memberRef == null || parent == null) return null; - var ts = parent as TypeSpec; - if (ts != null) + if (parent is TypeSpec ts) parent = ts.ScopeType; - var declaringTypeDef = parent as TypeDef; - if (declaringTypeDef != null) + if (parent is TypeDef declaringTypeDef) return declaringTypeDef; - var declaringTypeRef = parent as TypeRef; - if (declaringTypeRef != null) + if (parent is TypeRef declaringTypeRef) return Resolve(declaringTypeRef, memberRef.Module); // A module ref is used to reference the global type of a module in the same // assembly as the current module. - var moduleRef = parent as ModuleRef; - if (moduleRef != null) { + if (parent is ModuleRef moduleRef) { var module = memberRef.Module; if (module == null) return null; @@ -157,8 +144,7 @@ TypeDef GetDeclaringType(MemberRef memberRef, IMemberRefParent parent) { return globalType; } - var method = parent as MethodDef; - if (method != null) + if (parent is MethodDef method) return method.DeclaringType; return null; diff --git a/src/DotNet/Resource.cs b/src/DotNet/Resource.cs index 7ea735132..70f0b7a45 100644 --- a/src/DotNet/Resource.cs +++ b/src/DotNet/Resource.cs @@ -37,38 +37,36 @@ public abstract class Resource : IDisposable, IMDTokenProvider { ManifestResourceAttributes flags; /// - public MDToken MDToken { - get { return new MDToken(Table.ManifestResource, rid); } - } + public MDToken MDToken => new MDToken(Table.ManifestResource, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// /// Gets/sets the offset of the resource /// public uint? Offset { - get { return offset; } - set { offset = value; } + get => offset; + set => offset = value; } /// /// Gets/sets the name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets/sets the flags /// public ManifestResourceAttributes Attributes { - get { return flags; } - set { flags = value; } + get => flags; + set => flags = value; } /// @@ -80,23 +78,19 @@ public ManifestResourceAttributes Attributes { /// Gets/sets the visibility /// public ManifestResourceAttributes Visibility { - get { return flags & ManifestResourceAttributes.VisibilityMask; } - set { flags = (flags & ~ManifestResourceAttributes.VisibilityMask) | (value & ManifestResourceAttributes.VisibilityMask); } + get => flags & ManifestResourceAttributes.VisibilityMask; + set => flags = (flags & ~ManifestResourceAttributes.VisibilityMask) | (value & ManifestResourceAttributes.VisibilityMask); } /// /// true if is set /// - public bool IsPublic { - get { return (flags & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Public; } - } + public bool IsPublic => (flags & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Public; /// /// true if is set /// - public bool IsPrivate { - get { return (flags & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private; } - } + public bool IsPrivate => (flags & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private; /// /// Constructor @@ -132,9 +126,7 @@ public sealed class EmbeddedResource : Resource { #endif /// - public override ResourceType ResourceType { - get { return ResourceType.Embedded; } - } + public override ResourceType ResourceType => ResourceType.Embedded; /// /// Gets/sets the resource data. It's never null. @@ -151,7 +143,7 @@ public IImageStream Data { } set { if (value == null) - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif @@ -200,11 +192,7 @@ public EmbeddedResource(UTF8String name, IImageStream dataStream) /// Resource data /// Resource flags public EmbeddedResource(UTF8String name, IImageStream dataStream, ManifestResourceAttributes flags) - : base(name, flags) { - if (dataStream == null) - throw new ArgumentNullException("dataStream"); - this.dataStream = dataStream; - } + : base(name, flags) => this.dataStream = dataStream ?? throw new ArgumentNullException(nameof(dataStream)); /// /// Creates a new resource stream that can access the same data as the original @@ -225,9 +213,7 @@ public IImageStream GetClonedResourceStream() { /// Gets the resource data as a /// /// A stream - public Stream GetResourceStream() { - return GetClonedResourceStream().CreateStream(true); - } + public Stream GetResourceStream() => GetClonedResourceStream().CreateStream(true); /// /// Gets the resource data as a byte array @@ -260,10 +246,7 @@ protected override void Dispose(bool disposing) { } /// - public override string ToString() { - var ds = dataStream; - return string.Format("{0} - size: {1}", UTF8String.ToSystemStringOrEmpty(Name), ds == null ? 0 : ds.Length); - } + public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - size: {(dataStream?.Length ?? 0)}"; } /// @@ -273,20 +256,14 @@ public sealed class AssemblyLinkedResource : Resource { AssemblyRef asmRef; /// - public override ResourceType ResourceType { - get { return ResourceType.AssemblyLinked; } - } + public override ResourceType ResourceType => ResourceType.AssemblyLinked; /// /// Gets/sets the assembly reference /// public AssemblyRef Assembly { - get { return asmRef; } - set { - if (value == null) - throw new ArgumentNullException("value"); - asmRef = value; - } + get => asmRef; + set => asmRef = value ?? throw new ArgumentNullException(nameof(value)); } /// @@ -296,16 +273,10 @@ public AssemblyRef Assembly { /// Assembly reference /// Resource flags public AssemblyLinkedResource(UTF8String name, AssemblyRef asmRef, ManifestResourceAttributes flags) - : base(name, flags) { - if (asmRef == null) - throw new ArgumentNullException("asmRef"); - this.asmRef = asmRef; - } + : base(name, flags) => this.asmRef = asmRef ?? throw new ArgumentNullException(nameof(asmRef)); /// - public override string ToString() { - return string.Format("{0} - assembly: {1}", UTF8String.ToSystemStringOrEmpty(Name), asmRef.FullName); - } + public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - assembly: {asmRef.FullName}"; } /// @@ -315,36 +286,28 @@ public sealed class LinkedResource : Resource { FileDef file; /// - public override ResourceType ResourceType { - get { return ResourceType.Linked; } - } + public override ResourceType ResourceType => ResourceType.Linked; /// /// Gets/sets the file /// public FileDef File { - get { return file; } - set { - if (value == null) - throw new ArgumentNullException("value"); - file = value; - } + get => file; + set => file = value ?? throw new ArgumentNullException(nameof(value)); } /// /// Gets/sets the hash /// public byte[] Hash { - get { return file.HashValue; } - set { file.HashValue = value; } + get => file.HashValue; + set => file.HashValue = value; } /// /// Gets/sets the file name /// - public UTF8String FileName { - get { return file == null ? UTF8String.Empty : file.Name; } - } + public UTF8String FileName => file == null ? UTF8String.Empty : file.Name; /// /// Constructor @@ -353,13 +316,9 @@ public UTF8String FileName { /// The file /// Resource flags public LinkedResource(UTF8String name, FileDef file, ManifestResourceAttributes flags) - : base(name, flags) { - this.file = file; - } + : base(name, flags) => this.file = file; /// - public override string ToString() { - return string.Format("{0} - file: {1}", UTF8String.ToSystemStringOrEmpty(Name), UTF8String.ToSystemStringOrEmpty(FileName)); - } + public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - file: {UTF8String.ToSystemStringOrEmpty(FileName)}"; } } diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index 45027b2ca..f87bd3b48 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -16,14 +16,10 @@ public sealed class BuiltInResourceData : IResourceData { /// /// Gets the data /// - public object Data { - get { return data; } - } + public object Data => data; /// - public ResourceTypeCode Code { - get { return code; } - } + public ResourceTypeCode Code => code; /// public FileOffset StartOffset { get; set; } @@ -145,17 +141,17 @@ public override string ToString() { case ResourceTypeCode.Decimal: case ResourceTypeCode.DateTime: case ResourceTypeCode.TimeSpan: - return string.Format("{0}: '{1}'", code, data); + return $"{code}: '{data}'"; case ResourceTypeCode.ByteArray: case ResourceTypeCode.Stream: var ary = data as byte[]; if (ary != null) - return string.Format("{0}: Length: {1}", code, ary.Length); - return string.Format("{0}: '{1}'", code, data); + return $"{code}: Length: {ary.Length}"; + return $"{code}: '{data}'"; default: - return string.Format("{0}: '{1}'", code, data); + return $"{code}: '{data}'"; } } } diff --git a/src/DotNet/Resources/ResourceDataCreator.cs b/src/DotNet/Resources/ResourceDataCreator.cs index 157f634d1..46ea92c23 100644 --- a/src/DotNet/Resources/ResourceDataCreator.cs +++ b/src/DotNet/Resources/ResourceDataCreator.cs @@ -19,9 +19,7 @@ public class ResourceDataCreator { /// /// Gets the owner module /// - protected ModuleDef Module { - get { return module; } - } + protected ModuleDef Module => module; /// /// Constructor @@ -29,185 +27,145 @@ protected ModuleDef Module { /// Owner module public ResourceDataCreator(ModuleDef module) { this.module = module; - this.moduleMD = module as ModuleDefMD; + moduleMD = module as ModuleDefMD; } /// /// Gets number of user data types /// - public int Count { - get { return dict.Count; } - } + public int Count => dict.Count; /// /// Create null data /// /// - public BuiltInResourceData CreateNull() { - return new BuiltInResourceData(ResourceTypeCode.Null, null); - } + public BuiltInResourceData CreateNull() => new BuiltInResourceData(ResourceTypeCode.Null, null); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(string value) { - return new BuiltInResourceData(ResourceTypeCode.String, value); - } + public BuiltInResourceData Create(string value) => new BuiltInResourceData(ResourceTypeCode.String, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(bool value) { - return new BuiltInResourceData(ResourceTypeCode.Boolean, value); - } + public BuiltInResourceData Create(bool value) => new BuiltInResourceData(ResourceTypeCode.Boolean, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(char value) { - return new BuiltInResourceData(ResourceTypeCode.Char, value); - } + public BuiltInResourceData Create(char value) => new BuiltInResourceData(ResourceTypeCode.Char, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(byte value) { - return new BuiltInResourceData(ResourceTypeCode.Byte, value); - } + public BuiltInResourceData Create(byte value) => new BuiltInResourceData(ResourceTypeCode.Byte, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(sbyte value) { - return new BuiltInResourceData(ResourceTypeCode.SByte, value); - } + public BuiltInResourceData Create(sbyte value) => new BuiltInResourceData(ResourceTypeCode.SByte, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(short value) { - return new BuiltInResourceData(ResourceTypeCode.Int16, value); - } + public BuiltInResourceData Create(short value) => new BuiltInResourceData(ResourceTypeCode.Int16, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(ushort value) { - return new BuiltInResourceData(ResourceTypeCode.UInt16, value); - } + public BuiltInResourceData Create(ushort value) => new BuiltInResourceData(ResourceTypeCode.UInt16, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(int value) { - return new BuiltInResourceData(ResourceTypeCode.Int32, value); - } + public BuiltInResourceData Create(int value) => new BuiltInResourceData(ResourceTypeCode.Int32, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(uint value) { - return new BuiltInResourceData(ResourceTypeCode.UInt32, value); - } + public BuiltInResourceData Create(uint value) => new BuiltInResourceData(ResourceTypeCode.UInt32, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(long value) { - return new BuiltInResourceData(ResourceTypeCode.Int64, value); - } + public BuiltInResourceData Create(long value) => new BuiltInResourceData(ResourceTypeCode.Int64, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(ulong value) { - return new BuiltInResourceData(ResourceTypeCode.UInt64, value); - } + public BuiltInResourceData Create(ulong value) => new BuiltInResourceData(ResourceTypeCode.UInt64, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(float value) { - return new BuiltInResourceData(ResourceTypeCode.Single, value); - } + public BuiltInResourceData Create(float value) => new BuiltInResourceData(ResourceTypeCode.Single, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(double value) { - return new BuiltInResourceData(ResourceTypeCode.Double, value); - } + public BuiltInResourceData Create(double value) => new BuiltInResourceData(ResourceTypeCode.Double, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(decimal value) { - return new BuiltInResourceData(ResourceTypeCode.Decimal, value); - } + public BuiltInResourceData Create(decimal value) => new BuiltInResourceData(ResourceTypeCode.Decimal, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(DateTime value) { - return new BuiltInResourceData(ResourceTypeCode.DateTime, value); - } + public BuiltInResourceData Create(DateTime value) => new BuiltInResourceData(ResourceTypeCode.DateTime, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData Create(TimeSpan value) { - return new BuiltInResourceData(ResourceTypeCode.TimeSpan, value); - } + public BuiltInResourceData Create(TimeSpan value) => new BuiltInResourceData(ResourceTypeCode.TimeSpan, value); /// /// Creates array data /// /// Value /// - public BuiltInResourceData Create(byte[] value) { - return new BuiltInResourceData(ResourceTypeCode.ByteArray, value); - } + public BuiltInResourceData Create(byte[] value) => new BuiltInResourceData(ResourceTypeCode.ByteArray, value); /// /// Creates data /// /// Value /// - public BuiltInResourceData CreateStream(byte[] value) { - return new BuiltInResourceData(ResourceTypeCode.Stream, value); - } + public BuiltInResourceData CreateStream(byte[] value) => new BuiltInResourceData(ResourceTypeCode.Stream, value); /// /// Creates serialized data @@ -215,9 +173,7 @@ public BuiltInResourceData CreateStream(byte[] value) { /// Serialized data /// Type of serialized data /// - public BinaryResourceData CreateSerialized(byte[] value, UserResourceType type) { - return new BinaryResourceData(CreateUserResourceType(type.Name, true), value); - } + public BinaryResourceData CreateSerialized(byte[] value, UserResourceType type) => new BinaryResourceData(CreateUserResourceType(type.Name, true), value); /// /// Creates serialized data @@ -225,10 +181,9 @@ public BinaryResourceData CreateSerialized(byte[] value, UserResourceType type) /// Serialized data /// public BinaryResourceData CreateSerialized(byte[] value) { - string assemblyName, typeName; - if (!GetSerializedTypeAndAssemblyName(value, out assemblyName, out typeName)) + if (!GetSerializedTypeAndAssemblyName(value, out var assemblyName, out var typeName)) throw new ApplicationException("Could not get serialized type name"); - string fullName = string.Format("{0}, {1}", typeName, assemblyName); + string fullName = $"{typeName}, {assemblyName}"; return new BinaryResourceData(CreateUserResourceType(fullName), value); } @@ -238,12 +193,11 @@ public class OkException : Exception { public string TypeName { get; set; } } - public override Type BindToType(string assemblyName, string typeName) { + public override Type BindToType(string assemblyName, string typeName) => throw new OkException { AssemblyName = assemblyName, TypeName = typeName, }; - } } bool GetSerializedTypeAndAssemblyName(byte[] value, out string assemblyName, out string typeName) { @@ -270,9 +224,7 @@ bool GetSerializedTypeAndAssemblyName(byte[] value, out string assemblyName, out /// /// Full name of type /// - public UserResourceType CreateUserResourceType(string fullName) { - return CreateUserResourceType(fullName, false); - } + public UserResourceType CreateUserResourceType(string fullName) => CreateUserResourceType(fullName, false); /// /// Creates a user type. If the type already exists, the existing value is returned. @@ -282,8 +234,7 @@ public UserResourceType CreateUserResourceType(string fullName) { /// type in an existing assembly reference /// UserResourceType CreateUserResourceType(string fullName, bool useFullName) { - UserResourceType type; - if (dict.TryGetValue(fullName, out type)) + if (dict.TryGetValue(fullName, out var type)) return type; var newFullName = useFullName ? fullName : GetRealTypeFullName(fullName); @@ -305,15 +256,14 @@ string GetRealTypeFullName(string fullName) { string assemblyName = GetRealAssemblyName(asmRef); if (!string.IsNullOrEmpty(assemblyName)) - newFullName = string.Format("{0}, {1}", tr.ReflectionFullName, assemblyName); + newFullName = $"{tr.ReflectionFullName}, {assemblyName}"; return newFullName; } string GetRealAssemblyName(IAssembly asm) { string assemblyName = asm.FullName; - string newAsmName; - if (!asmNameToAsmFullName.TryGetValue(assemblyName, out newAsmName)) + if (!asmNameToAsmFullName.TryGetValue(assemblyName, out var newAsmName)) asmNameToAsmFullName[assemblyName] = newAsmName = TryGetRealAssemblyName(asm); return newAsmName; } @@ -339,9 +289,7 @@ string TryGetRealAssemblyName(IAssembly asm) { /// /// Simple name of assembly /// - protected virtual string GetAssemblyFullName(string simpleName) { - return null; - } + protected virtual string GetAssemblyFullName(string simpleName) => null; /// /// Gets all types sorted by diff --git a/src/DotNet/Resources/ResourceElement.cs b/src/DotNet/Resources/ResourceElement.cs index 53b3307a3..210eaae53 100644 --- a/src/DotNet/Resources/ResourceElement.cs +++ b/src/DotNet/Resources/ResourceElement.cs @@ -16,8 +16,6 @@ public sealed class ResourceElement { public IResourceData ResourceData { get; set; } /// - public override string ToString() { - return string.Format("N: {0}, V: {1}", Name, ResourceData); - } + public override string ToString() => $"N: {Name}, V: {ResourceData}"; } } diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index d90573344..60984308e 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -13,23 +13,17 @@ public sealed class ResourceElementSet { /// /// Gets the number of elements in the set /// - public int Count { - get { return dict.Count; } - } + public int Count => dict.Count; /// /// Gets all resource elements /// - public IEnumerable ResourceElements { - get { return dict.Values; } - } + public IEnumerable ResourceElements => dict.Values; /// /// Adds a new resource to the set, overwriting any existing resource /// /// - public void Add(ResourceElement elem) { - dict[elem.Name] = elem; - } + public void Add(ResourceElement elem) => dict[elem.Name] = elem; } } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 2de6dc436..32a1ac07d 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -50,7 +50,7 @@ public ResourceReaderException(SerializationInfo info, StreamingContext context) /// /// Reads .NET resources /// - public struct ResourceReader { + public readonly struct ResourceReader { readonly IBinaryReader reader; readonly long baseFileOffset; readonly ResourceDataCreator resourceDataCreator; @@ -58,11 +58,11 @@ public struct ResourceReader { ResourceReader(ModuleDef module, IBinaryReader reader, CreateResourceDataDelegate createResourceDataDelegate) { this.reader = reader; - this.resourceDataCreator = new ResourceDataCreator(module); + resourceDataCreator = new ResourceDataCreator(module); this.createResourceDataDelegate = createResourceDataDelegate; var stream = reader as IImageStream; - this.baseFileOffset = stream == null ? 0 : (long)stream.FileOffset; + baseFileOffset = stream == null ? 0 : (long)stream.FileOffset; } /// @@ -70,9 +70,8 @@ public struct ResourceReader { /// /// Reader /// - public static bool CouldBeResourcesFile(IBinaryReader reader) { - return reader.CanRead(4) && reader.ReadUInt32() == 0xBEEFCACE; - } + public static bool CouldBeResourcesFile(IBinaryReader reader) => + reader.CanRead(4) && reader.ReadUInt32() == 0xBEEFCACE; /// /// Reads a .NET resource @@ -80,9 +79,7 @@ public static bool CouldBeResourcesFile(IBinaryReader reader) { /// Owner module /// Data of resource /// - public static ResourceElementSet Read(ModuleDef module, IBinaryReader reader) { - return Read(module, reader, null); - } + public static ResourceElementSet Read(ModuleDef module, IBinaryReader reader) => Read(module, reader, null); /// /// Reads a .NET resource @@ -91,27 +88,26 @@ public static ResourceElementSet Read(ModuleDef module, IBinaryReader reader) { /// Data of resource /// Call back that gets called to create a instance. Can be null. /// - public static ResourceElementSet Read(ModuleDef module, IBinaryReader reader, CreateResourceDataDelegate createResourceDataDelegate) { - return new ResourceReader(module, reader, createResourceDataDelegate).Read(); - } + public static ResourceElementSet Read(ModuleDef module, IBinaryReader reader, CreateResourceDataDelegate createResourceDataDelegate) => + new ResourceReader(module, reader, createResourceDataDelegate).Read(); ResourceElementSet Read() { - ResourceElementSet resources = new ResourceElementSet(); + var resources = new ResourceElementSet(); uint sig = reader.ReadUInt32(); if (sig != 0xBEEFCACE) - throw new ResourceReaderException(string.Format("Invalid resource sig: {0:X8}", sig)); + throw new ResourceReaderException($"Invalid resource sig: {sig:X8}"); if (!CheckReaders()) throw new ResourceReaderException("Invalid resource reader"); int version = reader.ReadInt32(); if (version != 2)//TODO: Support version 1 - throw new ResourceReaderException(string.Format("Invalid resource version: {0}", version)); + throw new ResourceReaderException($"Invalid resource version: {version}"); int numResources = reader.ReadInt32(); if (numResources < 0) - throw new ResourceReaderException(string.Format("Invalid number of resources: {0}", numResources)); + throw new ResourceReaderException($"Invalid number of resources: {numResources}"); int numUserTypes = reader.ReadInt32(); if (numUserTypes < 0) - throw new ResourceReaderException(string.Format("Invalid number of user types: {0}", numUserTypes)); + throw new ResourceReaderException($"Invalid number of user types: {numUserTypes}"); var userTypes = new List(); for (int i = 0; i < numUserTypes; i++) @@ -148,8 +144,8 @@ ResourceElementSet Read() { long nextDataOffset = i == infos.Count - 1 ? end : infos[i + 1].offset; int size = (int)(nextDataOffset - info.offset); element.ResourceData = ReadResourceData(userTypes, size); - element.ResourceData.StartOffset = this.baseFileOffset + (FileOffset)info.offset; - element.ResourceData.EndOffset = this.baseFileOffset + (FileOffset)reader.Position; + element.ResourceData.StartOffset = baseFileOffset + (FileOffset)info.offset; + element.ResourceData.EndOffset = baseFileOffset + (FileOffset)reader.Position; resources.Add(element); } @@ -164,9 +160,7 @@ public ResourceInfo(string name, long offset) { this.name = name; this.offset = offset; } - public override string ToString() { - return string.Format("{0:X8} - {1}", offset, name); - } + public override string ToString() => $"{offset:X8} - {name}"; } IResourceData ReadResourceData(List userTypes, int size) { @@ -194,7 +188,7 @@ IResourceData ReadResourceData(List userTypes, int size) { default: int userTypeIndex = (int)(code - (uint)ResourceTypeCode.UserTypes); if (userTypeIndex < 0 || userTypeIndex >= userTypes.Count) - throw new ResourceReaderException(string.Format("Invalid resource data code: {0}", code)); + throw new ResourceReaderException($"Invalid resource data code: {code}"); var userType = userTypes[userTypeIndex]; var serializedData = reader.ReadBytes(size); if (createResourceDataDelegate != null) { @@ -220,10 +214,10 @@ bool CheckReaders() { int numReaders = reader.ReadInt32(); if (numReaders < 0) - throw new ResourceReaderException(string.Format("Invalid number of readers: {0}", numReaders)); + throw new ResourceReaderException($"Invalid number of readers: {numReaders}"); int readersSize = reader.ReadInt32(); if (readersSize < 0) - throw new ResourceReaderException(string.Format("Invalid readers size: {0:X8}", readersSize)); + throw new ResourceReaderException($"Invalid readers size: {readersSize:X8}"); for (int i = 0; i < numReaders; i++) { var resourceReaderFullName = reader.ReadString(); diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index 20d10dfb7..ceb65520a 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -20,8 +20,8 @@ public sealed class ResourceWriter { ResourceWriter(ModuleDef module, Stream stream, ResourceElementSet resources) { this.module = module; - this.typeCreator = new ResourceDataCreator(module); - this.writer = new BinaryWriter(stream); + typeCreator = new ResourceDataCreator(module); + writer = new BinaryWriter(stream); this.resources = resources; } @@ -31,9 +31,8 @@ public sealed class ResourceWriter { /// Owner module /// Output stream /// .NET resources - public static void Write(ModuleDef module, Stream stream, ResourceElementSet resources) { + public static void Write(ModuleDef module, Stream stream, ResourceElementSet resources) => new ResourceWriter(module, stream, resources).Write(); - } void Write() { InitializeUserTypes(); diff --git a/src/DotNet/Resources/UserResourceData.cs b/src/DotNet/Resources/UserResourceData.cs index 295b1cd3b..d8633cc34 100644 --- a/src/DotNet/Resources/UserResourceData.cs +++ b/src/DotNet/Resources/UserResourceData.cs @@ -14,16 +14,12 @@ public abstract class UserResourceData : IResourceData { /// /// Full name including assembly of type /// - public string TypeName { - get { return type.Name; } - } + public string TypeName => type.Name; /// /// User type code /// - public ResourceTypeCode Code { - get { return type.Code; } - } + public ResourceTypeCode Code => type.Code; /// public FileOffset StartOffset { get; set; } @@ -35,9 +31,7 @@ public ResourceTypeCode Code { /// Constructor /// /// User resource type - public UserResourceData(UserResourceType type) { - this.type = type; - } + public UserResourceData(UserResourceType type) => this.type = type; /// public abstract void WriteData(BinaryWriter writer, IFormatter formatter); @@ -52,9 +46,7 @@ public sealed class BinaryResourceData : UserResourceData { /// /// Gets the raw data /// - public byte[] Data { - get { return data; } - } + public byte[] Data => data; /// /// Constructor @@ -62,18 +54,12 @@ public byte[] Data { /// User resource type /// Raw serialized data public BinaryResourceData(UserResourceType type, byte[] data) - : base(type) { - this.data = data; - } + : base(type) => this.data = data; /// - public override void WriteData(BinaryWriter writer, IFormatter formatter) { - writer.Write(data); - } + public override void WriteData(BinaryWriter writer, IFormatter formatter) => writer.Write(data); /// - public override string ToString() { - return string.Format("Binary: Length: {0}", data.Length); - } + public override string ToString() => "Binary: Length: " + data.Length.ToString(); } } diff --git a/src/DotNet/Resources/UserResourceType.cs b/src/DotNet/Resources/UserResourceType.cs index ed251b947..7ab40c948 100644 --- a/src/DotNet/Resources/UserResourceType.cs +++ b/src/DotNet/Resources/UserResourceType.cs @@ -11,16 +11,12 @@ public sealed class UserResourceType { /// /// Full name including assembly of type /// - public string Name { - get { return name; } - } + public string Name => name; /// /// User type code /// - public ResourceTypeCode Code { - get { return code; } - } + public ResourceTypeCode Code => code; /// /// Constructor @@ -33,8 +29,6 @@ public UserResourceType(string name, ResourceTypeCode code) { } /// - public override string ToString() { - return string.Format("{0:X2} {1}", (int)code, name); - } + public override string ToString() => $"{(int)code:X2} {name}"; } } diff --git a/src/DotNet/SecurityAttribute.cs b/src/DotNet/SecurityAttribute.cs index 671b968f5..b83b06145 100644 --- a/src/DotNet/SecurityAttribute.cs +++ b/src/DotNet/SecurityAttribute.cs @@ -21,8 +21,8 @@ public sealed class SecurityAttribute : ICustomAttribute { /// Gets/sets the attribute type /// public ITypeDefOrRef AttributeType { - get { return attrType; } - set { attrType = value; } + get => attrType; + set => attrType = value; } /// @@ -38,16 +38,12 @@ public string TypeFullName { /// /// Gets all named arguments (field and property values) /// - public ThreadSafe.IList NamedArguments { - get { return namedArguments; } - } + public ThreadSafe.IList NamedArguments => namedArguments; /// /// true if is not empty /// - public bool HasNamedArguments { - get { return namedArguments.Count > 0; } - } + public bool HasNamedArguments => namedArguments.Count > 0; /// /// Gets all s that are field arguments @@ -113,8 +109,6 @@ public SecurityAttribute(ITypeDefOrRef attrType, IList namedArg } /// - public override string ToString() { - return TypeFullName; - } + public override string ToString() => TypeFullName; } } diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index fcc1215a5..3d2547a67 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -25,79 +25,49 @@ public sealed class TypeEqualityComparer : IEqualityComparer, IEqualityCo /// Constructor /// /// Comparison options - public TypeEqualityComparer(SigComparerOptions options) { - this.options = options; - } + public TypeEqualityComparer(SigComparerOptions options) => this.options = options; /// - public bool Equals(IType x, IType y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(IType x, IType y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(IType obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(IType obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(ITypeDefOrRef x, ITypeDefOrRef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(ITypeDefOrRef x, ITypeDefOrRef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(ITypeDefOrRef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(ITypeDefOrRef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(TypeRef x, TypeRef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(TypeRef x, TypeRef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(TypeRef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(TypeRef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(TypeDef x, TypeDef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(TypeDef x, TypeDef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(TypeDef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(TypeDef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(TypeSpec x, TypeSpec y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(TypeSpec x, TypeSpec y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(TypeSpec obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(TypeSpec obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(TypeSig x, TypeSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(TypeSig x, TypeSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(TypeSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(TypeSig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(ExportedType x, ExportedType y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(ExportedType x, ExportedType y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(ExportedType obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(ExportedType obj) => new SigComparer(options).GetHashCode(obj); } /// @@ -130,39 +100,25 @@ public sealed class FieldEqualityComparer : IEqualityComparer, IEquality /// Constructor /// /// Comparison options - public FieldEqualityComparer(SigComparerOptions options) { - this.options = options; - } + public FieldEqualityComparer(SigComparerOptions options) => this.options = options; /// - public bool Equals(IField x, IField y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(IField x, IField y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(IField obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(IField obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(FieldDef x, FieldDef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(FieldDef x, FieldDef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(FieldDef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(FieldDef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(MemberRef x, MemberRef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(MemberRef x, MemberRef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(MemberRef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(MemberRef obj) => new SigComparer(options).GetHashCode(obj); } /// @@ -195,59 +151,37 @@ public sealed class MethodEqualityComparer : IEqualityComparer, IEquali /// Constructor /// /// Comparison options - public MethodEqualityComparer(SigComparerOptions options) { - this.options = options; - } + public MethodEqualityComparer(SigComparerOptions options) => this.options = options; /// - public bool Equals(IMethod x, IMethod y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(IMethod x, IMethod y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(IMethod obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(IMethod obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(IMethodDefOrRef x, IMethodDefOrRef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(IMethodDefOrRef x, IMethodDefOrRef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(IMethodDefOrRef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(IMethodDefOrRef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(MethodDef x, MethodDef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(MethodDef x, MethodDef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(MethodDef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(MethodDef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(MemberRef x, MemberRef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(MemberRef x, MemberRef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(MemberRef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(MemberRef obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(MethodSpec x, MethodSpec y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(MethodSpec x, MethodSpec y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(MethodSpec obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(MethodSpec obj) => new SigComparer(options).GetHashCode(obj); } /// @@ -280,19 +214,13 @@ public sealed class PropertyEqualityComparer : IEqualityComparer { /// Constructor /// /// Comparison options - public PropertyEqualityComparer(SigComparerOptions options) { - this.options = options; - } + public PropertyEqualityComparer(SigComparerOptions options) => this.options = options; /// - public bool Equals(PropertyDef x, PropertyDef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(PropertyDef x, PropertyDef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(PropertyDef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(PropertyDef obj) => new SigComparer(options).GetHashCode(obj); } /// @@ -325,19 +253,13 @@ public sealed class EventEqualityComparer : IEqualityComparer { /// Constructor /// /// Comparison options - public EventEqualityComparer(SigComparerOptions options) { - this.options = options; - } + public EventEqualityComparer(SigComparerOptions options) => this.options = options; /// - public bool Equals(EventDef x, EventDef y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(EventDef x, EventDef y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(EventDef obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(EventDef obj) => new SigComparer(options).GetHashCode(obj); } /// @@ -360,79 +282,49 @@ public sealed class SignatureEqualityComparer : IEqualityComparer /// Comparison options - public SignatureEqualityComparer(SigComparerOptions options) { - this.options = options; - } + public SignatureEqualityComparer(SigComparerOptions options) => this.options = options; /// - public bool Equals(CallingConventionSig x, CallingConventionSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(CallingConventionSig x, CallingConventionSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(CallingConventionSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(CallingConventionSig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(MethodBaseSig x, MethodBaseSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(MethodBaseSig x, MethodBaseSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(MethodBaseSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(MethodBaseSig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(MethodSig x, MethodSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(MethodSig x, MethodSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(MethodSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(MethodSig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(PropertySig x, PropertySig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(PropertySig x, PropertySig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(PropertySig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(PropertySig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(FieldSig x, FieldSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(FieldSig x, FieldSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(FieldSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(FieldSig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(LocalSig x, LocalSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(LocalSig x, LocalSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(LocalSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(LocalSig obj) => new SigComparer(options).GetHashCode(obj); /// - public bool Equals(GenericInstMethodSig x, GenericInstMethodSig y) { - return new SigComparer(options).Equals(x, y); - } + public bool Equals(GenericInstMethodSig x, GenericInstMethodSig y) => new SigComparer(options).Equals(x, y); /// - public int GetHashCode(GenericInstMethodSig obj) { - return new SigComparer(options).GetHashCode(obj); - } + public int GetHashCode(GenericInstMethodSig obj) => new SigComparer(options).GetHashCode(obj); } /// @@ -618,97 +510,29 @@ public struct SigComparer { GenericArguments genericArguments; readonly ModuleDef sourceModule; - bool DontCompareTypeScope { - get { return (options & SigComparerOptions.DontCompareTypeScope) != 0; } - } - - bool CompareMethodFieldDeclaringType { - get { return (options & SigComparerOptions.CompareMethodFieldDeclaringType) != 0; } - } - - bool ComparePropertyDeclaringType { - get { return (options & SigComparerOptions.ComparePropertyDeclaringType) != 0; } - } - - bool CompareEventDeclaringType { - get { return (options & SigComparerOptions.CompareEventDeclaringType) != 0; } - } - - bool CompareSentinelParams { - get { return (options & SigComparerOptions.CompareSentinelParams) != 0; } - } - - bool CompareAssemblyPublicKeyToken { - get { return (options & SigComparerOptions.CompareAssemblyPublicKeyToken) != 0; } - } - - bool CompareAssemblyVersion { - get { return (options & SigComparerOptions.CompareAssemblyVersion) != 0; } - } - - bool CompareAssemblyLocale { - get { return (options & SigComparerOptions.CompareAssemblyLocale) != 0; } - } - - bool TypeRefCanReferenceGlobalType { - get { return (options & SigComparerOptions.TypeRefCanReferenceGlobalType) != 0; } - } - - bool DontCompareReturnType { - get { return (options & SigComparerOptions.DontCompareReturnType) != 0; } - } - - bool SubstituteGenericParameters { - get { return (options & SigComparerOptions.SubstituteGenericParameters) != 0; } - } - - bool CaseInsensitiveTypeNamespaces { - get { return (options & SigComparerOptions.CaseInsensitiveTypeNamespaces) != 0; } - } - - bool CaseInsensitiveTypeNames { - get { return (options & SigComparerOptions.CaseInsensitiveTypeNames) != 0; } - } - - bool CaseInsensitiveMethodFieldNames { - get { return (options & SigComparerOptions.CaseInsensitiveMethodFieldNames) != 0; } - } - - bool CaseInsensitivePropertyNames { - get { return (options & SigComparerOptions.CaseInsensitivePropertyNames) != 0; } - } - - bool CaseInsensitiveEventNames { - get { return (options & SigComparerOptions.CaseInsensitiveEventNames) != 0; } - } - - bool PrivateScopeFieldIsComparable { - get { return (options & SigComparerOptions.PrivateScopeFieldIsComparable) != 0; } - } - - bool PrivateScopeMethodIsComparable { - get { return (options & SigComparerOptions.PrivateScopeMethodIsComparable) != 0; } - } - - bool RawSignatureCompare { - get { return (options & SigComparerOptions.RawSignatureCompare) != 0; } - } - - bool IgnoreModifiers { - get { return (options & SigComparerOptions.IgnoreModifiers) != 0; } - } - - bool MscorlibIsNotSpecial { - get { return (options & SigComparerOptions.MscorlibIsNotSpecial) != 0; } - } - - bool DontProjectWinMDRefs { - get { return (options & SigComparerOptions.DontProjectWinMDRefs) != 0; } - } - - bool DontCheckTypeEquivalence { - get { return (options & SigComparerOptions.DontCheckTypeEquivalence) != 0; } - } + bool DontCompareTypeScope => (options & SigComparerOptions.DontCompareTypeScope) != 0; + bool CompareMethodFieldDeclaringType => (options & SigComparerOptions.CompareMethodFieldDeclaringType) != 0; + bool ComparePropertyDeclaringType => (options & SigComparerOptions.ComparePropertyDeclaringType) != 0; + bool CompareEventDeclaringType => (options & SigComparerOptions.CompareEventDeclaringType) != 0; + bool CompareSentinelParams => (options & SigComparerOptions.CompareSentinelParams) != 0; + bool CompareAssemblyPublicKeyToken => (options & SigComparerOptions.CompareAssemblyPublicKeyToken) != 0; + bool CompareAssemblyVersion => (options & SigComparerOptions.CompareAssemblyVersion) != 0; + bool CompareAssemblyLocale => (options & SigComparerOptions.CompareAssemblyLocale) != 0; + bool TypeRefCanReferenceGlobalType => (options & SigComparerOptions.TypeRefCanReferenceGlobalType) != 0; + bool DontCompareReturnType => (options & SigComparerOptions.DontCompareReturnType) != 0; + bool SubstituteGenericParameters => (options & SigComparerOptions.SubstituteGenericParameters) != 0; + bool CaseInsensitiveTypeNamespaces => (options & SigComparerOptions.CaseInsensitiveTypeNamespaces) != 0; + bool CaseInsensitiveTypeNames => (options & SigComparerOptions.CaseInsensitiveTypeNames) != 0; + bool CaseInsensitiveMethodFieldNames => (options & SigComparerOptions.CaseInsensitiveMethodFieldNames) != 0; + bool CaseInsensitivePropertyNames => (options & SigComparerOptions.CaseInsensitivePropertyNames) != 0; + bool CaseInsensitiveEventNames => (options & SigComparerOptions.CaseInsensitiveEventNames) != 0; + bool PrivateScopeFieldIsComparable => (options & SigComparerOptions.PrivateScopeFieldIsComparable) != 0; + bool PrivateScopeMethodIsComparable => (options & SigComparerOptions.PrivateScopeMethodIsComparable) != 0; + bool RawSignatureCompare => (options & SigComparerOptions.RawSignatureCompare) != 0; + bool IgnoreModifiers => (options & SigComparerOptions.IgnoreModifiers) != 0; + bool MscorlibIsNotSpecial => (options & SigComparerOptions.MscorlibIsNotSpecial) != 0; + bool DontProjectWinMDRefs => (options & SigComparerOptions.DontProjectWinMDRefs) != 0; + bool DontCheckTypeEquivalence => (options & SigComparerOptions.DontCheckTypeEquivalence) != 0; /// /// Constructor @@ -724,9 +548,9 @@ public SigComparer(SigComparerOptions options) /// Comparison options /// The module which the comparison take place in. public SigComparer(SigComparerOptions options, ModuleDef sourceModule) { - this.recursionCounter = new RecursionCounter(); + recursionCounter = new RecursionCounter(); this.options = options; - this.genericArguments = null; + genericArguments = null; this.sourceModule = sourceModule; } @@ -761,85 +585,26 @@ int GetHashCode_Name(bool caseInsensitive, string a) { return (a ?? string.Empty).GetHashCode(); } - bool Equals_TypeNamespaces(UTF8String a, UTF8String b) { - return Equals_Names(CaseInsensitiveTypeNamespaces, a, b); - } - - bool Equals_TypeNamespaces(UTF8String a, string b) { - return Equals_Names(CaseInsensitiveTypeNamespaces, UTF8String.ToSystemStringOrEmpty(a), b); - } - - int GetHashCode_TypeNamespace(UTF8String a) { - return GetHashCode_Name(CaseInsensitiveTypeNamespaces, UTF8String.ToSystemStringOrEmpty(a)); - } - - int GetHashCode_TypeNamespace(string a) { - return GetHashCode_Name(CaseInsensitiveTypeNamespaces, a); - } - - bool Equals_TypeNames(UTF8String a, UTF8String b) { - return Equals_Names(CaseInsensitiveTypeNames, a, b); - } - - bool Equals_TypeNames(UTF8String a, string b) { - return Equals_Names(CaseInsensitiveTypeNames, UTF8String.ToSystemStringOrEmpty(a), b); - } - - int GetHashCode_TypeName(UTF8String a) { - return GetHashCode_Name(CaseInsensitiveTypeNames, UTF8String.ToSystemStringOrEmpty(a)); - } - - int GetHashCode_TypeName(string a) { - return GetHashCode_Name(CaseInsensitiveTypeNames, a); - } - - bool Equals_MethodFieldNames(UTF8String a, UTF8String b) { - return Equals_Names(CaseInsensitiveMethodFieldNames, a, b); - } - - bool Equals_MethodFieldNames(UTF8String a, string b) { - return Equals_Names(CaseInsensitiveMethodFieldNames, UTF8String.ToSystemStringOrEmpty(a), b); - } - - int GetHashCode_MethodFieldName(UTF8String a) { - return GetHashCode_Name(CaseInsensitiveMethodFieldNames, UTF8String.ToSystemStringOrEmpty(a)); - } - - int GetHashCode_MethodFieldName(string a) { - return GetHashCode_Name(CaseInsensitiveMethodFieldNames, a); - } - - bool Equals_PropertyNames(UTF8String a, UTF8String b) { - return Equals_Names(CaseInsensitivePropertyNames, a, b); - } - - bool Equals_PropertyNames(UTF8String a, string b) { - return Equals_Names(CaseInsensitivePropertyNames, UTF8String.ToSystemStringOrEmpty(a), b); - } - - int GetHashCode_PropertyName(UTF8String a) { - return GetHashCode_Name(CaseInsensitivePropertyNames, UTF8String.ToSystemStringOrEmpty(a)); - } - - int GetHashCode_PropertyName(string a) { - return GetHashCode_Name(CaseInsensitivePropertyNames, a); - } - - bool Equals_EventNames(UTF8String a, UTF8String b) { - return Equals_Names(CaseInsensitiveEventNames, a, b); - } - - bool Equals_EventNames(UTF8String a, string b) { - return Equals_Names(CaseInsensitiveEventNames, UTF8String.ToSystemStringOrEmpty(a), b); - } - - int GetHashCode_EventName(UTF8String a) { - return GetHashCode_Name(CaseInsensitiveEventNames, UTF8String.ToSystemStringOrEmpty(a)); - } - - int GetHashCode_EventName(string a) { - return GetHashCode_Name(CaseInsensitiveEventNames, a); - } + bool Equals_TypeNamespaces(UTF8String a, UTF8String b) => Equals_Names(CaseInsensitiveTypeNamespaces, a, b); + bool Equals_TypeNamespaces(UTF8String a, string b) => Equals_Names(CaseInsensitiveTypeNamespaces, UTF8String.ToSystemStringOrEmpty(a), b); + int GetHashCode_TypeNamespace(UTF8String a) => GetHashCode_Name(CaseInsensitiveTypeNamespaces, UTF8String.ToSystemStringOrEmpty(a)); + int GetHashCode_TypeNamespace(string a) => GetHashCode_Name(CaseInsensitiveTypeNamespaces, a); + bool Equals_TypeNames(UTF8String a, UTF8String b) => Equals_Names(CaseInsensitiveTypeNames, a, b); + bool Equals_TypeNames(UTF8String a, string b) => Equals_Names(CaseInsensitiveTypeNames, UTF8String.ToSystemStringOrEmpty(a), b); + int GetHashCode_TypeName(UTF8String a) => GetHashCode_Name(CaseInsensitiveTypeNames, UTF8String.ToSystemStringOrEmpty(a)); + int GetHashCode_TypeName(string a) => GetHashCode_Name(CaseInsensitiveTypeNames, a); + bool Equals_MethodFieldNames(UTF8String a, UTF8String b) => Equals_Names(CaseInsensitiveMethodFieldNames, a, b); + bool Equals_MethodFieldNames(UTF8String a, string b) => Equals_Names(CaseInsensitiveMethodFieldNames, UTF8String.ToSystemStringOrEmpty(a), b); + int GetHashCode_MethodFieldName(UTF8String a) => GetHashCode_Name(CaseInsensitiveMethodFieldNames, UTF8String.ToSystemStringOrEmpty(a)); + int GetHashCode_MethodFieldName(string a) => GetHashCode_Name(CaseInsensitiveMethodFieldNames, a); + bool Equals_PropertyNames(UTF8String a, UTF8String b) => Equals_Names(CaseInsensitivePropertyNames, a, b); + bool Equals_PropertyNames(UTF8String a, string b) => Equals_Names(CaseInsensitivePropertyNames, UTF8String.ToSystemStringOrEmpty(a), b); + int GetHashCode_PropertyName(UTF8String a) => GetHashCode_Name(CaseInsensitivePropertyNames, UTF8String.ToSystemStringOrEmpty(a)); + int GetHashCode_PropertyName(string a) => GetHashCode_Name(CaseInsensitivePropertyNames, a); + bool Equals_EventNames(UTF8String a, UTF8String b) => Equals_Names(CaseInsensitiveEventNames, a, b); + bool Equals_EventNames(UTF8String a, string b) => Equals_Names(CaseInsensitiveEventNames, UTF8String.ToSystemStringOrEmpty(a), b); + int GetHashCode_EventName(UTF8String a) => GetHashCode_Name(CaseInsensitiveEventNames, UTF8String.ToSystemStringOrEmpty(a)); + int GetHashCode_EventName(string a) => GetHashCode_Name(CaseInsensitiveEventNames, a); SigComparerOptions ClearOptions(SigComparerOptions flags) { var old = options; @@ -853,9 +618,7 @@ SigComparerOptions SetOptions(SigComparerOptions flags) { return old; } - void RestoreOptions(SigComparerOptions oldFlags) { - options = oldFlags; - } + void RestoreOptions(SigComparerOptions oldFlags) => options = oldFlags; void InitializeGenericArguments() { if (genericArguments == null) @@ -1091,18 +854,14 @@ public int GetHashCode(IMemberRef a) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(ITypeDefOrRef a, ITypeDefOrRef b) { - return Equals((IType)a, (IType)b); - } + public bool Equals(ITypeDefOrRef a, ITypeDefOrRef b) => Equals((IType)a, (IType)b); /// /// Gets the hash code of a type /// /// The type /// The hash code - public int GetHashCode(ITypeDefOrRef a) { - return GetHashCode((IType)a); - } + public int GetHashCode(ITypeDefOrRef a) => GetHashCode((IType)a); /// /// Compares types @@ -1223,9 +982,7 @@ public int GetHashCode(IType a) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeRef a, TypeDef b) { - return Equals(b, a); - } + public bool Equals(TypeRef a, TypeDef b) => Equals(b, a); /// /// Compares types @@ -1297,9 +1054,7 @@ public bool Equals(TypeDef a, TypeRef b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(ExportedType a, TypeDef b) { - return Equals(b, a); - } + public bool Equals(ExportedType a, TypeDef b) => Equals(b, a); /// /// Compares types @@ -1368,9 +1123,7 @@ public bool Equals(TypeDef a, ExportedType b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSpec a, TypeDef b) { - return Equals(b, a); - } + public bool Equals(TypeSpec a, TypeDef b) => Equals(b, a); /// /// Compares types @@ -1392,9 +1145,7 @@ public bool Equals(TypeDef a, TypeSpec b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSig a, TypeDef b) { - return Equals(b, a); - } + public bool Equals(TypeSig a, TypeDef b) => Equals(b, a); /// /// Compares types @@ -1415,8 +1166,7 @@ public bool Equals(TypeDef a, TypeSig b) { // If this code gets updated, update GetHashCode(TypeSig), // Equals(TypeRef,TypeSig) and Equals(TypeSig,ExportedType) too //************************************************************* - var b2 = b as TypeDefOrRefSig; - if (b2 != null) + if (b is TypeDefOrRefSig b2) result = Equals(a, (IType)b2.TypeDefOrRef); else if (b is ModifierSig || b is PinnedSig) result = Equals(a, b.Next); @@ -1433,9 +1183,7 @@ public bool Equals(TypeDef a, TypeSig b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSpec a, TypeRef b) { - return Equals(b, a); - } + public bool Equals(TypeSpec a, TypeRef b) => Equals(b, a); /// /// Compares types @@ -1457,9 +1205,7 @@ public bool Equals(TypeRef a, TypeSpec b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(ExportedType a, TypeRef b) { - return Equals(b, a); - } + public bool Equals(ExportedType a, TypeRef b) => Equals(b, a); /// /// Compares types @@ -1493,9 +1239,7 @@ public bool Equals(TypeRef a, ExportedType b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSig a, TypeRef b) { - return Equals(b, a); - } + public bool Equals(TypeSig a, TypeRef b) => Equals(b, a); /// /// Compares types @@ -1516,8 +1260,7 @@ public bool Equals(TypeRef a, TypeSig b) { // If this code gets updated, update GetHashCode(TypeSig), // Equals(TypeRef,TypeSig) and Equals(TypeSig,ExportedType) too //************************************************************* - var b2 = b as TypeDefOrRefSig; - if (b2 != null) + if (b is TypeDefOrRefSig b2) result = Equals(a, (IType)b2.TypeDefOrRef); else if (b is ModifierSig || b is PinnedSig) result = Equals(a, b.Next); @@ -1534,9 +1277,7 @@ public bool Equals(TypeRef a, TypeSig b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSig a, TypeSpec b) { - return Equals(b, a); - } + public bool Equals(TypeSig a, TypeSpec b) => Equals(b, a); /// /// Compares types @@ -1558,9 +1299,7 @@ public bool Equals(TypeSpec a, TypeSig b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(ExportedType a, TypeSpec b) { - return Equals(b, a); - } + public bool Equals(ExportedType a, TypeSpec b) => Equals(b, a); /// /// Compares types @@ -1582,9 +1321,7 @@ public bool Equals(TypeSpec a, ExportedType b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(ExportedType a, TypeSig b) { - return Equals(b, a); - } + public bool Equals(ExportedType a, TypeSig b) => Equals(b, a); /// /// Compares types @@ -1605,8 +1342,7 @@ public bool Equals(TypeSig a, ExportedType b) { // If this code gets updated, update GetHashCode(TypeSig), // Equals(TypeRef,TypeSig) and Equals(TypeSig,ExportedType) too //************************************************************* - var a2 = a as TypeDefOrRefSig; - if (a2 != null) + if (a is TypeDefOrRefSig a2) result = Equals(a2.TypeDefOrRef, b); else if (a is ModifierSig || a is PinnedSig) result = Equals(a.Next, b); @@ -2053,26 +1789,16 @@ internal bool Equals(IModule a, IModule b) { return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); } - static bool IsCorLib(ModuleDef a) { - return a != null && a.IsManifestModule && a.Assembly.IsCorLib(); - } + static bool IsCorLib(ModuleDef a) => a != null && a.IsManifestModule && a.Assembly.IsCorLib(); static bool IsCorLib(IModule a) { var mod = a as ModuleDef; return mod != null && mod.IsManifestModule && mod.Assembly.IsCorLib(); } - static bool IsCorLib(Module a) { - return a != null && a.Assembly.ManifestModule == a && a.Assembly == typeof(void).Assembly; - } - - static bool IsCorLib(IAssembly a) { - return a.IsCorLib(); - } - - static bool IsCorLib(Assembly a) { - return a == typeof(void).Assembly; - } + static bool IsCorLib(Module a) => a != null && a.Assembly.ManifestModule == a && a.Assembly == typeof(void).Assembly; + static bool IsCorLib(IAssembly a) => a.IsCorLib(); + static bool IsCorLib(Assembly a) => a == typeof(void).Assembly; /// /// Compares modules @@ -2209,7 +1935,7 @@ public bool Equals(TypeSig a, TypeSig b) { if (RawSignatureCompare) { var gt1 = gia.GenericType; var gt2 = gib.GenericType; - result = TokenEquals(gt1 == null ? null : gt1.TypeDefOrRef, gt2 == null ? null : gt2.TypeDefOrRef) && + result = TokenEquals(gt1?.TypeDefOrRef, gt2?.TypeDefOrRef) && Equals(gia.GenericArguments, gib.GenericArguments); } else { @@ -2331,7 +2057,7 @@ public int GetHashCode(TypeSig a) { case ElementType.Array: // Don't include sizes and lower bounds since GetHashCode(Type) doesn't (and can't). - ArraySig ara = (ArraySig)a; + var ara = (ArraySig)a; hash = HASHCODE_MAGIC_ET_ARRAY + (int)ara.Rank + GetHashCode(ara.Next); break; @@ -2539,22 +2265,22 @@ public int GetHashCode(CallingConventionSig a) { case CallingConvention.VarArg: case CallingConvention.Property: case CallingConvention.NativeVarArg: - MethodBaseSig ma = a as MethodBaseSig; + var ma = a as MethodBaseSig; hash = ma == null ? 0 : GetHashCode(ma); break; case CallingConvention.Field: - FieldSig fa = a as FieldSig; + var fa = a as FieldSig; hash = fa == null ? 0 : GetHashCode(fa); break; case CallingConvention.LocalSig: - LocalSig la = a as LocalSig; + var la = a as LocalSig; hash = la == null ? 0 : GetHashCode(la); break; case CallingConvention.GenericInst: - GenericInstMethodSig ga = a as GenericInstMethodSig; + var ga = a as GenericInstMethodSig; hash = ga == null ? 0 : GetHashCode(ga); break; @@ -2617,9 +2343,7 @@ public int GetHashCode(MethodBaseSig a) { return hash; } - int GetHashCode_CallingConvention(CallingConventionSig a) { - return GetHashCode(a.GetCallingConvention()); - } + int GetHashCode_CallingConvention(CallingConventionSig a) => GetHashCode(a.GetCallingConvention()); int GetHashCode(CallingConvention a) { //******************************************************************* @@ -2831,9 +2555,7 @@ public int GetHashCode(IMethod a) { /// Method #1 /// Method #2 /// true if same, false otherwise - public bool Equals(MemberRef a, MethodDef b) { - return Equals(b, a); - } + public bool Equals(MemberRef a, MethodDef b) => Equals(b, a); /// /// Compares methods @@ -3064,7 +2786,7 @@ bool Equals(IMemberRefParent a, IMemberRefParent b) { else if ((moda = a as ModuleRef) != null & (modb = b as ModuleRef) != null) { ModuleDef omoda = moda.Module, omodb = modb.Module; result = Equals((IModule)moda, (IModule)modb) && - Equals(omoda == null ? null : omoda.Assembly, omodb == null ? null : omodb.Assembly); + Equals(omoda?.Assembly, omodb?.Assembly); } else if ((ma = a as MethodDef) != null && (mb = b as MethodDef) != null) result = Equals(ma, mb); @@ -3174,9 +2896,7 @@ public int GetHashCode(IField a) { /// Field #1 /// Field #2 /// true if same, false otherwise - public bool Equals(MemberRef a, FieldDef b) { - return Equals(b, a); - } + public bool Equals(MemberRef a, FieldDef b) => Equals(b, a); /// /// Compares fields @@ -3284,7 +3004,7 @@ public int GetHashCode(PropertyDef a) { var sig = a.PropertySig; int hash = GetHashCode_PropertyName(a.Name) + - GetHashCode(sig == null ? null : sig.RetType); + GetHashCode(sig?.RetType); if (ComparePropertyDeclaringType) hash += GetHashCode(a.DeclaringType); @@ -3354,9 +3074,7 @@ bool EqualsGlobal(TypeDef a, ModuleRef b) { return result; } - static AssemblyDef GetAssembly(ModuleDef module) { - return module == null ? null : module.Assembly; - } + static AssemblyDef GetAssembly(ModuleDef module) => module?.Assembly; /// /// Compares types @@ -3364,9 +3082,7 @@ static AssemblyDef GetAssembly(ModuleDef module) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(Type a, IType b) { - return Equals(b, a); - } + public bool Equals(Type a, IType b) => Equals(b, a); /// /// Compares types @@ -3412,9 +3128,7 @@ public bool Equals(IType a, Type b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(Type a, TypeDef b) { - return Equals(b, a); - } + public bool Equals(Type a, TypeDef b) => Equals(b, a); /// /// Compares types @@ -3467,9 +3181,7 @@ bool EnclosingTypeEquals(TypeDef a, Type b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(Type a, TypeRef b) { - return Equals(b, a); - } + public bool Equals(Type a, TypeRef b) => Equals(b, a); /// /// Compares types @@ -3531,9 +3243,7 @@ bool Equals_TypeNamespaces(UTF8String a, Type b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(Type a, TypeSpec b) { - return Equals(b, a); - } + public bool Equals(Type a, TypeSpec b) => Equals(b, a); /// /// Compares types @@ -3557,9 +3267,7 @@ public bool Equals(TypeSpec a, Type b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(Type a, TypeSig b) { - return Equals(b, a); - } + public bool Equals(Type a, TypeSig b) => Equals(b, a); /// /// Compares types @@ -3567,13 +3275,10 @@ public bool Equals(Type a, TypeSig b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSig a, Type b) { - return Equals(a, b, false); - } + public bool Equals(TypeSig a, Type b) => Equals(a, b, false); bool Equals(ITypeDefOrRef a, Type b, bool treatAsGenericInst) { - var ts = a as TypeSpec; - if (ts != null) + if (a is TypeSpec ts) return Equals(ts.TypeSig, b, treatAsGenericInst); return Equals(a, b); } @@ -3681,7 +3386,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { if (!b.IsArray || b.IsSZArray()) result = false; else { - ArraySig ara = a as ArraySig; + var ara = a as ArraySig; result = ara.Rank == b.GetArrayRank() && (IsFnPtrElementType(b) ? (a = a.Next.RemoveModifiers()) != null && a.ElementType == ElementType.FnPtr : @@ -3754,9 +3459,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(Type a, ExportedType b) { - return Equals(b, a); - } + public bool Equals(Type a, ExportedType b) => Equals(b, a); /// /// Compares types @@ -3809,9 +3512,7 @@ public bool Equals(ExportedType a, Type b) { /// /// The type /// The hash code - public int GetHashCode(Type a) { - return GetHashCode(a, false); - } + public int GetHashCode(Type a) => GetHashCode(a, false); /// /// Gets the hash code of a type @@ -3943,9 +3644,7 @@ int GetHashCode(IList a) { /// /// Number of generic method parameters /// Hash code - static int GetHashCode_ElementType_MVar(int numGenericParams) { - return GetHashCode(numGenericParams, HASHCODE_MAGIC_ET_MVAR); - } + static int GetHashCode_ElementType_MVar(int numGenericParams) => GetHashCode(numGenericParams, HASHCODE_MAGIC_ET_MVAR); static int GetHashCode(int numGenericParams, int etypeHashCode) { //************************************************************************ @@ -4170,9 +3869,7 @@ bool DeclaringTypeEquals(MethodSpec a, MethodBase b) { /// Method #1 /// Method #2 /// true if same, false otherwise - public bool Equals(MethodBase a, IMethod b) { - return Equals(b, a); - } + public bool Equals(MethodBase a, IMethod b) => Equals(b, a); /// /// Compares methods @@ -4212,9 +3909,7 @@ public bool Equals(IMethod a, MethodBase b) { /// Method #1 /// Method #2 /// true if same, false otherwise - public bool Equals(MethodBase a, MethodDef b) { - return Equals(b, a); - } + public bool Equals(MethodBase a, MethodDef b) => Equals(b, a); /// /// Compares methods @@ -4258,9 +3953,7 @@ public bool Equals(MethodDef a, MethodBase b) { /// Method #1 /// Method #2 /// true if same, false otherwise - public bool Equals(MethodBase a, MethodSig b) { - return Equals(b, a); - } + public bool Equals(MethodBase a, MethodSig b) => Equals(b, a); /// /// Compares method sigs @@ -4291,9 +3984,7 @@ public bool Equals(MethodSig a, MethodBase b) { /// Method #1 /// Method #2 /// true if same, false otherwise - public bool Equals(MethodBase a, MemberRef b) { - return Equals(b, a); - } + public bool Equals(MethodBase a, MemberRef b) => Equals(b, a); /// /// Compares methods @@ -4382,10 +4073,10 @@ bool Equals(IMemberRefParent a, Type b, Module bModule) { if ((ita = a as ITypeDefOrRef) != null) result = Equals((IType)ita, b); else if ((moda = a as ModuleRef) != null) { - ModuleDef omoda = moda.Module; + var omoda = moda.Module; result = (object)b == null && // b == null => it's the global type Equals(moda, bModule) && - Equals(omoda == null ? null : omoda.Assembly, bModule.Assembly); + Equals(omoda?.Assembly, bModule.Assembly); } else if ((ma = a as MethodDef) != null) result = Equals(ma.DeclaringType, b); @@ -4404,9 +4095,7 @@ bool Equals(IMemberRefParent a, Type b, Module bModule) { /// Method #1 /// Method #2 /// true if same, false otherwise - public bool Equals(MethodBase a, MethodSpec b) { - return Equals(b, a); - } + public bool Equals(MethodBase a, MethodSpec b) => Equals(b, a); /// /// Compares methods @@ -4511,13 +4200,8 @@ int GetHashCode_ReturnType(MethodBase a) { return GetHashCode(typeof(void)); } - int GetHashCode(ParameterInfo a, Type declaringType) { - return GetHashCode(a.ParameterType, declaringType.MustTreatTypeAsGenericInstType(a.ParameterType)); - } - - int GetHashCode(Type a, Type declaringType) { - return GetHashCode(a, declaringType.MustTreatTypeAsGenericInstType(a)); - } + int GetHashCode(ParameterInfo a, Type declaringType) => GetHashCode(a.ParameterType, declaringType.MustTreatTypeAsGenericInstType(a.ParameterType)); + int GetHashCode(Type a, Type declaringType) => GetHashCode(a, declaringType.MustTreatTypeAsGenericInstType(a)); /// /// Compares calling conventions @@ -4599,9 +4283,7 @@ bool ReturnTypeEquals(TypeSig a, MethodBase b) { return result; } - static bool IsSystemVoid(TypeSig a) { - return a.RemovePinnedAndModifiers().GetElementType() == ElementType.Void; - } + static bool IsSystemVoid(TypeSig a) => a.RemovePinnedAndModifiers().GetElementType() == ElementType.Void; /// /// Compares parameter lists @@ -4649,8 +4331,7 @@ bool Equals(TypeSig a, ParameterInfo b, Type declaringType) { if (!recursionCounter.Increment()) return false; - TypeSig a2; - bool result = ModifiersEquals(a, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out a2) && + bool result = ModifiersEquals(a, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && Equals(a2, b.ParameterType, declaringType.MustTreatTypeAsGenericInstType(b.ParameterType)); recursionCounter.Decrement(); @@ -4722,9 +4403,7 @@ bool ModifiersEquals(IList a, IList b) { /// Field #1 /// Field #2 /// true if same, false otherwise - public bool Equals(FieldInfo a, IField b) { - return Equals(b, a); - } + public bool Equals(FieldInfo a, IField b) => Equals(b, a); /// /// Compares fields @@ -4761,9 +4440,7 @@ public bool Equals(IField a, FieldInfo b) { /// Field #1 /// Field #2 /// true if same, false otherwise - public bool Equals(FieldInfo a, FieldDef b) { - return Equals(b, a); - } + public bool Equals(FieldInfo a, FieldDef b) => Equals(b, a); /// /// Compares fields @@ -4795,8 +4472,7 @@ bool Equals(FieldSig a, FieldInfo b) { if (!recursionCounter.Increment()) return false; - TypeSig a2; - bool result = ModifiersEquals(a.Type, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out a2) && + bool result = ModifiersEquals(a.Type, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && Equals(a2, b.FieldType, b.DeclaringType.MustTreatTypeAsGenericInstType(b.FieldType)); recursionCounter.Decrement(); @@ -4809,9 +4485,7 @@ bool Equals(FieldSig a, FieldInfo b) { /// Field #1 /// Field #2 /// true if same, false otherwise - public bool Equals(FieldInfo a, MemberRef b) { - return Equals(b, a); - } + public bool Equals(FieldInfo a, MemberRef b) => Equals(b, a); /// /// Compares fields @@ -4911,8 +4585,7 @@ bool Equals(PropertySig a, PropertyInfo b) { if (!recursionCounter.Increment()) return false; - TypeSig a2; - bool result = ModifiersEquals(a.RetType, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out a2) && + bool result = ModifiersEquals(a.RetType, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && Equals(a2, b.PropertyType, b.DeclaringType.MustTreatTypeAsGenericInstType(b.PropertyType)); recursionCounter.Decrement(); @@ -4988,8 +4661,6 @@ public int GetHashCode(EventInfo a) { } /// - public override string ToString() { - return string.Format("{0} - {1}", recursionCounter, options); - } + public override string ToString() => $"{recursionCounter} - {options}"; } } diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 2988fb706..3050d4a0a 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -47,9 +47,8 @@ public struct SignatureReader : IDisposable { /// #Blob stream offset of signature /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig) { - return ReadSig(readerModule, sig, new GenericParamContext()); - } + public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig) => + ReadSig(readerModule, sig, new GenericParamContext()); /// /// Reads a signature from the #Blob stream @@ -82,9 +81,8 @@ public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig, G /// The signature data /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature) { - return ReadSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); - } + public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature) => + ReadSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); /// /// Reads a signature @@ -94,9 +92,8 @@ public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature) /// Generic parameter context /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature, GenericParamContext gpContext) { - return ReadSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), gpContext); - } + public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature, GenericParamContext gpContext) => + ReadSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), gpContext); /// /// Reads a signature @@ -105,9 +102,8 @@ public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature, /// The signature reader which will be owned by us /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, IBinaryReader signature) { - return ReadSig(module, module.CorLibTypes, signature, new GenericParamContext()); - } + public static CallingConventionSig ReadSig(ModuleDefMD module, IBinaryReader signature) => + ReadSig(module, module.CorLibTypes, signature, new GenericParamContext()); /// /// Reads a signature @@ -117,9 +113,8 @@ public static CallingConventionSig ReadSig(ModuleDefMD module, IBinaryReader sig /// Generic parameter context /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, IBinaryReader signature, GenericParamContext gpContext) { - return ReadSig(module, module.CorLibTypes, signature, gpContext); - } + public static CallingConventionSig ReadSig(ModuleDefMD module, IBinaryReader signature, GenericParamContext gpContext) => + ReadSig(module, module.CorLibTypes, signature, gpContext); /// /// Reads a signature @@ -129,9 +124,8 @@ public static CallingConventionSig ReadSig(ModuleDefMD module, IBinaryReader sig /// The signature data /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature) { - return ReadSig(helper, corLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); - } + public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature) => + ReadSig(helper, corLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); /// /// Reads a signature @@ -142,9 +136,8 @@ public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLi /// Generic parameter context /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext) { - return ReadSig(helper, corLibTypes, MemoryImageStream.Create(signature), gpContext); - } + public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext) => + ReadSig(helper, corLibTypes, MemoryImageStream.Create(signature), gpContext); /// /// Reads a signature @@ -154,9 +147,8 @@ public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLi /// The signature reader which will be owned by us /// A new instance or null if /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, IBinaryReader signature) { - return ReadSig(helper, corLibTypes, signature, new GenericParamContext()); - } + public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, IBinaryReader signature) => + ReadSig(helper, corLibTypes, signature, new GenericParamContext()); /// /// Reads a signature @@ -187,9 +179,8 @@ public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLi /// #Blob stream offset of signature /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig) { - return ReadTypeSig(readerModule, sig, new GenericParamContext()); - } + public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig) => + ReadTypeSig(readerModule, sig, new GenericParamContext()); /// /// Reads a type signature from the #Blob stream @@ -218,9 +209,8 @@ public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig, GenericPar /// here, else this will be null /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig, out byte[] extraData) { - return ReadTypeSig(readerModule, sig, new GenericParamContext(), out extraData); - } + public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig, out byte[] extraData) => + ReadTypeSig(readerModule, sig, new GenericParamContext(), out extraData); /// /// Reads a type signature from the #Blob stream @@ -260,9 +250,8 @@ public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig, GenericPar /// The signature data /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature) { - return ReadTypeSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); - } + public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature) => + ReadTypeSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); /// /// Reads a signature @@ -272,9 +261,8 @@ public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature) { /// Generic parameter context /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature, GenericParamContext gpContext) { - return ReadTypeSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), gpContext); - } + public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature, GenericParamContext gpContext) => + ReadTypeSig(module, module.CorLibTypes, MemoryImageStream.Create(signature), gpContext); /// /// Reads a signature @@ -283,9 +271,8 @@ public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature, GenericP /// The signature reader which will be owned by us /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, IBinaryReader signature) { - return ReadTypeSig(module, module.CorLibTypes, signature, new GenericParamContext()); - } + public static TypeSig ReadTypeSig(ModuleDefMD module, IBinaryReader signature) => + ReadTypeSig(module, module.CorLibTypes, signature, new GenericParamContext()); /// /// Reads a signature @@ -295,9 +282,8 @@ public static TypeSig ReadTypeSig(ModuleDefMD module, IBinaryReader signature) { /// Generic parameter context /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, IBinaryReader signature, GenericParamContext gpContext) { - return ReadTypeSig(module, module.CorLibTypes, signature, gpContext); - } + public static TypeSig ReadTypeSig(ModuleDefMD module, IBinaryReader signature, GenericParamContext gpContext) => + ReadTypeSig(module, module.CorLibTypes, signature, gpContext); /// /// Reads a signature @@ -307,9 +293,8 @@ public static TypeSig ReadTypeSig(ModuleDefMD module, IBinaryReader signature, G /// The signature data /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature) { - return ReadTypeSig(helper, corLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); - } + public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature) => + ReadTypeSig(helper, corLibTypes, MemoryImageStream.Create(signature), new GenericParamContext()); /// /// Reads a signature @@ -320,9 +305,8 @@ public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes co /// Generic parameter context /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext) { - return ReadTypeSig(helper, corLibTypes, MemoryImageStream.Create(signature), gpContext); - } + public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext) => + ReadTypeSig(helper, corLibTypes, MemoryImageStream.Create(signature), gpContext); /// /// Reads a signature @@ -332,9 +316,8 @@ public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes co /// The signature reader which will be owned by us /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, IBinaryReader signature) { - return ReadTypeSig(helper, corLibTypes, signature, new GenericParamContext()); - } + public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, IBinaryReader signature) => + ReadTypeSig(helper, corLibTypes, signature, new GenericParamContext()); /// /// Reads a signature @@ -345,10 +328,8 @@ public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes co /// Generic parameter context /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, IBinaryReader signature, GenericParamContext gpContext) { - byte[] extraData; - return ReadTypeSig(helper, corLibTypes, signature, gpContext, out extraData); - } + public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, IBinaryReader signature, GenericParamContext gpContext) => + ReadTypeSig(helper, corLibTypes, signature, gpContext, out var extraData); /// /// Reads a signature @@ -361,9 +342,8 @@ public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes co /// here, else this will be null /// A new instance or null if /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext, out byte[] extraData) { - return ReadTypeSig(helper, corLibTypes, MemoryImageStream.Create(signature), gpContext, out extraData); - } + public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext, out byte[] extraData) => + ReadTypeSig(helper, corLibTypes, MemoryImageStream.Create(signature), gpContext, out extraData); /// /// Reads a signature @@ -419,7 +399,7 @@ public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes co this.corLibTypes = corLibTypes; this.reader = reader; this.gpContext = gpContext; - this.recursionCounter = new RecursionCounter(); + recursionCounter = new RecursionCounter(); } byte[] GetExtraData() { @@ -480,38 +460,30 @@ CallingConventionSig ReadSig() { /// /// First byte of signature /// A new instance - FieldSig ReadField(CallingConvention callingConvention) { - return new FieldSig(callingConvention, ReadType()); - } + FieldSig ReadField(CallingConvention callingConvention) => new FieldSig(callingConvention, ReadType()); /// /// Reads a /// /// First byte of signature /// A new instance - MethodSig ReadMethod(CallingConvention callingConvention) { - return ReadSig(new MethodSig(callingConvention)); - } + MethodSig ReadMethod(CallingConvention callingConvention) => ReadSig(new MethodSig(callingConvention)); /// /// Reads a /// /// First byte of signature /// A new instance - PropertySig ReadProperty(CallingConvention callingConvention) { - return ReadSig(new PropertySig(callingConvention)); - } + PropertySig ReadProperty(CallingConvention callingConvention) => ReadSig(new PropertySig(callingConvention)); T ReadSig(T methodSig) where T : MethodBaseSig { if (methodSig.Generic) { - uint count; - if (!reader.ReadCompressedUInt32(out count)) + if (!reader.ReadCompressedUInt32(out uint count)) return null; methodSig.GenParamCount = count; } - uint numParams; - if (!reader.ReadCompressedUInt32(out numParams)) + if (!reader.ReadCompressedUInt32(out uint numParams)) return null; methodSig.RetType = ReadType(); @@ -537,8 +509,7 @@ T ReadSig(T methodSig) where T : MethodBaseSig { /// First byte of signature /// A new instance LocalSig ReadLocalSig(CallingConvention callingConvention) { - uint count; - if (!reader.ReadCompressedUInt32(out count)) + if (!reader.ReadCompressedUInt32(out uint count)) return null; var sig = new LocalSig(callingConvention, count); var locals = sig.Locals; @@ -553,8 +524,7 @@ LocalSig ReadLocalSig(CallingConvention callingConvention) { /// First byte of signature /// A new instance GenericInstMethodSig ReadGenericInstMethod(CallingConvention callingConvention) { - uint count; - if (!reader.ReadCompressedUInt32(out count)) + if (!reader.ReadCompressedUInt32(out uint count)) return null; var sig = new GenericInstMethodSig(callingConvention, count); var args = sig.GenericArguments; @@ -653,8 +623,7 @@ TypeSig ReadType() { break; var sizes = new List((int)num); for (uint i = 0; i < num; i++) { - uint size; - if (!reader.ReadCompressedUInt32(out size)) + if (!reader.ReadCompressedUInt32(out uint size)) goto exit; sizes.Add(size); } @@ -662,8 +631,7 @@ TypeSig ReadType() { break; var lowerBounds = new List((int)num); for (uint i = 0; i < num; i++) { - int size; - if (!reader.ReadCompressedInt32(out size)) + if (!reader.ReadCompressedInt32(out int size)) goto exit; lowerBounds.Add(size); } @@ -695,8 +663,7 @@ TypeSig ReadType() { /// /// A instance ITypeDefOrRef ReadTypeDefOrRef() { - uint codedToken; - if (!reader.ReadCompressedUInt32(out codedToken)) + if (!reader.ReadCompressedUInt32(out uint codedToken)) return null; return helper.ResolveTypeDefOrRef(codedToken, gpContext); } diff --git a/src/DotNet/StandAloneSig.cs b/src/DotNet/StandAloneSig.cs index b25dd7c87..7b10bcdd5 100644 --- a/src/DotNet/StandAloneSig.cs +++ b/src/DotNet/StandAloneSig.cs @@ -23,27 +23,23 @@ public abstract class StandAloneSig : IHasCustomAttribute, IHasCustomDebugInform protected uint rid; /// - public MDToken MDToken { - get { return new MDToken(Table.StandAloneSig, rid); } - } + public MDToken MDToken => new MDToken(Table.StandAloneSig, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int HasCustomAttributeTag { - get { return 11; } - } + public int HasCustomAttributeTag => 11; /// /// From column StandAloneSig.Signature /// public CallingConventionSig Signature { - get { return signature; } - set { signature = value; } + get => signature; + set => signature = value; } /// protected CallingConventionSig signature; @@ -61,24 +57,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 11; } - } + public int HasCustomDebugInformationTag => 11; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -93,30 +82,27 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// Gets/sets the method sig /// public MethodSig MethodSig { - get { return signature as MethodSig; } - set { signature = value; } + get => signature as MethodSig; + set => signature = value; } /// /// Gets/sets the locals sig /// public LocalSig LocalSig { - get { return signature as LocalSig; } - set { signature = value; } + get => signature as LocalSig; + set => signature = value; } /// - public bool ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); } /// @@ -133,17 +119,13 @@ public StandAloneSigUser() { /// Constructor /// /// A locals sig - public StandAloneSigUser(LocalSig localSig) { - this.signature = localSig; - } + public StandAloneSigUser(LocalSig localSig) => signature = localSig; /// /// Constructor /// /// A method sig - public StandAloneSigUser(MethodSig methodSig) { - this.signature = methodSig; - } + public StandAloneSigUser(MethodSig methodSig) => signature = methodSig; } /// @@ -157,9 +139,7 @@ sealed class StandAloneSigMD : StandAloneSig, IMDTokenProviderMD { readonly GenericParamContext gpContext; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override void InitializeCustomAttributes() { @@ -188,9 +168,9 @@ public StandAloneSigMD(ModuleDefMD readerModule, uint rid, GenericParamContext g if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.StandAloneSigTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("StandAloneSig rid {0} does not exist", rid)); + throw new BadImageFormatException($"StandAloneSig rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; this.gpContext = gpContext; diff --git a/src/DotNet/StrongNameKey.cs b/src/DotNet/StrongNameKey.cs index 1f110eafd..85d853765 100644 --- a/src/DotNet/StrongNameKey.cs +++ b/src/DotNet/StrongNameKey.cs @@ -85,31 +85,31 @@ public sealed class StrongNamePublicKey { /// Gets/sets the signature algorithm /// public SignatureAlgorithm SignatureAlgorithm { - get { return signatureAlgorithm; } - set { signatureAlgorithm = value; } + get => signatureAlgorithm; + set => signatureAlgorithm = value; } /// /// Gets/sets the hash algorithm /// public AssemblyHashAlgorithm HashAlgorithm { - get { return hashAlgorithm; } - set { hashAlgorithm = value; } + get => hashAlgorithm; + set => hashAlgorithm = value; } /// /// Gets/sets the modulus /// public byte[] Modulus { - get { return modulus; } - set { modulus = value; } + get => modulus; + set => modulus = value; } /// /// Gets/sets the public exponent /// public byte[] PublicExponent { - get { return publicExponent; } + get => publicExponent; set { if (value == null || value.Length != 4) throw new ArgumentException("PublicExponent must be exactly 4 bytes"); @@ -169,9 +169,7 @@ public StrongNamePublicKey(PublicKey pk) /// /// Public key data /// Strong name key is invalid - public StrongNamePublicKey(byte[] pk) { - Initialize(new BinaryReader(new MemoryStream(pk))); - } + public StrongNamePublicKey(byte[] pk) => Initialize(new BinaryReader(new MemoryStream(pk))); /// /// Constructor @@ -188,18 +186,14 @@ public StrongNamePublicKey(string filename) { /// /// Public key stream /// Strong name key is invalid - public StrongNamePublicKey(Stream stream) { - Initialize(new BinaryReader(stream)); - } + public StrongNamePublicKey(Stream stream) => Initialize(new BinaryReader(stream)); /// /// Constructor /// /// Public key reader /// Strong name key is invalid - public StrongNamePublicKey(BinaryReader reader) { - Initialize(reader); - } + public StrongNamePublicKey(BinaryReader reader) => Initialize(reader); void Initialize(BinaryReader reader) { try { @@ -233,9 +227,7 @@ void Initialize(BinaryReader reader) { /// /// Creates a public key blob /// - public byte[] CreatePublicKey() { - return CreatePublicKey(signatureAlgorithm, hashAlgorithm, modulus, publicExponent); - } + public byte[] CreatePublicKey() => CreatePublicKey(signatureAlgorithm, hashAlgorithm, modulus, publicExponent); internal static byte[] CreatePublicKey(SignatureAlgorithm sigAlg, AssemblyHashAlgorithm hashAlg, byte[] modulus, byte[] publicExponent) { if (sigAlg != SignatureAlgorithm.CALG_RSA_SIGN) @@ -257,9 +249,7 @@ internal static byte[] CreatePublicKey(SignatureAlgorithm sigAlg, AssemblyHashAl } /// - public override string ToString() { - return Utils.ToHex(CreatePublicKey(), false); - } + public override string ToString() => Utils.ToHex(CreatePublicKey(), false); } /// @@ -380,12 +370,10 @@ public byte[] Modulus { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - modulus = value; + modulus = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -406,12 +394,10 @@ public byte[] Prime1 { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - prime1 = value; + prime1 = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -432,12 +418,10 @@ public byte[] Prime2 { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - prime2 = value; + prime2 = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -458,12 +442,10 @@ public byte[] Exponent1 { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - exponent1 = value; + exponent1 = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -484,12 +466,10 @@ public byte[] Exponent2 { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - exponent2 = value; + exponent2 = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -510,12 +490,10 @@ public byte[] Coefficient { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - coefficient = value; + coefficient = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -536,12 +514,10 @@ public byte[] PrivateExponent { #endif } set { - if (value == null) - throw new ArgumentNullException("value"); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - privateExponent = value; + privateExponent = value ?? throw new ArgumentNullException(nameof(value)); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif @@ -559,9 +535,7 @@ public StrongNameKey() { /// /// Strong name key data /// Strong name key is invalid - public StrongNameKey(byte[] keyData) { - Initialize(new BinaryReader(new MemoryStream(keyData))); - } + public StrongNameKey(byte[] keyData) => Initialize(new BinaryReader(new MemoryStream(keyData))); /// /// Constructor @@ -578,18 +552,14 @@ public StrongNameKey(string filename) { /// /// Strong name key stream /// Strong name key is invalid - public StrongNameKey(Stream stream) { - Initialize(new BinaryReader(stream)); - } + public StrongNameKey(Stream stream) => Initialize(new BinaryReader(stream)); /// /// Constructor /// /// Strong name key reader /// Strong name key is invalid - public StrongNameKey(BinaryReader reader) { - Initialize(reader); - } + public StrongNameKey(BinaryReader reader) => Initialize(reader); /// /// Initializes the public/private key pair data diff --git a/src/DotNet/StrongNameSigner.cs b/src/DotNet/StrongNameSigner.cs index 0e8d42edd..caf619e4c 100644 --- a/src/DotNet/StrongNameSigner.cs +++ b/src/DotNet/StrongNameSigner.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet { /// Strong name signs an assembly. It supports normal strong name signing and the new /// (.NET 4.5) enhanced strong name signing. /// - public struct StrongNameSigner { + public readonly struct StrongNameSigner { readonly Stream stream; readonly long baseOffset; @@ -78,7 +78,7 @@ byte[] StrongNameHashData(AssemblyHashAlgorithm hashAlg, long snSigOffset, uint long snSigOffsetEnd = snSigOffset + snSigSize; using (var hasher = new AssemblyHash(hashAlg)) { - byte[] buffer = new byte[0x8000]; + var buffer = new byte[0x8000]; // Hash the DOS header. It's defined to be all data from the start of // the file up to the NT headers. diff --git a/src/DotNet/TIAHelper.cs b/src/DotNet/TIAHelper.cs index 441e52627..10360d12a 100644 --- a/src/DotNet/TIAHelper.cs +++ b/src/DotNet/TIAHelper.cs @@ -10,19 +10,16 @@ namespace dnlib.DotNet { /// System.Runtime.InteropServices.TypeIdentifierAttribute helper code used by /// static class TIAHelper { - struct Info : IEquatable { + readonly struct Info : IEquatable { public readonly UTF8String Scope; public readonly UTF8String Identifier; public Info(UTF8String scope, UTF8String identifier) { - this.Scope = scope; - this.Identifier = identifier; + Scope = scope; + Identifier = identifier; } - public bool Equals(Info other) { - return stricmp(Scope, other.Scope) && - UTF8String.Equals(Identifier, other.Identifier); - } + public bool Equals(Info other) => stricmp(Scope, other.Scope) && UTF8String.Equals(Identifier, other.Identifier); static bool stricmp(UTF8String a, UTF8String b) { var da = (object)a == null ? null : a.Data; @@ -65,8 +62,7 @@ static bool stricmp(UTF8String a, UTF8String b) { } } else { - var mod = td.Module; - var asm = mod == null ? null : mod.Assembly; + var asm = td.Module?.Assembly; if (asm == null) return null; bool isTypeLib = asm.CustomAttributes.IsDefined("System.Runtime.InteropServices.ImportedFromTypeLibAttribute") || @@ -80,8 +76,7 @@ static bool stricmp(UTF8String a, UTF8String b) { if (td.IsInterface && td.IsImport) gca = td.CustomAttributes.Find("System.Runtime.InteropServices.GuidAttribute"); else { - var mod = td.Module; - var asm = mod == null ? null : mod.Assembly; + var asm = td.Module?.Assembly; if (asm == null) return null; gca = asm.CustomAttributes.Find("System.Runtime.InteropServices.GuidAttribute"); diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index a29abece2..d078cabd2 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -30,108 +30,70 @@ public abstract class TypeDef : ITypeDefOrRef, IHasCustomAttribute, IHasDeclSecu #endif /// - public MDToken MDToken { - get { return new MDToken(Table.TypeDef, rid); } - } + public MDToken MDToken => new MDToken(Table.TypeDef, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int TypeDefOrRefTag { - get { return 0; } - } + public int TypeDefOrRefTag => 0; /// - public int HasCustomAttributeTag { - get { return 3; } - } + public int HasCustomAttributeTag => 3; /// - public int HasDeclSecurityTag { - get { return 0; } - } + public int HasDeclSecurityTag => 0; /// - public int MemberRefParentTag { - get { return 0; } - } + public int MemberRefParentTag => 0; /// - public int TypeOrMethodDefTag { - get { return 0; } - } + public int TypeOrMethodDefTag => 0; /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { return GenericParameters.Count; } - } + int IGenericParameterProvider.NumberOfGenericParameters => GenericParameters.Count; /// - string IType.TypeName { - get { return FullNameCreator.Name(this, false, null); } - } + string IType.TypeName => FullNameCreator.Name(this, false, null); /// - public string ReflectionName { - get { return FullNameCreator.Name(this, true, null); } - } + public string ReflectionName => FullNameCreator.Name(this, true, null); /// - string IType.Namespace { - get { return FullNameCreator.Namespace(this, false, null); } - } + string IType.Namespace => FullNameCreator.Namespace(this, false, null); /// - public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true, null); } - } + public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); /// - public string FullName { - get { return FullNameCreator.FullName(this, false, null, null); } - } + public string FullName => FullNameCreator.FullName(this, false, null, null); /// - public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true, null, null); } - } + public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); /// - public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } - } + public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly { - get { return FullNameCreator.DefinitionAssembly(this); } - } + public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); /// - public IScope Scope { - get { return Module; } - } + public IScope Scope => Module; /// - public ITypeDefOrRef ScopeType { - get { return this; } - } + public ITypeDefOrRef ScopeType => this; /// /// Always returns false since a does not contain any /// or . /// - public bool ContainsGenericParameter { - get { return false; } - } + public bool ContainsGenericParameter => false; /// - public ModuleDef Module { - get { return FullNameCreator.OwnerModule(this); } - } + public ModuleDef Module => FullNameCreator.OwnerModule(this); /// /// Gets/sets the owner module @@ -172,68 +134,28 @@ void InitializeModule2() { } /// Called to initialize - protected virtual ModuleDef GetModule2_NoLock() { - return null; - } - - bool IIsTypeOrMethod.IsType { - get { return true; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return true; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + protected virtual ModuleDef GetModule2_NoLock() => null; + + bool IIsTypeOrMethod.IsType => true; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => true; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// /// From column TypeDef.Flags /// public TypeAttributes Attributes { - get { return (TypeAttributes)attributes; } - set { attributes = (int)value; } + get => (TypeAttributes)attributes; + set => attributes = (int)value; } /// Attributes protected int attributes; @@ -242,8 +164,8 @@ public TypeAttributes Attributes { /// From column TypeDef.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -252,8 +174,8 @@ public UTF8String Name { /// From column TypeDef.Namespace /// public UTF8String Namespace { - get { return @namespace; } - set { @namespace = value; } + get => @namespace; + set => @namespace = value; } /// Name protected UTF8String @namespace; @@ -297,14 +219,10 @@ void InitializeBaseType() { } /// Called to initialize - protected virtual ITypeDefOrRef GetBaseType_NoLock() { - return null; - } + protected virtual ITypeDefOrRef GetBaseType_NoLock() => null; /// Reset - protected void ResetBaseType() { - baseType_isInitialized = false; - } + protected void ResetBaseType() => baseType_isInitialized = false; /// /// From column TypeDef.FieldList @@ -319,9 +237,8 @@ public ThreadSafe.IList Fields { /// protected LazyList fields; /// Initializes - protected virtual void InitializeFields() { + protected virtual void InitializeFields() => Interlocked.CompareExchange(ref fields, new LazyList(this), null); - } /// /// From column TypeDef.MethodList @@ -336,9 +253,8 @@ public ThreadSafe.IList Methods { /// protected LazyList methods; /// Initializes - protected virtual void InitializeMethods() { + protected virtual void InitializeMethods() => Interlocked.CompareExchange(ref methods, new LazyList(this), null); - } /// public ThreadSafe.IList GenericParameters { @@ -351,9 +267,8 @@ public ThreadSafe.IList GenericParameters { /// protected LazyList genericParameters; /// Initializes - protected virtual void InitializeGenericParameters() { + protected virtual void InitializeGenericParameters() => Interlocked.CompareExchange(ref genericParameters, new LazyList(this), null); - } /// /// Gets the interfaces @@ -368,9 +283,8 @@ public ThreadSafe.IList Interfaces { /// protected ThreadSafe.IList interfaces; /// Initializes - protected virtual void InitializeInterfaces() { + protected virtual void InitializeInterfaces() => Interlocked.CompareExchange(ref interfaces, ThreadSafeListCreator.Create(), null); - } /// public ThreadSafe.IList DeclSecurities { @@ -383,9 +297,8 @@ public ThreadSafe.IList DeclSecurities { /// protected ThreadSafe.IList declSecurities; /// Initializes - protected virtual void InitializeDeclSecurities() { + protected virtual void InitializeDeclSecurities() => Interlocked.CompareExchange(ref declSecurities, ThreadSafeListCreator.Create(), null); - } /// /// Gets/sets the class layout @@ -433,14 +346,10 @@ ClassLayout GetOrCreateClassLayout() { } /// Called to initialize - protected virtual ClassLayout GetClassLayout_NoLock() { - return null; - } + protected virtual ClassLayout GetClassLayout_NoLock() => null; /// - public bool HasDeclSecurities { - get { return DeclSecurities.Count > 0; } - } + public bool HasDeclSecurities => DeclSecurities.Count > 0; /// /// Gets/sets the enclosing type. It's null if this isn't a nested class. @@ -466,9 +375,7 @@ public TypeDef DeclaringType { } /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return DeclaringType; } - } + ITypeDefOrRef IMemberRef.DeclaringType => DeclaringType; /// /// Called by and should normally not be called by any user @@ -511,9 +418,7 @@ void InitializeDeclaringType2() { } /// Called to initialize - protected virtual TypeDef GetDeclaringType2_NoLock() { - return null; - } + protected virtual TypeDef GetDeclaringType2_NoLock() => null; /// /// Gets all the nested types @@ -528,9 +433,8 @@ public ThreadSafe.IList NestedTypes { /// protected LazyList nestedTypes; /// Initializes - protected virtual void InitializeNestedTypes() { + protected virtual void InitializeNestedTypes() => Interlocked.CompareExchange(ref nestedTypes, new LazyList(this), null); - } /// /// Gets all events @@ -545,9 +449,8 @@ public ThreadSafe.IList Events { /// protected LazyList events; /// Initializes - protected virtual void InitializeEvents() { + protected virtual void InitializeEvents() => Interlocked.CompareExchange(ref events, new LazyList(this), null); - } /// /// Gets all properties @@ -562,9 +465,8 @@ public ThreadSafe.IList Properties { /// protected LazyList properties; /// Initializes - protected virtual void InitializeProperties() { + protected virtual void InitializeProperties() => Interlocked.CompareExchange(ref properties, new LazyList(this), null); - } /// /// Gets all custom attributes @@ -579,24 +481,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 3; } - } + public int HasCustomDebugInformationTag => 3; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -611,65 +506,48 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// true if there's at least one in /// - public bool HasFields { - get { return Fields.Count > 0; } - } + public bool HasFields => Fields.Count > 0; /// /// true if there's at least one in /// - public bool HasMethods { - get { return Methods.Count > 0; } - } + public bool HasMethods => Methods.Count > 0; /// /// true if there's at least one in /// - public bool HasGenericParameters { - get { return GenericParameters.Count > 0; } - } + public bool HasGenericParameters => GenericParameters.Count > 0; /// /// true if there's at least one in /// - public bool HasEvents { - get { return Events.Count > 0; } - } + public bool HasEvents => Events.Count > 0; /// /// true if there's at least one in /// - public bool HasProperties { - get { return Properties.Count > 0; } - } + public bool HasProperties => Properties.Count > 0; /// /// true if there's at least one in /// - public bool HasNestedTypes { - get { return NestedTypes.Count > 0; } - } + public bool HasNestedTypes => NestedTypes.Count > 0; /// /// true if there's at least one in /// - public bool HasInterfaces { - get { return Interfaces.Count > 0; } - } + public bool HasInterfaces => Interfaces.Count > 0; /// /// true if is not null /// - public bool HasClassLayout { - get { return ClassLayout != null; } - } + public bool HasClassLayout => ClassLayout != null; /// /// Gets/sets the packing size. If you write to this property but @@ -717,8 +595,7 @@ public bool IsValueType { // PERF: Don't allocate a System.String by calling FullName etc. UTF8String baseName, baseNamespace; - var baseTr = baseType as TypeRef; - if (baseTr != null) { + if (baseType is TypeRef baseTr) { baseName = baseTr.Name; baseNamespace = baseTr.Namespace; } @@ -760,11 +637,9 @@ public bool IsEnum { return false; // PERF: Don't allocate a System.String by calling FullName etc. - var baseTr = baseType as TypeRef; - if (baseTr != null) + if (baseType is TypeRef baseTr) return baseTr.Namespace == systemString && baseTr.Name == enumString; - var baseTd = baseType as TypeDef; - if (baseTd != null) + if (baseType is TypeDef baseTd) return baseTd.Namespace == systemString && baseTd.Name == enumString; return false; } @@ -784,11 +659,9 @@ public bool IsDelegate { return false; // PERF: Don't allocate a System.String by calling FullName etc. - var baseTr = baseType as TypeRef; - if (baseTr != null) + if (baseType is TypeRef baseTr) return baseTr.Namespace == systemString && baseTr.Name == multicastDelegateString; - var baseTd = baseType as TypeDef; - if (baseTd != null) + if (baseType is TypeDef baseTd) return baseTd.Namespace == systemString && baseTd.Name == multicastDelegateString; return false; } @@ -797,14 +670,10 @@ public bool IsDelegate { /// /// true if this is a nested type (it has a declaring type) /// - public bool IsNested { - get { return DeclaringType != null; } - } + public bool IsNested => DeclaringType != null; /// - public bool IsPrimitive { - get { return this.IsPrimitive(); } - } + public bool IsPrimitive => this.IsPrimitive(); /// /// Modify property: = @@ -852,225 +721,195 @@ void ModifyAttributes(bool set, TypeAttributes flags) { /// Gets/sets the visibility /// public TypeAttributes Visibility { - get { return (TypeAttributes)attributes & TypeAttributes.VisibilityMask; } - set { ModifyAttributes(~TypeAttributes.VisibilityMask, value & TypeAttributes.VisibilityMask); } + get => (TypeAttributes)attributes & TypeAttributes.VisibilityMask; + set => ModifyAttributes(~TypeAttributes.VisibilityMask, value & TypeAttributes.VisibilityMask); } /// /// true if is set /// - public bool IsNotPublic { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; } - } + public bool IsNotPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; /// /// true if is set /// - public bool IsPublic { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; } - } + public bool IsPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; /// /// true if is set /// - public bool IsNestedPublic { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; } - } + public bool IsNestedPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; /// /// true if is set /// - public bool IsNestedPrivate { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; } - } + public bool IsNestedPrivate => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; /// /// true if is set /// - public bool IsNestedFamily { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; } - } + public bool IsNestedFamily => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; /// /// true if is set /// - public bool IsNestedAssembly { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; } - } + public bool IsNestedAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; /// /// true if is set /// - public bool IsNestedFamilyAndAssembly { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; } - } + public bool IsNestedFamilyAndAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; /// /// true if is set /// - public bool IsNestedFamilyOrAssembly { - get { return ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; } - } + public bool IsNestedFamilyOrAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; /// /// Gets/sets the layout /// public TypeAttributes Layout { - get { return (TypeAttributes)attributes & TypeAttributes.LayoutMask; } - set { ModifyAttributes(~TypeAttributes.LayoutMask, value & TypeAttributes.LayoutMask); } + get => (TypeAttributes)attributes & TypeAttributes.LayoutMask; + set => ModifyAttributes(~TypeAttributes.LayoutMask, value & TypeAttributes.LayoutMask); } /// /// true if is set /// - public bool IsAutoLayout { - get { return ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; } - } + public bool IsAutoLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; /// /// true if is set /// - public bool IsSequentialLayout { - get { return ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; } - } + public bool IsSequentialLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; /// /// true if is set /// - public bool IsExplicitLayout { - get { return ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; } - } + public bool IsExplicitLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; /// /// Gets/sets the bit /// public bool IsInterface { - get { return ((TypeAttributes)attributes & TypeAttributes.Interface) != 0; } - set { ModifyAttributes(value, TypeAttributes.Interface); } + get => ((TypeAttributes)attributes & TypeAttributes.Interface) != 0; + set => ModifyAttributes(value, TypeAttributes.Interface); } /// /// Gets/sets the bit /// public bool IsClass { - get { return ((TypeAttributes)attributes & TypeAttributes.Interface) == 0; } - set { ModifyAttributes(!value, TypeAttributes.Interface); } + get => ((TypeAttributes)attributes & TypeAttributes.Interface) == 0; + set => ModifyAttributes(!value, TypeAttributes.Interface); } /// /// Gets/sets the bit /// public bool IsAbstract { - get { return ((TypeAttributes)attributes & TypeAttributes.Abstract) != 0; } - set { ModifyAttributes(value, TypeAttributes.Abstract); } + get => ((TypeAttributes)attributes & TypeAttributes.Abstract) != 0; + set => ModifyAttributes(value, TypeAttributes.Abstract); } /// /// Gets/sets the bit /// public bool IsSealed { - get { return ((TypeAttributes)attributes & TypeAttributes.Sealed) != 0; } - set { ModifyAttributes(value, TypeAttributes.Sealed); } + get => ((TypeAttributes)attributes & TypeAttributes.Sealed) != 0; + set => ModifyAttributes(value, TypeAttributes.Sealed); } /// /// Gets/sets the bit /// public bool IsSpecialName { - get { return ((TypeAttributes)attributes & TypeAttributes.SpecialName) != 0; } - set { ModifyAttributes(value, TypeAttributes.SpecialName); } + get => ((TypeAttributes)attributes & TypeAttributes.SpecialName) != 0; + set => ModifyAttributes(value, TypeAttributes.SpecialName); } /// /// Gets/sets the bit /// public bool IsImport { - get { return ((TypeAttributes)attributes & TypeAttributes.Import) != 0; } - set { ModifyAttributes(value, TypeAttributes.Import); } + get => ((TypeAttributes)attributes & TypeAttributes.Import) != 0; + set => ModifyAttributes(value, TypeAttributes.Import); } /// /// Gets/sets the bit /// public bool IsSerializable { - get { return ((TypeAttributes)attributes & TypeAttributes.Serializable) != 0; } - set { ModifyAttributes(value, TypeAttributes.Serializable); } + get => ((TypeAttributes)attributes & TypeAttributes.Serializable) != 0; + set => ModifyAttributes(value, TypeAttributes.Serializable); } /// /// Gets/sets the bit /// public bool IsWindowsRuntime { - get { return ((TypeAttributes)attributes & TypeAttributes.WindowsRuntime) != 0; } - set { ModifyAttributes(value, TypeAttributes.WindowsRuntime); } + get => ((TypeAttributes)attributes & TypeAttributes.WindowsRuntime) != 0; + set => ModifyAttributes(value, TypeAttributes.WindowsRuntime); } /// /// Gets/sets the string format /// public TypeAttributes StringFormat { - get { return (TypeAttributes)attributes & TypeAttributes.StringFormatMask; } - set { ModifyAttributes(~TypeAttributes.StringFormatMask, value & TypeAttributes.StringFormatMask); } + get => (TypeAttributes)attributes & TypeAttributes.StringFormatMask; + set => ModifyAttributes(~TypeAttributes.StringFormatMask, value & TypeAttributes.StringFormatMask); } /// /// true if is set /// - public bool IsAnsiClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; } - } + public bool IsAnsiClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; /// /// true if is set /// - public bool IsUnicodeClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; } - } + public bool IsUnicodeClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; /// /// true if is set /// - public bool IsAutoClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; } - } + public bool IsAutoClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; /// /// true if is set /// - public bool IsCustomFormatClass { - get { return ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.CustomFormatClass; } - } + public bool IsCustomFormatClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.CustomFormatClass; /// /// Gets/sets the bit /// public bool IsBeforeFieldInit { - get { return ((TypeAttributes)attributes & TypeAttributes.BeforeFieldInit) != 0; } - set { ModifyAttributes(value, TypeAttributes.BeforeFieldInit); } + get => ((TypeAttributes)attributes & TypeAttributes.BeforeFieldInit) != 0; + set => ModifyAttributes(value, TypeAttributes.BeforeFieldInit); } /// /// Gets/sets the bit /// public bool IsForwarder { - get { return ((TypeAttributes)attributes & TypeAttributes.Forwarder) != 0; } - set { ModifyAttributes(value, TypeAttributes.Forwarder); } + get => ((TypeAttributes)attributes & TypeAttributes.Forwarder) != 0; + set => ModifyAttributes(value, TypeAttributes.Forwarder); } /// /// Gets/sets the bit /// public bool IsRuntimeSpecialName { - get { return ((TypeAttributes)attributes & TypeAttributes.RTSpecialName) != 0; } - set { ModifyAttributes(value, TypeAttributes.RTSpecialName); } + get => ((TypeAttributes)attributes & TypeAttributes.RTSpecialName) != 0; + set => ModifyAttributes(value, TypeAttributes.RTSpecialName); } /// /// Gets/sets the bit /// public bool HasSecurity { - get { return ((TypeAttributes)attributes & TypeAttributes.HasSecurity) != 0; } - set { ModifyAttributes(value, TypeAttributes.HasSecurity); } + get => ((TypeAttributes)attributes & TypeAttributes.HasSecurity) != 0; + set => ModifyAttributes(value, TypeAttributes.HasSecurity); } /// @@ -1086,9 +925,7 @@ public bool IsGlobalModuleType { /// /// Gets a list of all nested types and all their nested types /// - public IEnumerable GetTypes() { - return AllTypesHelper.Types(NestedTypes); - } + public IEnumerable GetTypes() => AllTypesHelper.Types(NestedTypes); /// /// Gets an enum's underlying type or null if none. Should only be called @@ -1112,9 +949,7 @@ public TypeSig GetEnumUnderlyingType() { /// A method/field reference /// A or a instance or null /// if it couldn't be resolved. - public IMemberForwarded Resolve(MemberRef memberRef) { - return Resolve(memberRef, 0); - } + public IMemberForwarded Resolve(MemberRef memberRef) => Resolve(memberRef, 0); /// /// Resolves a method or a field. (owner type) is ignored when @@ -1145,9 +980,7 @@ public IMemberForwarded Resolve(MemberRef memberRef, SigComparerOptions options) /// Method name /// Method signature /// The first method that matches or null if none found - public MethodDef FindMethod(UTF8String name, MethodSig sig) { - return FindMethod(name, sig, 0, null); - } + public MethodDef FindMethod(UTF8String name, MethodSig sig) => FindMethod(name, sig, 0, null); /// /// Finds a method @@ -1156,9 +989,7 @@ public MethodDef FindMethod(UTF8String name, MethodSig sig) { /// Method signature /// Method signature comparison options /// The first method that matches or null if none found - public MethodDef FindMethod(UTF8String name, MethodSig sig, SigComparerOptions options) { - return FindMethod(name, sig, options, null); - } + public MethodDef FindMethod(UTF8String name, MethodSig sig, SigComparerOptions options) => FindMethod(name, sig, options, null); /// /// Finds a method @@ -1213,9 +1044,7 @@ public IEnumerable FindMethods(UTF8String name) { /// Finds the class constructor (aka type initializer). It's the method named .cctor /// /// The class constructor or null if none found - public MethodDef FindStaticConstructor() { - return Methods.ExecuteLocked(null, (tsList, arg) => FindStaticConstructor_NoMethodsLock()); - } + public MethodDef FindStaticConstructor() => Methods.ExecuteLocked(null, (tsList, arg) => FindStaticConstructor_NoMethodsLock()); MethodDef FindStaticConstructor_NoMethodsLock() { foreach (var method in Methods.GetEnumerable_NoLock()) { @@ -1300,9 +1129,7 @@ public MethodDef FindDefaultConstructor() { /// Field name /// Field signature /// The first field that matches or null if none found - public FieldDef FindField(UTF8String name, FieldSig sig) { - return FindField(name, sig, 0, null); - } + public FieldDef FindField(UTF8String name, FieldSig sig) => FindField(name, sig, 0, null); /// /// Finds a field @@ -1311,9 +1138,7 @@ public FieldDef FindField(UTF8String name, FieldSig sig) { /// Field signature /// Field signature comparison options /// The first field that matches or null if none found - public FieldDef FindField(UTF8String name, FieldSig sig, SigComparerOptions options) { - return FindField(name, sig, options, null); - } + public FieldDef FindField(UTF8String name, FieldSig sig, SigComparerOptions options) => FindField(name, sig, options, null); /// /// Finds a field @@ -1370,9 +1195,7 @@ public IEnumerable FindFields(UTF8String name) { /// Name of event /// Type of event /// A or null if not found - public EventDef FindEvent(UTF8String name, IType type) { - return FindEvent(name, type, 0, null); - } + public EventDef FindEvent(UTF8String name, IType type) => FindEvent(name, type, 0, null); /// /// Finds an event @@ -1381,9 +1204,7 @@ public EventDef FindEvent(UTF8String name, IType type) { /// Type of event /// Event type comparison options /// A or null if not found - public EventDef FindEvent(UTF8String name, IType type, SigComparerOptions options) { - return FindEvent(name, type, options, null); - } + public EventDef FindEvent(UTF8String name, IType type, SigComparerOptions options) => FindEvent(name, type, options, null); /// /// Finds an event @@ -1437,9 +1258,7 @@ public IEnumerable FindEvents(UTF8String name) { /// Name of property /// Property signature /// A or null if not found - public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig) { - return FindProperty(name, propSig, 0, null); - } + public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig) => FindProperty(name, propSig, 0, null); /// /// Finds a property @@ -1448,9 +1267,7 @@ public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig) { /// Property signature /// Property signature comparison options /// A or null if not found - public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig, SigComparerOptions options) { - return FindProperty(name, propSig, options, null); - } + public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig, SigComparerOptions options) => FindProperty(name, propSig, options, null); /// /// Finds a property @@ -1504,9 +1321,7 @@ public IEnumerable FindProperties(UTF8String name) { /// Method name /// Method signature /// The method or null if it wasn't found - public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig) { - return FindMethodCheckBaseType(name, sig, 0, null); - } + public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig) => FindMethodCheckBaseType(name, sig, 0, null); /// /// Finds a method by checking this type or any of its base types @@ -1515,9 +1330,7 @@ public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig) { /// Method signature /// Method signature comparison options /// The method or null if it wasn't found - public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig, SigComparerOptions options) { - return FindMethodCheckBaseType(name, sig, options, null); - } + public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig, SigComparerOptions options) => FindMethodCheckBaseType(name, sig, options, null); /// /// Finds a method by checking this type or any of its base types @@ -1560,9 +1373,7 @@ public MethodDef FindMethodCheckBaseType(UTF8String name) { /// Field name /// Field signature /// The field or null if it wasn't found - public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig) { - return FindFieldCheckBaseType(name, sig, 0, null); - } + public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig) => FindFieldCheckBaseType(name, sig, 0, null); /// /// Finds a field by checking this type or any of its base types @@ -1571,9 +1382,7 @@ public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig) { /// Field signature /// Field signature comparison options /// The field or null if it wasn't found - public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig, SigComparerOptions options) { - return FindFieldCheckBaseType(name, sig, options, null); - } + public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig, SigComparerOptions options) => FindFieldCheckBaseType(name, sig, options, null); /// /// Finds a field by checking this type or any of its base types @@ -1649,9 +1458,7 @@ public EventDef FindEventCheckBaseType(UTF8String name) { /// Property name /// Property signature /// The property or null if it wasn't found - public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig) { - return FindPropertyCheckBaseType(name, sig, 0, null); - } + public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig) => FindPropertyCheckBaseType(name, sig, 0, null); /// /// Finds a property by checking this type or any of its base types @@ -1660,9 +1467,7 @@ public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig) { /// Property signature /// Property signature comparison options /// The property or null if it wasn't found - public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, SigComparerOptions options) { - return FindPropertyCheckBaseType(name, sig, options, null); - } + public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, SigComparerOptions options) => FindPropertyCheckBaseType(name, sig, options, null); /// /// Finds a property by checking this type or any of its base types @@ -1703,9 +1508,7 @@ public PropertyDef FindPropertyCheckBaseType(UTF8String name) { /// Removes a method from this type. It also removes it from any properties and events. /// /// The method to remove - public void Remove(MethodDef method) { - Remove(method, false); - } + public void Remove(MethodDef method) => Remove(method, false); /// /// Removes a method from this type. It also removes it from any properties and events. @@ -1741,24 +1544,20 @@ public void Remove(MethodDef method, bool removeEmptyPropertiesEvents) { Methods.Remove(method); } - void RemoveEmptyProperties() { + void RemoveEmptyProperties() => Properties.IterateAllReverse((tsList, index, value) => { if (value.IsEmpty) tsList.RemoveAt_NoLock(index); }); - } - void RemoveEmptyEvents() { + void RemoveEmptyEvents() => Events.IterateAllReverse((tsList, index, value) => { if (value.IsEmpty) tsList.RemoveAt_NoLock(index); }); - } /// - void IListListener.OnLazyAdd(int index, ref FieldDef value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref FieldDef value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref FieldDef value) { #if DEBUG @@ -1775,9 +1574,7 @@ void IListListener.OnAdd(int index, FieldDef value) { } /// - void IListListener.OnRemove(int index, FieldDef value) { - value.DeclaringType2 = null; - } + void IListListener.OnRemove(int index, FieldDef value) => value.DeclaringType2 = null; /// void IListListener.OnResize(int index) { @@ -1790,9 +1587,7 @@ void IListListener.OnClear() { } /// - void IListListener.OnLazyAdd(int index, ref MethodDef value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref MethodDef value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref MethodDef value) { #if DEBUG @@ -1863,9 +1658,7 @@ void IListListener.OnClear() { } /// - void IListListener.OnLazyAdd(int index, ref EventDef value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref EventDef value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref EventDef value) { #if DEBUG @@ -1882,9 +1675,7 @@ void IListListener.OnAdd(int index, EventDef value) { } /// - void IListListener.OnRemove(int index, EventDef value) { - value.DeclaringType2 = null; - } + void IListListener.OnRemove(int index, EventDef value) => value.DeclaringType2 = null; /// void IListListener.OnResize(int index) { @@ -1897,9 +1688,7 @@ void IListListener.OnClear() { } /// - void IListListener.OnLazyAdd(int index, ref PropertyDef value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref PropertyDef value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref PropertyDef value) { #if DEBUG @@ -1916,9 +1705,7 @@ void IListListener.OnAdd(int index, PropertyDef value) { } /// - void IListListener.OnRemove(int index, PropertyDef value) { - value.DeclaringType2 = null; - } + void IListListener.OnRemove(int index, PropertyDef value) => value.DeclaringType2 = null; /// void IListListener.OnResize(int index) { @@ -1931,9 +1718,7 @@ void IListListener.OnClear() { } /// - void IListListener.OnLazyAdd(int index, ref GenericParam value) { - OnLazyAdd2(index, ref value); - } + void IListListener.OnLazyAdd(int index, ref GenericParam value) => OnLazyAdd2(index, ref value); internal virtual void OnLazyAdd2(int index, ref GenericParam value) { #if DEBUG @@ -1950,9 +1735,7 @@ void IListListener.OnAdd(int index, GenericParam value) { } /// - void IListListener.OnRemove(int index, GenericParam value) { - value.Owner = null; - } + void IListListener.OnRemove(int index, GenericParam value) => value.Owner = null; /// void IListListener.OnResize(int index) { @@ -2026,8 +1809,7 @@ internal static bool GetClassSize(TypeDef td, out uint size) { /// protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { // Check common case first - var md = mdr as MethodDef; - if (md != null) + if (mdr is MethodDef md) return md; // Must be a member ref @@ -2058,8 +1840,7 @@ protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { // If it's a TypeRef, resolve it as if it is a reference to a type in the // current module, even if its ResolutionScope happens to be some other // assembly/module (that's what the CLR does) - var tr = parent as TypeRef; - if (tr != null && Module != null) + if (parent is TypeRef tr && Module != null) td = Module.Find(tr); } if (td == null) @@ -2068,9 +1849,7 @@ protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -2110,16 +1889,16 @@ public TypeDefUser(UTF8String name, ITypeDefOrRef baseType) /// Name /// Base class or null if it's an interface public TypeDefUser(UTF8String @namespace, UTF8String name, ITypeDefOrRef baseType) { - this.fields = new LazyList(this); - this.methods = new LazyList(this); - this.genericParameters = new LazyList(this); - this.nestedTypes = new LazyList(this); - this.events = new LazyList(this); - this.properties = new LazyList(this); + fields = new LazyList(this); + methods = new LazyList(this); + genericParameters = new LazyList(this); + nestedTypes = new LazyList(this); + events = new LazyList(this); + properties = new LazyList(this); this.@namespace = @namespace; this.name = name; this.baseType = baseType; - this.baseType_isInitialized = true; + baseType_isInitialized = true; } } @@ -2135,14 +1914,10 @@ sealed class TypeDefMD : TypeDef, IMDTokenProviderMD { Dictionary> methodRidToOverrides; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// - protected override ITypeDefOrRef GetBaseType_NoLock() { - return readerModule.ResolveTypeDefOrRef(extendsCodedToken, new GenericParamContext(this)); - } + protected override ITypeDefOrRef GetBaseType_NoLock() => readerModule.ResolveTypeDefOrRef(extendsCodedToken, new GenericParamContext(this)); /// protected override void InitializeFields() { @@ -2180,9 +1955,7 @@ protected override void InitializeDeclSecurities() { } /// - protected override ClassLayout GetClassLayout_NoLock() { - return readerModule.ResolveClassLayout(readerModule.MetaData.GetClassLayoutRid(origRid)); - } + protected override ClassLayout GetClassLayout_NoLock() => readerModule.ResolveClassLayout(readerModule.MetaData.GetClassLayoutRid(origRid)); /// protected override TypeDef GetDeclaringType2_NoLock() { @@ -2238,9 +2011,7 @@ protected override void InitializeCustomDebugInfos() { } /// - protected override ModuleDef GetModule2_NoLock() { - return DeclaringType2_NoLock != null ? null : readerModule; - } + protected override ModuleDef GetModule2_NoLock() => DeclaringType2_NoLock != null ? null : readerModule; /// /// Constructor @@ -2254,13 +2025,12 @@ public TypeDefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.TypeDefTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("TypeDef rid {0} does not exist", rid)); + throw new BadImageFormatException($"TypeDef rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - uint name, @namespace; - extendsCodedToken = readerModule.TablesStream.ReadTypeDefRow(origRid, out this.attributes, out name, out @namespace); + extendsCodedToken = readerModule.TablesStream.ReadTypeDefRow(origRid, out attributes, out uint name, out uint @namespace); this.name = readerModule.StringsStream.ReadNoNull(name); this.@namespace = readerModule.StringsStream.ReadNoNull(@namespace); } @@ -2278,8 +2048,7 @@ internal ThreadSafe.IList GetMethodOverrides(MethodDefMD method, if (methodRidToOverrides == null) InitializeMethodOverrides(); - ThreadSafe.IList overrides; - if (methodRidToOverrides.TryGetValue(method.OrigRid, out overrides)) { + if (methodRidToOverrides.TryGetValue(method.OrigRid, out var overrides)) { var newList = ThreadSafeListCreator.Create(overrides.Count); for (int i = 0; i < overrides.Count; i++) { @@ -2293,13 +2062,13 @@ internal ThreadSafe.IList GetMethodOverrides(MethodDefMD method, return ThreadSafeListCreator.Create(); } - struct MethodOverrideTokens { + readonly struct MethodOverrideTokens { public readonly uint MethodBodyToken; public readonly uint MethodDeclarationToken; public MethodOverrideTokens(uint methodBodyToken, uint methodDeclarationToken) { - this.MethodBodyToken = methodBodyToken; - this.MethodDeclarationToken = methodDeclarationToken; + MethodBodyToken = methodBodyToken; + MethodDeclarationToken = methodDeclarationToken; } } @@ -2308,8 +2077,7 @@ void InitializeMethodOverrides() { var ridList = readerModule.MetaData.GetMethodImplRidList(origRid); for (uint i = 0; i < ridList.Length; i++) { - uint methodBodyToken; - uint methodDeclToken = readerModule.TablesStream.ReadMethodImplRow(ridList[i], out methodBodyToken); + uint methodDeclToken = readerModule.TablesStream.ReadMethodImplRow(ridList[i], out uint methodBodyToken); var methodBody = readerModule.ResolveMethodDefOrRef(methodBodyToken); var methodDecl = readerModule.ResolveMethodDefOrRef(methodDeclToken); @@ -2323,9 +2091,8 @@ void InitializeMethodOverrides() { if (method == null || method.DeclaringType != this) continue; - ThreadSafe.IList overrides; uint rid = method.Rid; - if (!newMethodRidToOverrides.TryGetValue(rid, out overrides)) + if (!newMethodRidToOverrides.TryGetValue(rid, out var overrides)) newMethodRidToOverrides[rid] = overrides = ThreadSafeListCreator.Create(); overrides.Add(new MethodOverrideTokens(methodBody.MDToken.Raw, methodDecl.MDToken.Raw)); } @@ -2342,8 +2109,7 @@ internal void InitializeMethodSemanticsAttributes() { for (uint i = 0; i < list.Length; i++) { var ridList = readerModule.MetaData.GetMethodSemanticsRidList(Table.Property, list[i]); for (uint j = 0; j < ridList.Length; j++) { - MethodSemanticsAttributes semantics; - uint methodToken = readerModule.TablesStream.ReadMethodSemanticsRow(ridList[j], out semantics); + uint methodToken = readerModule.TablesStream.ReadMethodSemanticsRow(ridList[j], out var semantics); var method = readerModule.ResolveMethod(methodToken); if (method == null) continue; @@ -2357,8 +2123,7 @@ internal void InitializeMethodSemanticsAttributes() { for (uint i = 0; i < list.Length; i++) { var ridList = readerModule.MetaData.GetMethodSemanticsRidList(Table.Event, list[i]); for (uint j = 0; j < ridList.Length; j++) { - MethodSemanticsAttributes semantics; - uint methodToken = readerModule.TablesStream.ReadMethodSemanticsRow(ridList[j], out semantics); + uint methodToken = readerModule.TablesStream.ReadMethodSemanticsRow(ridList[j], out var semantics); var method = readerModule.ResolveMethod(methodToken); if (method == null) continue; @@ -2384,8 +2149,7 @@ internal void InitializeProperty(PropertyDefMD prop, out ThreadSafe.IList isCacheEnabled; set { if (isCacheEnabled == value) return; @@ -87,9 +87,7 @@ public TypeDefFinder(IEnumerable rootTypes) /// from should also be included. /// If is null public TypeDefFinder(IEnumerable rootTypes, bool includeNestedTypes) { - if (rootTypes == null) - throw new ArgumentNullException("rootTypes"); - this.rootTypes = rootTypes; + this.rootTypes = rootTypes ?? throw new ArgumentNullException(nameof(rootTypes)); this.includeNestedTypes = includeNestedTypes; } @@ -146,8 +144,7 @@ public TypeDef Find(TypeRef typeRef) { } TypeDef FindCache(TypeRef typeRef) { - TypeDef cachedType; - if (typeRefCache.TryGetValue(typeRef, out cachedType)) + if (typeRefCache.TryGetValue(typeRef, out var cachedType)) return cachedType; // Build the cache lazily @@ -160,8 +157,7 @@ TypeDef FindCache(TypeRef typeRef) { } TypeDef FindCacheReflection(string fullName) { - TypeDef cachedType; - if (reflectionNameCache.TryGetValue(fullName, out cachedType)) + if (reflectionNameCache.TryGetValue(fullName, out var cachedType)) return cachedType; // Build the cache lazily @@ -176,8 +172,7 @@ TypeDef FindCacheReflection(string fullName) { } TypeDef FindCacheNormal(string fullName) { - TypeDef cachedType; - if (normalNameCache.TryGetValue(fullName, out cachedType)) + if (normalNameCache.TryGetValue(fullName, out var cachedType)) return cachedType; // Build the cache lazily diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index a0e665eb4..86dfb38ef 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -15,17 +15,9 @@ namespace dnlib.DotNet { struct TypeHelper { RecursionCounter recursionCounter; - internal static bool ContainsGenericParameter(StandAloneSig ss) { - return ss != null && TypeHelper.ContainsGenericParameter(ss.Signature); - } - - internal static bool ContainsGenericParameter(InterfaceImpl ii) { - return ii != null && TypeHelper.ContainsGenericParameter(ii.Interface); - } - - internal static bool ContainsGenericParameter(GenericParamConstraint gpc) { - return gpc != null && ContainsGenericParameter(gpc.Constraint); - } + internal static bool ContainsGenericParameter(StandAloneSig ss) => ss != null && TypeHelper.ContainsGenericParameter(ss.Signature); + internal static bool ContainsGenericParameter(InterfaceImpl ii) => ii != null && TypeHelper.ContainsGenericParameter(ii.Interface); + internal static bool ContainsGenericParameter(GenericParamConstraint gpc) => gpc != null && ContainsGenericParameter(gpc.Constraint); internal static bool ContainsGenericParameter(MethodSpec ms) { if (ms == null) @@ -45,12 +37,10 @@ internal static bool ContainsGenericParameter(MemberRef mr) { var cl = mr.Class; - var tdr = cl as ITypeDefOrRef; - if (tdr != null) + if (cl is ITypeDefOrRef tdr) return tdr.ContainsGenericParameter; - var md = cl as MethodDef; - if (md != null) + if (cl is MethodDef md) return TypeHelper.ContainsGenericParameter(md.Signature); return false; @@ -64,20 +54,16 @@ internal static bool ContainsGenericParameter(MemberRef mr) { /// true if contains a /// or a . public static bool ContainsGenericParameter(CallingConventionSig callConv) { - var fs = callConv as FieldSig; - if (fs != null) + if (callConv is FieldSig fs) return ContainsGenericParameter(fs); - var mbs = callConv as MethodBaseSig; - if (mbs != null) + if (callConv is MethodBaseSig mbs) return ContainsGenericParameter(mbs); - var ls = callConv as LocalSig; - if (ls != null) + if (callConv is LocalSig ls) return ContainsGenericParameter(ls); - var gim = callConv as GenericInstMethodSig; - if (gim != null) + if (callConv is GenericInstMethodSig gim) return ContainsGenericParameter(gim); return false; @@ -90,9 +76,7 @@ public static bool ContainsGenericParameter(CallingConventionSig callConv) { /// Field signature /// true if contains a /// or a . - public static bool ContainsGenericParameter(FieldSig fieldSig) { - return new TypeHelper().ContainsGenericParameterInternal(fieldSig); - } + public static bool ContainsGenericParameter(FieldSig fieldSig) => new TypeHelper().ContainsGenericParameterInternal(fieldSig); /// /// Checks whether contains a or a @@ -101,9 +85,7 @@ public static bool ContainsGenericParameter(FieldSig fieldSig) { /// Method or property signature /// true if contains a /// or a . - public static bool ContainsGenericParameter(MethodBaseSig methodSig) { - return new TypeHelper().ContainsGenericParameterInternal(methodSig); - } + public static bool ContainsGenericParameter(MethodBaseSig methodSig) => new TypeHelper().ContainsGenericParameterInternal(methodSig); /// /// Checks whether contains a or a @@ -112,9 +94,7 @@ public static bool ContainsGenericParameter(MethodBaseSig methodSig) { /// Local signature /// true if contains a /// or a . - public static bool ContainsGenericParameter(LocalSig localSig) { - return new TypeHelper().ContainsGenericParameterInternal(localSig); - } + public static bool ContainsGenericParameter(LocalSig localSig) => new TypeHelper().ContainsGenericParameterInternal(localSig); /// /// Checks whether contains a or a @@ -123,9 +103,7 @@ public static bool ContainsGenericParameter(LocalSig localSig) { /// Generic method signature /// true if contains a /// or a . - public static bool ContainsGenericParameter(GenericInstMethodSig gim) { - return new TypeHelper().ContainsGenericParameterInternal(gim); - } + public static bool ContainsGenericParameter(GenericInstMethodSig gim) => new TypeHelper().ContainsGenericParameterInternal(gim); /// /// Checks whether contains a or a @@ -135,24 +113,19 @@ public static bool ContainsGenericParameter(GenericInstMethodSig gim) { /// true if contains a or a /// . public static bool ContainsGenericParameter(IType type) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return ContainsGenericParameter(td); - var tr = type as TypeRef; - if (tr != null) + if (type is TypeRef tr) return ContainsGenericParameter(tr); - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return ContainsGenericParameter(ts); - var sig = type as TypeSig; - if (sig != null) + if (type is TypeSig sig) return ContainsGenericParameter(sig); - var et = type as ExportedType; - if (et != null) + if (type is ExportedType et) return ContainsGenericParameter(et); return false; @@ -165,9 +138,7 @@ public static bool ContainsGenericParameter(IType type) { /// Type /// true if contains a or a /// . - public static bool ContainsGenericParameter(TypeDef type) { - return new TypeHelper().ContainsGenericParameterInternal(type); - } + public static bool ContainsGenericParameter(TypeDef type) => new TypeHelper().ContainsGenericParameterInternal(type); /// /// Checks whether contains a or a @@ -176,9 +147,7 @@ public static bool ContainsGenericParameter(TypeDef type) { /// Type /// true if contains a or a /// . - public static bool ContainsGenericParameter(TypeRef type) { - return new TypeHelper().ContainsGenericParameterInternal(type); - } + public static bool ContainsGenericParameter(TypeRef type) => new TypeHelper().ContainsGenericParameterInternal(type); /// /// Checks whether contains a or a @@ -187,9 +156,7 @@ public static bool ContainsGenericParameter(TypeRef type) { /// Type /// true if contains a or a /// . - public static bool ContainsGenericParameter(TypeSpec type) { - return new TypeHelper().ContainsGenericParameterInternal(type); - } + public static bool ContainsGenericParameter(TypeSpec type) => new TypeHelper().ContainsGenericParameterInternal(type); /// /// Checks whether contains a or a @@ -198,9 +165,7 @@ public static bool ContainsGenericParameter(TypeSpec type) { /// Type /// true if contains a or a /// . - public static bool ContainsGenericParameter(TypeSig type) { - return new TypeHelper().ContainsGenericParameterInternal(type); - } + public static bool ContainsGenericParameter(TypeSig type) => new TypeHelper().ContainsGenericParameterInternal(type); /// /// Checks whether contains a or a @@ -209,17 +174,11 @@ public static bool ContainsGenericParameter(TypeSig type) { /// Type /// true if contains a or a /// . - public static bool ContainsGenericParameter(ExportedType type) { - return new TypeHelper().ContainsGenericParameterInternal(type); - } + public static bool ContainsGenericParameter(ExportedType type) => new TypeHelper().ContainsGenericParameterInternal(type); - bool ContainsGenericParameterInternal(TypeDef type) { - return false; - } + bool ContainsGenericParameterInternal(TypeDef type) => false; - bool ContainsGenericParameterInternal(TypeRef type) { - return false; - } + bool ContainsGenericParameterInternal(TypeRef type) => false; bool ContainsGenericParameterInternal(TypeSpec type) { if (type == null) @@ -316,25 +275,19 @@ bool ContainsGenericParameterInternal(TypeSig type) { return res; } - bool ContainsGenericParameterInternal(ExportedType type) { - return false; - } + bool ContainsGenericParameterInternal(ExportedType type) => false; bool ContainsGenericParameterInternal(CallingConventionSig callConv) { - var fs = callConv as FieldSig; - if (fs != null) + if (callConv is FieldSig fs) return ContainsGenericParameterInternal(fs); - var mbs = callConv as MethodBaseSig; - if (mbs != null) + if (callConv is MethodBaseSig mbs) return ContainsGenericParameterInternal(mbs); - var ls = callConv as LocalSig; - if (ls != null) + if (callConv is LocalSig ls) return ContainsGenericParameterInternal(ls); - var gim = callConv as GenericInstMethodSig; - if (gim != null) + if (callConv is GenericInstMethodSig gim) return ContainsGenericParameterInternal(gim); return false; diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index 9122c9063..6d5b7f8b2 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -77,9 +77,8 @@ public abstract class TypeNameParser : IDisposable { /// Helper class /// A new instance /// If parsing failed - public static ITypeDefOrRef ParseReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) { - return ParseReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - } + public static ITypeDefOrRef ParseReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => + ParseReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); /// /// Parses a Reflection type name and creates a @@ -102,9 +101,8 @@ public static ITypeDefOrRef ParseReflectionThrow(ModuleDef ownerModule, string t /// Full name of type /// Helper class /// A new instance or null if parsing failed - public static ITypeDefOrRef ParseReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) { - return ParseReflection(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - } + public static ITypeDefOrRef ParseReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => + ParseReflection(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); /// /// Parses a Reflection type name and creates a @@ -131,9 +129,8 @@ public static ITypeDefOrRef ParseReflection(ModuleDef ownerModule, string typeFu /// Helper class /// A new instance /// If parsing failed - public static TypeSig ParseAsTypeSigReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) { - return ParseAsTypeSigReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - } + public static TypeSig ParseAsTypeSigReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => + ParseAsTypeSigReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); /// /// Parses a Reflection type name and creates a @@ -156,9 +153,8 @@ public static TypeSig ParseAsTypeSigReflectionThrow(ModuleDef ownerModule, strin /// Full name of type /// Helper class /// A new instance or null if parsing failed - public static TypeSig ParseAsTypeSigReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) { - return ParseAsTypeSigReflection(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - } + public static TypeSig ParseAsTypeSigReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => + ParseAsTypeSigReflection(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); /// /// Parses a Reflection type name and creates a @@ -196,7 +192,7 @@ protected TypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRe /// Generic parameter context protected TypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) { this.ownerModule = ownerModule; - this.reader = new StringReader(typeFullName ?? string.Empty); + reader = new StringReader(typeFullName ?? string.Empty); this.typeNameParserHelper = typeNameParserHelper; this.gpContext = gpContext; } @@ -206,9 +202,7 @@ protected TypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRe /// /// A new instance /// If parsing failed - internal ITypeDefOrRef Parse() { - return ownerModule.UpdateRowId(ParseAsTypeSig().ToTypeDefOrRef()); - } + internal ITypeDefOrRef Parse() => ownerModule.UpdateRowId(ParseAsTypeSig().ToTypeDefOrRef()); /// /// Parses a type name and creates a @@ -229,9 +223,7 @@ protected void RecursionIncrement() { /// /// Decrement recursion counter /// - protected void RecursionDecrement() { - recursionCounter.Decrement(); - } + protected void RecursionDecrement() => recursionCounter.Decrement(); /// public void Dispose() { @@ -254,9 +246,7 @@ protected virtual void Dispose(bool disposing) { internal abstract class TSpec { public readonly ElementType etype; - protected TSpec(ElementType etype) { - this.etype = etype; - } + protected TSpec(ElementType etype) => this.etype = etype; } internal sealed class SZArraySpec : TSpec { @@ -364,10 +354,9 @@ protected TypeRef ReadTypeRefAndNestedNoAssembly(char nestedChar) { /// /// A new instance protected TypeRef ReadTypeRefNoAssembly() { - string ns, name; // White space is important here. Any white space before the comma/EOF must be // parsed as part of the name. - GetNamespaceAndName(ReadId(false), out ns, out name); + GetNamespaceAndName(ReadId(false), out var ns, out var name); return ownerModule.UpdateRowId(new TypeRefUser(ownerModule, ns, name)); } @@ -384,22 +373,17 @@ static void GetNamespaceAndName(string fullName, out string ns, out string name) } internal TypeSig ToTypeSig(ITypeDefOrRef type) { - var td = type as TypeDef; - if (td != null) + if (type is TypeDef td) return ToTypeSig(td, td.IsValueType); - var tr = type as TypeRef; - if (tr != null) + if (type is TypeRef tr) return ToTypeSig(tr, IsValueType(tr)); - var ts = type as TypeSpec; - if (ts != null) + if (type is TypeSpec ts) return ts.TypeSig; Verify(false, "Unknown type"); return null; } - static TypeSig ToTypeSig(ITypeDefOrRef type, bool isValueType) { - return isValueType ? (TypeSig)new ValueTypeSig(type) : new ClassSig(type); - } + static TypeSig ToTypeSig(ITypeDefOrRef type, bool isValueType) => isValueType ? (TypeSig)new ValueTypeSig(type) : new ClassSig(type); internal AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { AssemblyRef asmRef = null; @@ -413,9 +397,7 @@ internal AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { return AssemblyRef.CurrentAssembly; } - internal bool IsValueType(TypeRef typeRef) { - return typeRef != null && typeRef.IsValueType; - } + internal bool IsValueType(TypeRef typeRef) => typeRef != null && typeRef.IsValueType; internal static void Verify(bool b, string msg) { if (!b) @@ -471,9 +453,7 @@ internal int ReadInt32() { } } - internal string ReadId() { - return ReadId(true); - } + internal string ReadId() => ReadId(true); internal string ReadId(bool ignoreWhiteSpace) { SkipWhite(); @@ -488,16 +468,12 @@ internal string ReadId(bool ignoreWhiteSpace) { /// /// Peeks the next char. -1 if no more chars. /// - protected int PeekChar() { - return reader.Peek(); - } + protected int PeekChar() => reader.Peek(); /// /// Gets the next char or -1 if no more chars /// - protected int ReadChar() { - return reader.Read(); - } + protected int ReadChar() => reader.Read(); /// /// Gets the next ID char or -1 if no more ID chars @@ -536,9 +512,7 @@ public ReflectionTypeNameParser(ModuleDef ownerModule, string typeFullName, IAss /// /// Full assembly name /// A new instance or null if parsing failed - public static AssemblyRef ParseAssemblyRef(string asmFullName) { - return ParseAssemblyRef(asmFullName, new GenericParamContext()); - } + public static AssemblyRef ParseAssemblyRef(string asmFullName) => ParseAssemblyRef(asmFullName, new GenericParamContext()); /// /// Parses an assembly name @@ -584,7 +558,7 @@ TypeSig ReadType(bool readAssemblyReference) { result = CreateTypeSig(tspecs, currentSig); } else { - TypeRef typeRef = ReadTypeRefAndNestedNoAssembly('+'); + var typeRef = ReadTypeRefAndNestedNoAssembly('+'); var tspecs = ReadTSpecs(); var nonNestedTypeRef = TypeRef.GetNonNestedTypeRef(typeRef); AssemblyRef asmRef; diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index 8881fad71..25b97216c 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -32,103 +32,67 @@ public abstract class TypeRef : ITypeDefOrRef, IHasCustomAttribute, IMemberRefPa #endif /// - public MDToken MDToken { - get { return new MDToken(Table.TypeRef, rid); } - } + public MDToken MDToken => new MDToken(Table.TypeRef, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int TypeDefOrRefTag { - get { return 1; } - } + public int TypeDefOrRefTag => 1; /// - public int HasCustomAttributeTag { - get { return 2; } - } + public int HasCustomAttributeTag => 2; /// - public int MemberRefParentTag { - get { return 1; } - } + public int MemberRefParentTag => 1; /// - public int ResolutionScopeTag { - get { return 3; } - } + public int ResolutionScopeTag => 3; /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { return 0; } - } + int IGenericParameterProvider.NumberOfGenericParameters => 0; /// - string IType.TypeName { - get { return FullNameCreator.Name(this, false, null); } - } + string IType.TypeName => FullNameCreator.Name(this, false, null); /// - public string ReflectionName { - get { return FullNameCreator.Name(this, true, null); } - } + public string ReflectionName => FullNameCreator.Name(this, true, null); /// - string IType.Namespace { - get { return FullNameCreator.Namespace(this, false, null); } - } + string IType.Namespace => FullNameCreator.Namespace(this, false, null); /// - public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true, null); } - } + public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); /// - public string FullName { - get { return FullNameCreator.FullName(this, false, null, null); } - } + public string FullName => FullNameCreator.FullName(this, false, null, null); /// - public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true, null, null); } - } + public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); /// - public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } - } + public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly { - get { return FullNameCreator.DefinitionAssembly(this); } - } + public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); /// - public IScope Scope { - get { return FullNameCreator.Scope(this); } - } + public IScope Scope => FullNameCreator.Scope(this); /// - public ITypeDefOrRef ScopeType { - get { return this; } - } + public ITypeDefOrRef ScopeType => this; /// /// Always returns false since a does not contain any /// or . /// - public bool ContainsGenericParameter { - get { return false; } - } + public bool ContainsGenericParameter => false; /// - public ModuleDef Module { - get { return module; } - } + public ModuleDef Module => module; /// /// From column TypeRef.ResolutionScope @@ -169,16 +133,14 @@ void InitializeResolutionScope() { } /// Called to initialize - protected virtual IResolutionScope GetResolutionScope_NoLock() { - return null; - } + protected virtual IResolutionScope GetResolutionScope_NoLock() => null; /// /// From column TypeRef.Name /// public UTF8String Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// Name protected UTF8String name; @@ -187,8 +149,8 @@ public UTF8String Name { /// From column TypeRef.Namespace /// public UTF8String Namespace { - get { return @namespace; } - set { @namespace = value; } + get => @namespace; + set => @namespace = value; } /// Name protected UTF8String @namespace; @@ -206,24 +168,17 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 2; } - } + public int HasCustomDebugInformationTag => 2; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -238,16 +193,13 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// /// true if it's nested within another /// - public bool IsNested { - get { return DeclaringType != null; } - } + public bool IsNested => DeclaringType != null; /// public bool IsValueType { @@ -258,81 +210,35 @@ public bool IsValueType { } /// - public bool IsPrimitive { - get { return this.IsPrimitive(); } - } + public bool IsPrimitive => this.IsPrimitive(); /// /// Gets the declaring type, if any /// - public TypeRef DeclaringType { - get { return ResolutionScope as TypeRef; } - } + public TypeRef DeclaringType => ResolutionScope as TypeRef; /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { return DeclaringType; } - } - - bool IIsTypeOrMethod.IsType { - get { return true; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return false; } - } - - bool IMemberRef.IsTypeRef { - get { return true; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + ITypeDefOrRef IMemberRef.DeclaringType => DeclaringType; + + bool IIsTypeOrMethod.IsType => true; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => false; + bool IMemberRef.IsTypeRef => true; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// /// Resolves the type /// /// A instance or null if it couldn't be resolved - public TypeDef Resolve() { - return Resolve(null); - } + public TypeDef Resolve() => Resolve(null); /// /// Resolves the type @@ -350,9 +256,7 @@ public TypeDef Resolve(ModuleDef sourceModule) { /// /// A instance /// If the type couldn't be resolved - public TypeDef ResolveThrow() { - return ResolveThrow(null); - } + public TypeDef ResolveThrow() => ResolveThrow(null); /// /// Resolves the type @@ -364,7 +268,7 @@ public TypeDef ResolveThrow(ModuleDef sourceModule) { var type = Resolve(sourceModule); if (type != null) return type; - throw new TypeResolveException(string.Format("Could not resolve type: {0} ({1})", this, DefinitionAssembly)); + throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); } /// @@ -385,9 +289,7 @@ internal static TypeRef GetNonNestedTypeRef(TypeRef typeRef) { } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -424,7 +326,7 @@ public TypeRefUser(ModuleDef module, UTF8String @namespace, UTF8String name) public TypeRefUser(ModuleDef module, UTF8String @namespace, UTF8String name, IResolutionScope resolutionScope) { this.module = module; this.resolutionScope = resolutionScope; - this.resolutionScope_isInitialized = true; + resolutionScope_isInitialized = true; this.name = name; this.@namespace = @namespace; } @@ -441,14 +343,10 @@ sealed class TypeRefMD : TypeRef, IMDTokenProviderMD { readonly uint resolutionScopeCodedToken; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// - protected override IResolutionScope GetResolutionScope_NoLock() { - return readerModule.ResolveResolutionScope(resolutionScopeCodedToken); - } + protected override IResolutionScope GetResolutionScope_NoLock() => readerModule.ResolveResolutionScope(resolutionScopeCodedToken); /// protected override void InitializeCustomAttributes() { @@ -476,17 +374,16 @@ public TypeRefMD(ModuleDefMD readerModule, uint rid) { if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.TypeRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("TypeRef rid {0} does not exist", rid)); + throw new BadImageFormatException($"TypeRef rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; - this.module = readerModule; - uint resolutionScope, name; - uint @namespace = readerModule.TablesStream.ReadTypeRefRow(origRid, out resolutionScope, out name); + module = readerModule; + uint @namespace = readerModule.TablesStream.ReadTypeRefRow(origRid, out uint resolutionScope, out uint name); this.name = readerModule.StringsStream.ReadNoNull(name); this.@namespace = readerModule.StringsStream.ReadNoNull(@namespace); - this.resolutionScopeCodedToken = resolutionScope; + resolutionScopeCodedToken = resolutionScope; } } } diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index d79c03d0b..b7a5fa3ad 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -60,25 +60,19 @@ public abstract class TypeSig : IType { public abstract ElementType ElementType { get; } /// - public MDToken MDToken { - get { return new MDToken(Table.TypeSpec, rid); } - } + public MDToken MDToken => new MDToken(Table.TypeSpec, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } + bool IIsTypeOrMethod.IsMethod => false; /// - bool IIsTypeOrMethod.IsType { - get { return true; } - } + bool IIsTypeOrMethod.IsType => true; /// int IGenericParameterProvider.NumberOfGenericParameters { @@ -105,230 +99,160 @@ public bool IsValueType { } /// - public bool IsPrimitive { - get { return ElementType.IsPrimitive(); } - } + public bool IsPrimitive => ElementType.IsPrimitive(); /// - public string TypeName { - get { return FullNameCreator.Name(this, false, null); } - } + public string TypeName => FullNameCreator.Name(this, false, null); /// UTF8String IFullName.Name { - get { return new UTF8String(FullNameCreator.Name(this, false, null)); } - set { throw new NotSupportedException(); } + get => new UTF8String(FullNameCreator.Name(this, false, null)); + set => throw new NotSupportedException(); } /// - public string ReflectionName { - get { return FullNameCreator.Name(this, true, null); } - } + public string ReflectionName => FullNameCreator.Name(this, true, null); /// - public string Namespace { - get { return FullNameCreator.Namespace(this, false, null); } - } + public string Namespace => FullNameCreator.Namespace(this, false, null); /// - public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true, null); } - } + public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); /// - public string FullName { - get { return FullNameCreator.FullName(this, false, null, null, null, null); } - } + public string FullName => FullNameCreator.FullName(this, false, null, null, null, null); /// - public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true, null, null, null, null); } - } + public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null, null, null); /// - public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } - } + public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly { - get { return FullNameCreator.DefinitionAssembly(this); } - } + public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); /// - public IScope Scope { - get { return FullNameCreator.Scope(this); } - } + public IScope Scope => FullNameCreator.Scope(this); /// - public ITypeDefOrRef ScopeType { - get { return FullNameCreator.ScopeType(this); } - } + public ITypeDefOrRef ScopeType => FullNameCreator.ScopeType(this); /// - public ModuleDef Module { - get { return FullNameCreator.OwnerModule(this); } - } + public ModuleDef Module => FullNameCreator.OwnerModule(this); /// /// true if it's a /// - public bool IsTypeDefOrRef { - get { return this is TypeDefOrRefSig; } - } + public bool IsTypeDefOrRef => this is TypeDefOrRefSig; /// /// true if it's a /// - public bool IsCorLibType { - get { return this is CorLibTypeSig; } - } + public bool IsCorLibType => this is CorLibTypeSig; /// /// true if it's a /// - public bool IsClassSig { - get { return this is ClassSig; } - } + public bool IsClassSig => this is ClassSig; /// /// true if it's a /// - public bool IsValueTypeSig { - get { return this is ValueTypeSig; } - } + public bool IsValueTypeSig => this is ValueTypeSig; /// /// true if it's a /// - public bool IsGenericParameter { - get { return this is GenericSig; } - } + public bool IsGenericParameter => this is GenericSig; /// /// true if it's a /// - public bool IsGenericTypeParameter { - get { return this is GenericVar; } - } + public bool IsGenericTypeParameter => this is GenericVar; /// /// true if it's a /// - public bool IsGenericMethodParameter { - get { return this is GenericMVar; } - } + public bool IsGenericMethodParameter => this is GenericMVar; /// /// true if it's a /// - public bool IsSentinel { - get { return this is SentinelSig; } - } + public bool IsSentinel => this is SentinelSig; /// /// true if it's a /// - public bool IsFunctionPointer { - get { return this is FnPtrSig; } - } + public bool IsFunctionPointer => this is FnPtrSig; /// /// true if it's a /// - public bool IsGenericInstanceType { - get { return this is GenericInstSig; } - } + public bool IsGenericInstanceType => this is GenericInstSig; /// /// true if it's a /// - public bool IsPointer { - get { return this is PtrSig; } - } + public bool IsPointer => this is PtrSig; /// /// true if it's a /// - public bool IsByRef { - get { return this is ByRefSig; } - } + public bool IsByRef => this is ByRefSig; /// /// true if it's a or a /// - public bool IsSingleOrMultiDimensionalArray { - get { return this is ArraySigBase; } - } + public bool IsSingleOrMultiDimensionalArray => this is ArraySigBase; /// /// true if it's a /// - public bool IsArray { - get { return this is ArraySig; } - } + public bool IsArray => this is ArraySig; /// /// true if it's a /// - public bool IsSZArray { - get { return this is SZArraySig; } - } + public bool IsSZArray => this is SZArraySig; /// /// true if it's a /// - public bool IsModifier { - get { return this is ModifierSig; } - } + public bool IsModifier => this is ModifierSig; /// /// true if it's a /// - public bool IsRequiredModifier { - get { return this is CModReqdSig; } - } + public bool IsRequiredModifier => this is CModReqdSig; /// /// true if it's a /// - public bool IsOptionalModifier { - get { return this is CModOptSig; } - } + public bool IsOptionalModifier => this is CModOptSig; /// /// true if it's a /// - public bool IsPinned { - get { return this is PinnedSig; } - } + public bool IsPinned => this is PinnedSig; /// /// true if it's a /// - public bool IsValueArray { - get { return this is ValueArraySig; } - } + public bool IsValueArray => this is ValueArraySig; /// /// true if it's a /// - public bool IsModuleSig { - get { return this is ModuleSig; } - } + public bool IsModuleSig => this is ModuleSig; /// /// true if this contains a or a /// . /// - public bool ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } public static partial class Extensions { @@ -378,9 +302,7 @@ public static TypeSig RemovePinnedAndModifiers(this TypeSig a) { /// The type /// A or null if it's not a /// - public static TypeDefOrRefSig ToTypeDefOrRefSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as TypeDefOrRefSig; - } + public static TypeDefOrRefSig ToTypeDefOrRefSig(this TypeSig type) => type.RemovePinnedAndModifiers() as TypeDefOrRefSig; /// /// Returns a @@ -388,9 +310,7 @@ public static TypeDefOrRefSig ToTypeDefOrRefSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static ClassOrValueTypeSig ToClassOrValueTypeSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as ClassOrValueTypeSig; - } + public static ClassOrValueTypeSig ToClassOrValueTypeSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ClassOrValueTypeSig; /// /// Returns a @@ -398,9 +318,7 @@ public static ClassOrValueTypeSig ToClassOrValueTypeSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static ValueTypeSig ToValueTypeSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as ValueTypeSig; - } + public static ValueTypeSig ToValueTypeSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ValueTypeSig; /// /// Returns a @@ -408,9 +326,7 @@ public static ValueTypeSig ToValueTypeSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static ClassSig ToClassSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as ClassSig; - } + public static ClassSig ToClassSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ClassSig; /// /// Returns a @@ -418,9 +334,7 @@ public static ClassSig ToClassSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static GenericSig ToGenericSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as GenericSig; - } + public static GenericSig ToGenericSig(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericSig; /// /// Returns a @@ -428,9 +342,7 @@ public static GenericSig ToGenericSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static GenericVar ToGenericVar(this TypeSig type) { - return type.RemovePinnedAndModifiers() as GenericVar; - } + public static GenericVar ToGenericVar(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericVar; /// /// Returns a @@ -438,9 +350,7 @@ public static GenericVar ToGenericVar(this TypeSig type) { /// The type /// A or null if it's not a /// - public static GenericMVar ToGenericMVar(this TypeSig type) { - return type.RemovePinnedAndModifiers() as GenericMVar; - } + public static GenericMVar ToGenericMVar(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericMVar; /// /// Returns a @@ -448,9 +358,7 @@ public static GenericMVar ToGenericMVar(this TypeSig type) { /// The type /// A or null if it's not a /// - public static GenericInstSig ToGenericInstSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as GenericInstSig; - } + public static GenericInstSig ToGenericInstSig(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericInstSig; /// /// Returns a @@ -458,9 +366,7 @@ public static GenericInstSig ToGenericInstSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static PtrSig ToPtrSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as PtrSig; - } + public static PtrSig ToPtrSig(this TypeSig type) => type.RemovePinnedAndModifiers() as PtrSig; /// /// Returns a @@ -468,9 +374,7 @@ public static PtrSig ToPtrSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static ByRefSig ToByRefSig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as ByRefSig; - } + public static ByRefSig ToByRefSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ByRefSig; /// /// Returns a @@ -478,9 +382,7 @@ public static ByRefSig ToByRefSig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static ArraySig ToArraySig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as ArraySig; - } + public static ArraySig ToArraySig(this TypeSig type) => type.RemovePinnedAndModifiers() as ArraySig; /// /// Returns a @@ -488,18 +390,14 @@ public static ArraySig ToArraySig(this TypeSig type) { /// The type /// A or null if it's not a /// - public static SZArraySig ToSZArraySig(this TypeSig type) { - return type.RemovePinnedAndModifiers() as SZArraySig; - } + public static SZArraySig ToSZArraySig(this TypeSig type) => type.RemovePinnedAndModifiers() as SZArraySig; /// /// Gets the next field or null /// /// this /// - public static TypeSig GetNext(this TypeSig self) { - return self == null ? null : self.Next; - } + public static TypeSig GetNext(this TypeSig self) => self?.Next; /// /// Gets the value or false if @@ -507,9 +405,7 @@ public static TypeSig GetNext(this TypeSig self) { /// /// this /// - public static bool GetIsValueType(this TypeSig self) { - return self == null ? false : self.IsValueType; - } + public static bool GetIsValueType(this TypeSig self) => self == null ? false : self.IsValueType; /// /// Gets the value or false if @@ -517,55 +413,42 @@ public static bool GetIsValueType(this TypeSig self) { /// /// this /// - public static bool GetIsPrimitive(this TypeSig self) { - return self == null ? false : self.IsPrimitive; - } + public static bool GetIsPrimitive(this TypeSig self) => self == null ? false : self.IsPrimitive; /// /// Gets the element type /// /// this /// The element type - public static ElementType GetElementType(this TypeSig a) { - return a == null ? ElementType.End : a.ElementType; - } + public static ElementType GetElementType(this TypeSig a) => a == null ? ElementType.End : a.ElementType; /// /// Gets the full name of the type /// /// this /// Full name of the type - public static string GetFullName(this TypeSig a) { - return a == null ? string.Empty : a.FullName; - } + public static string GetFullName(this TypeSig a) => a == null ? string.Empty : a.FullName; /// /// Gets the name of the type /// /// this /// Name of the type - public static string GetName(this TypeSig a) { - return a == null ? string.Empty : a.TypeName; - } + public static string GetName(this TypeSig a) => a == null ? string.Empty : a.TypeName; /// /// Gets the namespace of the type /// /// this /// Namespace of the type - public static string GetNamespace(this TypeSig a) { - return a == null ? string.Empty : a.Namespace; - } + public static string GetNamespace(this TypeSig a) => a == null ? string.Empty : a.Namespace; /// /// Returns the if it is a . /// /// this /// A or null if none found - public static TypeRef TryGetTypeRef(this TypeSig a) { - var tdr = a.RemovePinnedAndModifiers() as TypeDefOrRefSig; - return tdr == null ? null : tdr.TypeRef; - } + public static TypeRef TryGetTypeRef(this TypeSig a) => (a.RemovePinnedAndModifiers() as TypeDefOrRefSig)?.TypeRef; /// /// Returns the if it is a . @@ -573,20 +456,14 @@ public static TypeRef TryGetTypeRef(this TypeSig a) { /// /// this /// A or null if none found - public static TypeDef TryGetTypeDef(this TypeSig a) { - var tdr = a.RemovePinnedAndModifiers() as TypeDefOrRefSig; - return tdr == null ? null : tdr.TypeDef; - } + public static TypeDef TryGetTypeDef(this TypeSig a) => (a.RemovePinnedAndModifiers() as TypeDefOrRefSig)?.TypeDef; /// /// Returns the if it is a . /// /// this /// A or null if none found - public static TypeSpec TryGetTypeSpec(this TypeSig a) { - var tdr = a.RemovePinnedAndModifiers() as TypeDefOrRefSig; - return tdr == null ? null : tdr.TypeSpec; - } + public static TypeSpec TryGetTypeSpec(this TypeSig a) => (a.RemovePinnedAndModifiers() as TypeDefOrRefSig)?.TypeSpec; } /// @@ -596,9 +473,7 @@ public static TypeSpec TryGetTypeSpec(this TypeSig a) { /// public abstract class LeafSig : TypeSig { /// - public sealed override TypeSig Next { - get { return null; } - } + public sealed override TypeSig Next => null; } /// @@ -610,60 +485,44 @@ public abstract class TypeDefOrRefSig : LeafSig { /// /// Gets the the TypeDefOrRef /// - public ITypeDefOrRef TypeDefOrRef { - get { return typeDefOrRef; } - } + public ITypeDefOrRef TypeDefOrRef => typeDefOrRef; /// /// Returns true if != null /// - public bool IsTypeRef { - get { return TypeRef != null; } - } + public bool IsTypeRef => TypeRef != null; /// /// Returns true if != null /// - public bool IsTypeDef { - get { return TypeDef != null; } - } + public bool IsTypeDef => TypeDef != null; /// /// Returns true if != null /// - public bool IsTypeSpec { - get { return TypeSpec != null; } - } + public bool IsTypeSpec => TypeSpec != null; /// /// Gets the or null if it's not a /// - public TypeRef TypeRef { - get { return typeDefOrRef as TypeRef; } - } + public TypeRef TypeRef => typeDefOrRef as TypeRef; /// /// Gets the or null if it's not a /// - public TypeDef TypeDef { - get { return typeDefOrRef as TypeDef; } - } + public TypeDef TypeDef => typeDefOrRef as TypeDef; /// /// Gets the or null if it's not a /// - public TypeSpec TypeSpec { - get { return typeDefOrRef as TypeSpec; } - } + public TypeSpec TypeSpec => typeDefOrRef as TypeSpec; /// /// Constructor /// /// A , or /// a - protected TypeDefOrRefSig(ITypeDefOrRef typeDefOrRef) { - this.typeDefOrRef = typeDefOrRef; - } + protected TypeDefOrRefSig(ITypeDefOrRef typeDefOrRef) => this.typeDefOrRef = typeDefOrRef; } /// @@ -675,9 +534,7 @@ public sealed class CorLibTypeSig : TypeDefOrRefSig { /// /// Gets the element type /// - public override ElementType ElementType { - get { return elementType; } - } + public override ElementType ElementType => elementType; /// /// Constructor @@ -711,9 +568,7 @@ protected ClassOrValueTypeSig(ITypeDefOrRef typeDefOrRef) /// public sealed class ValueTypeSig : ClassOrValueTypeSig { /// - public override ElementType ElementType { - get { return ElementType.ValueType; } - } + public override ElementType ElementType => ElementType.ValueType; /// /// Constructor @@ -729,9 +584,7 @@ public ValueTypeSig(ITypeDefOrRef typeDefOrRef) /// public sealed class ClassSig : ClassOrValueTypeSig { /// - public override ElementType ElementType { - get { return ElementType.Class; } - } + public override ElementType ElementType => ElementType.Class; /// /// Constructor @@ -753,48 +606,36 @@ public abstract class GenericSig : LeafSig { /// /// true if it has an owner or /// - public bool HasOwner { - get { return genericParamProvider != null; } - } + public bool HasOwner => genericParamProvider != null; /// /// true if it has an owner ( is /// not null) /// - public bool HasOwnerType { - get { return OwnerType != null; } - } + public bool HasOwnerType => OwnerType != null; /// /// true if it has an owner ( is /// not null) /// - public bool HasOwnerMethod { - get { return OwnerMethod != null; } - } + public bool HasOwnerMethod => OwnerMethod != null; /// /// Gets the owner type or null if the owner is a or if it /// has no owner. /// - public TypeDef OwnerType { - get { return genericParamProvider as TypeDef; } - } + public TypeDef OwnerType => genericParamProvider as TypeDef; /// /// Gets the owner method or null if the owner is a or if it /// has no owner. /// - public MethodDef OwnerMethod { - get { return genericParamProvider as MethodDef; } - } + public MethodDef OwnerMethod => genericParamProvider as MethodDef; /// /// Gets the generic param number /// - public uint Number { - get { return number; } - } + public uint Number => number; /// /// Gets the corresponding or null if none exists. @@ -836,16 +677,12 @@ protected GenericSig(bool isTypeVar, uint number, ITypeOrMethodDef genericParamP /// /// Returns true if it's a MVar element type /// - public bool IsMethodVar { - get { return !isTypeVar; } - } + public bool IsMethodVar => !isTypeVar; /// /// Returns true if it's a Var element type /// - public bool IsTypeVar { - get { return isTypeVar; } - } + public bool IsTypeVar => isTypeVar; } /// @@ -853,9 +690,7 @@ public bool IsTypeVar { /// public sealed class GenericVar : GenericSig { /// - public override ElementType ElementType { - get { return ElementType.Var; } - } + public override ElementType ElementType => ElementType.Var; /// public GenericVar(uint number) @@ -891,9 +726,7 @@ public GenericVar(int number, TypeDef genericParamProvider) /// public sealed class GenericMVar : GenericSig { /// - public override ElementType ElementType { - get { return ElementType.MVar; } - } + public override ElementType ElementType => ElementType.MVar; /// public GenericMVar(uint number) @@ -929,9 +762,7 @@ public GenericMVar(int number, MethodDef genericParamProvider) /// public sealed class SentinelSig : LeafSig { /// - public override ElementType ElementType { - get { return ElementType.Sentinel; } - } + public override ElementType ElementType => ElementType.Sentinel; } /// @@ -941,31 +772,23 @@ public sealed class FnPtrSig : LeafSig { readonly CallingConventionSig signature; /// - public override ElementType ElementType { - get { return ElementType.FnPtr; } - } + public override ElementType ElementType => ElementType.FnPtr; /// /// Gets the signature /// - public CallingConventionSig Signature { - get { return signature; } - } + public CallingConventionSig Signature => signature; /// /// Gets the /// - public MethodSig MethodSig { - get { return signature as MethodSig; } - } + public MethodSig MethodSig => signature as MethodSig; /// /// Constructor /// /// The method signature - public FnPtrSig(CallingConventionSig signature) { - this.signature = signature; - } + public FnPtrSig(CallingConventionSig signature) => this.signature = signature; } /// @@ -976,31 +799,25 @@ public sealed class GenericInstSig : LeafSig { readonly ThreadSafe.IList genericArgs; /// - public override ElementType ElementType { - get { return ElementType.GenericInst; } - } + public override ElementType ElementType => ElementType.GenericInst; /// /// Gets the generic type /// public ClassOrValueTypeSig GenericType { - get { return genericType; } - set { genericType = value; } + get => genericType; + set => genericType = value; } /// /// Gets the generic arguments (it's never null) /// - public ThreadSafe.IList GenericArguments { - get { return genericArgs; } - } + public ThreadSafe.IList GenericArguments => genericArgs; /// /// Default constructor /// - public GenericInstSig() { - this.genericArgs = ThreadSafeListCreator.Create(); - } + public GenericInstSig() => genericArgs = ThreadSafeListCreator.Create(); /// /// Constructor @@ -1008,7 +825,7 @@ public GenericInstSig() { /// The generic type public GenericInstSig(ClassOrValueTypeSig genericType) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create(); + genericArgs = ThreadSafeListCreator.Create(); } /// @@ -1018,7 +835,7 @@ public GenericInstSig(ClassOrValueTypeSig genericType) { /// Number of generic arguments public GenericInstSig(ClassOrValueTypeSig genericType, uint genArgCount) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create((int)genArgCount); + genericArgs = ThreadSafeListCreator.Create((int)genArgCount); } /// @@ -1037,7 +854,7 @@ public GenericInstSig(ClassOrValueTypeSig genericType, int genArgCount) /// Generic argument #1 public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create(genArg1); + genericArgs = ThreadSafeListCreator.Create(genArg1); } /// @@ -1048,7 +865,7 @@ public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1) { /// Generic argument #2 public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1, TypeSig genArg2) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create(genArg1, genArg2); + genericArgs = ThreadSafeListCreator.Create(genArg1, genArg2); } /// @@ -1060,7 +877,7 @@ public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1, TypeSig /// Generic argument #3 public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1, TypeSig genArg2, TypeSig genArg3) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create(genArg1, genArg2, genArg3); + genericArgs = ThreadSafeListCreator.Create(genArg1, genArg2, genArg3); } /// @@ -1070,7 +887,7 @@ public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1, TypeSig /// Generic arguments public GenericInstSig(ClassOrValueTypeSig genericType, params TypeSig[] genArgs) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create(genArgs); + genericArgs = ThreadSafeListCreator.Create(genArgs); } /// @@ -1080,7 +897,7 @@ public GenericInstSig(ClassOrValueTypeSig genericType, params TypeSig[] genArgs) /// Generic arguments public GenericInstSig(ClassOrValueTypeSig genericType, IList genArgs) { this.genericType = genericType; - this.genericArgs = ThreadSafeListCreator.Create(genArgs); + genericArgs = ThreadSafeListCreator.Create(genArgs); } } @@ -1091,17 +908,13 @@ public abstract class NonLeafSig : TypeSig { readonly TypeSig nextSig; /// - public sealed override TypeSig Next { - get { return nextSig; } - } + public sealed override TypeSig Next => nextSig; /// /// Constructor /// /// Next sig - protected NonLeafSig(TypeSig nextSig) { - this.nextSig = nextSig; - } + protected NonLeafSig(TypeSig nextSig) => this.nextSig = nextSig; } /// @@ -1109,9 +922,7 @@ protected NonLeafSig(TypeSig nextSig) { /// public sealed class PtrSig : NonLeafSig { /// - public override ElementType ElementType { - get { return ElementType.Ptr; } - } + public override ElementType ElementType => ElementType.Ptr; /// /// Constructor @@ -1127,9 +938,7 @@ public PtrSig(TypeSig nextSig) /// public sealed class ByRefSig : NonLeafSig { /// - public override ElementType ElementType { - get { return ElementType.ByRef; } - } + public override ElementType ElementType => ElementType.ByRef; /// /// Constructor @@ -1157,18 +966,14 @@ protected ArraySigBase(TypeSig arrayType) /// and false if it's a single-dimensional array (i.e., ) /// /// - public bool IsMultiDimensional { - get { return ElementType == ElementType.Array; } - } + public bool IsMultiDimensional => ElementType == ElementType.Array; /// /// true if it's a single-dimensional array (i.e., ), /// and false if it's a multi-dimensional array (i.e., ) /// /// - public bool IsSingleDimensional { - get { return ElementType == ElementType.SZArray; } - } + public bool IsSingleDimensional => ElementType == ElementType.SZArray; /// /// Gets/sets the rank (number of dimensions). This can only be set if @@ -1201,31 +1006,25 @@ public sealed class ArraySig : ArraySigBase { readonly ThreadSafe.IList lowerBounds; /// - public override ElementType ElementType { - get { return ElementType.Array; } - } + public override ElementType ElementType => ElementType.Array; /// /// Gets/sets the rank (max value is 0x1FFFFFFF) /// public override uint Rank { - get { return rank; } - set { rank = value; } + get => rank; + set => rank = value; } /// /// Gets all sizes (max elements is 0x1FFFFFFF) /// - public ThreadSafe.IList Sizes { - get { return sizes; } - } + public ThreadSafe.IList Sizes => sizes; /// /// Gets all lower bounds (max elements is 0x1FFFFFFF) /// - public ThreadSafe.IList LowerBounds { - get { return lowerBounds; } - } + public ThreadSafe.IList LowerBounds => lowerBounds; /// /// Constructor @@ -1233,8 +1032,8 @@ public ThreadSafe.IList LowerBounds { /// Array type public ArraySig(TypeSig arrayType) : base(arrayType) { - this.sizes = ThreadSafeListCreator.Create(); - this.lowerBounds = ThreadSafeListCreator.Create(); + sizes = ThreadSafeListCreator.Create(); + lowerBounds = ThreadSafeListCreator.Create(); } /// @@ -1245,8 +1044,8 @@ public ArraySig(TypeSig arrayType) public ArraySig(TypeSig arrayType, uint rank) : base(arrayType) { this.rank = rank; - this.sizes = ThreadSafeListCreator.Create(); - this.lowerBounds = ThreadSafeListCreator.Create(); + sizes = ThreadSafeListCreator.Create(); + lowerBounds = ThreadSafeListCreator.Create(); } /// @@ -1298,14 +1097,10 @@ internal ArraySig(TypeSig arrayType, uint rank, IList sizes, IList lo } /// - public override ThreadSafe.IList GetSizes() { - return sizes; - } + public override ThreadSafe.IList GetSizes() => sizes; /// - public override ThreadSafe.IList GetLowerBounds() { - return lowerBounds; - } + public override ThreadSafe.IList GetLowerBounds() => lowerBounds; } /// @@ -1314,14 +1109,12 @@ public override ThreadSafe.IList GetLowerBounds() { /// public sealed class SZArraySig : ArraySigBase { /// - public override ElementType ElementType { - get { return ElementType.SZArray; } - } + public override ElementType ElementType => ElementType.SZArray; /// public override uint Rank { - get { return 1; } - set { throw new NotSupportedException(); } + get => 1; + set => throw new NotSupportedException(); } /// @@ -1333,14 +1126,10 @@ public SZArraySig(TypeSig nextSig) } /// - public override ThreadSafe.IList GetSizes() { - return ThreadSafeListCreator.Create(); - } + public override ThreadSafe.IList GetSizes() => ThreadSafeListCreator.Create(); /// - public override ThreadSafe.IList GetLowerBounds() { - return ThreadSafeListCreator.Create(); - } + public override ThreadSafe.IList GetLowerBounds() => ThreadSafeListCreator.Create(); } /// @@ -1352,9 +1141,7 @@ public abstract class ModifierSig : NonLeafSig { /// /// Returns the modifier type /// - public ITypeDefOrRef Modifier { - get { return modifier; } - } + public ITypeDefOrRef Modifier => modifier; /// /// Constructor @@ -1362,9 +1149,7 @@ public ITypeDefOrRef Modifier { /// Modifier type /// The next element type protected ModifierSig(ITypeDefOrRef modifier, TypeSig nextSig) - : base(nextSig) { - this.modifier = modifier; - } + : base(nextSig) => this.modifier = modifier; } /// @@ -1372,9 +1157,7 @@ protected ModifierSig(ITypeDefOrRef modifier, TypeSig nextSig) /// public sealed class CModReqdSig : ModifierSig { /// - public override ElementType ElementType { - get { return ElementType.CModReqd; } - } + public override ElementType ElementType => ElementType.CModReqd; /// public CModReqdSig(ITypeDefOrRef modifier, TypeSig nextSig) @@ -1387,9 +1170,7 @@ public CModReqdSig(ITypeDefOrRef modifier, TypeSig nextSig) /// public sealed class CModOptSig : ModifierSig { /// - public override ElementType ElementType { - get { return ElementType.CModOpt; } - } + public override ElementType ElementType => ElementType.CModOpt; /// public CModOptSig(ITypeDefOrRef modifier, TypeSig nextSig) @@ -1402,9 +1183,7 @@ public CModOptSig(ITypeDefOrRef modifier, TypeSig nextSig) /// public sealed class PinnedSig : NonLeafSig { /// - public override ElementType ElementType { - get { return ElementType.Pinned; } - } + public override ElementType ElementType => ElementType.Pinned; /// /// Constructor @@ -1422,16 +1201,14 @@ public sealed class ValueArraySig : NonLeafSig { uint size; /// - public override ElementType ElementType { - get { return ElementType.ValueArray; } - } + public override ElementType ElementType => ElementType.ValueArray; /// /// Gets/sets the size /// public uint Size { - get { return size; } - set { size = value; } + get => size; + set => size = value; } /// @@ -1440,9 +1217,7 @@ public uint Size { /// The next element type /// Size of the array public ValueArraySig(TypeSig nextSig, uint size) - : base(nextSig) { - this.size = size; - } + : base(nextSig) => this.size = size; } /// @@ -1452,16 +1227,14 @@ public sealed class ModuleSig : NonLeafSig { uint index; /// - public override ElementType ElementType { - get { return ElementType.Module; } - } + public override ElementType ElementType => ElementType.Module; /// /// Gets/sets the index /// public uint Index { - get { return index; } - set { index = value; } + get => index; + set => index = value; } /// @@ -1470,8 +1243,6 @@ public uint Index { /// Index /// The next element type public ModuleSig(uint index, TypeSig nextSig) - : base(nextSig) { - this.index = index; - } + : base(nextSig) => this.index = index; } } diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index dd2f4160f..bd9fac66c 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -27,30 +27,22 @@ public abstract class TypeSpec : ITypeDefOrRef, IHasCustomAttribute, IMemberRefP #endif /// - public MDToken MDToken { - get { return new MDToken(Table.TypeSpec, rid); } - } + public MDToken MDToken => new MDToken(Table.TypeSpec, rid); /// public uint Rid { - get { return rid; } - set { rid = value; } + get => rid; + set => rid = value; } /// - public int TypeDefOrRefTag { - get { return 2; } - } + public int TypeDefOrRefTag => 2; /// - public int HasCustomAttributeTag { - get { return 13; } - } + public int HasCustomAttributeTag => 13; /// - public int MemberRefParentTag { - get { return 4; } - } + public int MemberRefParentTag => 4; /// int IGenericParameterProvider.NumberOfGenericParameters { @@ -78,12 +70,10 @@ ITypeDefOrRef IMemberRef.DeclaringType { get { var sig = TypeSig.RemovePinnedAndModifiers(); - var gis = sig as GenericInstSig; - if (gis != null) + if (sig is GenericInstSig gis) sig = gis.GenericType; - var tdr = sig as TypeDefOrRefSig; - if (tdr != null) { + if (sig is TypeDefOrRefSig tdr) { if (tdr.IsTypeDef || tdr.IsTypeRef) return tdr.TypeDefOrRef.DeclaringType; return null; // If it's another TypeSpec, just stop. Don't want possible inf recursion. @@ -93,57 +83,19 @@ ITypeDefOrRef IMemberRef.DeclaringType { } } - bool IIsTypeOrMethod.IsType { - get { return true; } - } - - bool IIsTypeOrMethod.IsMethod { - get { return false; } - } - - bool IMemberRef.IsField { - get { return false; } - } - - bool IMemberRef.IsTypeSpec { - get { return true; } - } - - bool IMemberRef.IsTypeRef { - get { return false; } - } - - bool IMemberRef.IsTypeDef { - get { return false; } - } - - bool IMemberRef.IsMethodSpec { - get { return false; } - } - - bool IMemberRef.IsMethodDef { - get { return false; } - } - - bool IMemberRef.IsMemberRef { - get { return false; } - } - - bool IMemberRef.IsFieldDef { - get { return false; } - } - - bool IMemberRef.IsPropertyDef { - get { return false; } - } - - bool IMemberRef.IsEventDef { - get { return false; } - } - - bool IMemberRef.IsGenericParam { - get { return false; } - } + bool IIsTypeOrMethod.IsType => true; + bool IIsTypeOrMethod.IsMethod => false; + bool IMemberRef.IsField => false; + bool IMemberRef.IsTypeSpec => true; + bool IMemberRef.IsTypeRef => false; + bool IMemberRef.IsTypeDef => false; + bool IMemberRef.IsMethodSpec => false; + bool IMemberRef.IsMethodDef => false; + bool IMemberRef.IsMemberRef => false; + bool IMemberRef.IsFieldDef => false; + bool IMemberRef.IsPropertyDef => false; + bool IMemberRef.IsEventDef => false; + bool IMemberRef.IsGenericParam => false; /// public bool IsValueType { @@ -162,64 +114,40 @@ public bool IsPrimitive { } /// - public string TypeName { - get { return FullNameCreator.Name(this, false, null); } - } + public string TypeName => FullNameCreator.Name(this, false, null); /// - public string ReflectionName { - get { return FullNameCreator.Name(this, true, null); } - } + public string ReflectionName => FullNameCreator.Name(this, true, null); /// - string IType.Namespace { - get { return FullNameCreator.Namespace(this, false, null); } - } + string IType.Namespace => FullNameCreator.Namespace(this, false, null); /// - public string ReflectionNamespace { - get { return FullNameCreator.Namespace(this, true, null); } - } + public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); /// - public string FullName { - get { return FullNameCreator.FullName(this, false, null, null); } - } + public string FullName => FullNameCreator.FullName(this, false, null, null); /// - public string ReflectionFullName { - get { return FullNameCreator.FullName(this, true, null, null); } - } + public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); /// - public string AssemblyQualifiedName { - get { return FullNameCreator.AssemblyQualifiedName(this, null, null); } - } + public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly { - get { return FullNameCreator.DefinitionAssembly(this); } - } + public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); /// - public IScope Scope { - get { return FullNameCreator.Scope(this); } - } + public IScope Scope => FullNameCreator.Scope(this); /// - public ITypeDefOrRef ScopeType { - get { return FullNameCreator.ScopeType(this); } - } + public ITypeDefOrRef ScopeType => FullNameCreator.ScopeType(this); /// - public bool ContainsGenericParameter { - get { return TypeHelper.ContainsGenericParameter(this); } - } + public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// - public ModuleDef Module { - get { return FullNameCreator.OwnerModule(this); } - } + public ModuleDef Module => FullNameCreator.OwnerModule(this); /// /// From column TypeSpec.Signature @@ -297,25 +225,18 @@ public CustomAttributeCollection CustomAttributes { /// protected CustomAttributeCollection customAttributes; /// Initializes - protected virtual void InitializeCustomAttributes() { + protected virtual void InitializeCustomAttributes() => Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); - } /// - public bool HasCustomAttributes { - get { return CustomAttributes.Count > 0; } - } + public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public int HasCustomDebugInformationTag { - get { return 13; } - } + public int HasCustomDebugInformationTag => 13; /// - public bool HasCustomDebugInfos { - get { return CustomDebugInfos.Count > 0; } - } + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; /// /// Gets all custom debug infos @@ -330,13 +251,10 @@ public ThreadSafe.IList CustomDebugInfos { /// protected ThreadSafe.IList customDebugInfos; /// Initializes - protected virtual void InitializeCustomDebugInfos() { + protected virtual void InitializeCustomDebugInfos() => Interlocked.CompareExchange(ref customDebugInfos, ThreadSafeListCreator.Create(), null); - } /// - public override string ToString() { - return FullName; - } + public override string ToString() => FullName; } /// @@ -355,8 +273,8 @@ public TypeSpecUser() { /// A type sig public TypeSpecUser(TypeSig typeSig) { this.typeSig = typeSig; - this.extraData = null; - this.typeSigAndExtraData_isInitialized = true; + extraData = null; + typeSigAndExtraData_isInitialized = true; } } @@ -372,9 +290,7 @@ sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD { readonly uint signatureOffset; /// - public uint OrigRid { - get { return origRid; } - } + public uint OrigRid => origRid; /// protected override TypeSig GetTypeSigAndExtraData_NoLock(out byte[] extraData) { @@ -411,13 +327,13 @@ public TypeSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpCont if (readerModule == null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.TypeSpecTable.IsInvalidRID(rid)) - throw new BadImageFormatException(string.Format("TypeSpec rid {0} does not exist", rid)); + throw new BadImageFormatException($"TypeSpec rid {rid} does not exist"); #endif - this.origRid = rid; + origRid = rid; this.rid = rid; this.readerModule = readerModule; this.gpContext = gpContext; - this.signatureOffset = readerModule.TablesStream.ReadTypeSpecRow2(origRid); + signatureOffset = readerModule.TablesStream.ReadTypeSpecRow2(origRid); } } } diff --git a/src/DotNet/UTF8String.cs b/src/DotNet/UTF8String.cs index d14a7ddca..9fab4d90e 100644 --- a/src/DotNet/UTF8String.cs +++ b/src/DotNet/UTF8String.cs @@ -17,14 +17,10 @@ public sealed class UTF8StringEqualityComparer : IEqualityComparer { public static readonly UTF8StringEqualityComparer Instance = new UTF8StringEqualityComparer(); /// - public bool Equals(UTF8String x, UTF8String y) { - return UTF8String.Equals(x, y); - } + public bool Equals(UTF8String x, UTF8String y) => UTF8String.Equals(x, y); /// - public int GetHashCode(UTF8String obj) { - return UTF8String.GetHashCode(obj); - } + public int GetHashCode(UTF8String obj) => UTF8String.GetHashCode(obj); } /// @@ -58,35 +54,27 @@ public string String { /// /// Gets the original encoded data. Don't modify this data. /// - public byte[] Data { - get { return data; } - } + public byte[] Data => data; /// /// Gets the length of the this as a . I.e., it's the same as /// String.Length. /// /// - public int Length { - get { return String.Length; } - } + public int Length => String.Length; /// /// Gets the length of the raw data. It's the same as Data.Length /// /// - public int DataLength { - get { return data == null ? 0 : data.Length; } - } + public int DataLength => data == null ? 0 : data.Length; /// /// Checks whether is null or if its data is null. /// /// The instance to check /// true if null or empty, false otherwise - public static bool IsNull(UTF8String utf8) { - return (object)utf8 == null || utf8.data == null; - } + public static bool IsNull(UTF8String utf8) => (object)utf8 == null || utf8.data == null; /// /// Checks whether is null or if its data is null or the @@ -94,19 +82,13 @@ public static bool IsNull(UTF8String utf8) { /// /// The instance to check /// true if null or empty, false otherwise - public static bool IsNullOrEmpty(UTF8String utf8) { - return (object)utf8 == null || utf8.data == null || utf8.data.Length == 0; - } + public static bool IsNullOrEmpty(UTF8String utf8) => (object)utf8 == null || utf8.data == null || utf8.data.Length == 0; /// Implicit conversion from to - public static implicit operator string(UTF8String s) { - return UTF8String.ToSystemString(s); - } + public static implicit operator string(UTF8String s) => UTF8String.ToSystemString(s); /// Implicit conversion from to - public static implicit operator UTF8String(string s) { - return s == null ? null : new UTF8String(s); - } + public static implicit operator UTF8String(string s) => s == null ? null : new UTF8String(s); /// /// Converts it to a @@ -126,9 +108,7 @@ public static string ToSystemString(UTF8String utf8) { /// /// The UTF-8 string instace or null /// A (never null) - public static string ToSystemStringOrEmpty(UTF8String utf8) { - return ToSystemString(utf8) ?? string.Empty; - } + public static string ToSystemStringOrEmpty(UTF8String utf8) => ToSystemString(utf8) ?? string.Empty; /// /// Gets the hash code of a @@ -141,9 +121,7 @@ public static int GetHashCode(UTF8String utf8) { } /// - public int CompareTo(UTF8String other) { - return CompareTo(this, other); - } + public int CompareTo(UTF8String other) => CompareTo(this, other); /// /// Compares two instances (case sensitive) @@ -151,9 +129,7 @@ public int CompareTo(UTF8String other) { /// Instance #1 or null /// Instance #2 or null /// < 0 if a < b, 0 if a == b, > 0 if a > b - public static int CompareTo(UTF8String a, UTF8String b) { - return Utils.CompareTo((object)a == null ? null : a.data, (object)b == null ? null : b.data); - } + public static int CompareTo(UTF8String a, UTF8String b) => Utils.CompareTo((object)a == null ? null : a.data, (object)b == null ? null : b.data); /// /// Compares two instances (case insensitive) @@ -181,67 +157,43 @@ public static int CaseInsensitiveCompareTo(UTF8String a, UTF8String b) { /// Instance #1 or null /// Instance #2 or null /// true if equals, false otherwise - public static bool CaseInsensitiveEquals(UTF8String a, UTF8String b) { - return CaseInsensitiveCompareTo(a, b) == 0; - } + public static bool CaseInsensitiveEquals(UTF8String a, UTF8String b) => CaseInsensitiveCompareTo(a, b) == 0; /// Overloaded operator - public static bool operator ==(UTF8String left, UTF8String right) { - return CompareTo(left, right) == 0; - } + public static bool operator ==(UTF8String left, UTF8String right) => CompareTo(left, right) == 0; /// Overloaded operator - public static bool operator ==(UTF8String left, string right) { - return ToSystemString(left) == right; - } + public static bool operator ==(UTF8String left, string right) => ToSystemString(left) == right; /// Overloaded operator - public static bool operator ==(string left, UTF8String right) { - return left == ToSystemString(right); - } + public static bool operator ==(string left, UTF8String right) => left == ToSystemString(right); /// Overloaded operator - public static bool operator !=(UTF8String left, UTF8String right) { - return CompareTo(left, right) != 0; - } + public static bool operator !=(UTF8String left, UTF8String right) => CompareTo(left, right) != 0; /// Overloaded operator - public static bool operator !=(UTF8String left, string right) { - return ToSystemString(left) != right; - } + public static bool operator !=(UTF8String left, string right) => ToSystemString(left) != right; /// Overloaded operator - public static bool operator !=(string left, UTF8String right) { - return left != ToSystemString(right); - } + public static bool operator !=(string left, UTF8String right) => left != ToSystemString(right); /// Overloaded operator - public static bool operator >(UTF8String left, UTF8String right) { - return CompareTo(left, right) > 0; - } + public static bool operator >(UTF8String left, UTF8String right) => CompareTo(left, right) > 0; /// Overloaded operator - public static bool operator <(UTF8String left, UTF8String right) { - return CompareTo(left, right) < 0; - } + public static bool operator <(UTF8String left, UTF8String right) => CompareTo(left, right) < 0; /// Overloaded operator - public static bool operator >=(UTF8String left, UTF8String right) { - return CompareTo(left, right) >= 0; - } + public static bool operator >=(UTF8String left, UTF8String right) => CompareTo(left, right) >= 0; /// Overloaded operator - public static bool operator <=(UTF8String left, UTF8String right) { - return CompareTo(left, right) <= 0; - } + public static bool operator <=(UTF8String left, UTF8String right) => CompareTo(left, right) <= 0; /// /// Constructor /// /// UTF-8 data that this instance now owns - public UTF8String(byte[] data) { - this.data = data; - } + public UTF8String(byte[] data) => this.data = data; /// /// Constructor @@ -268,14 +220,10 @@ static string ConvertFromUTF8(byte[] data) { /// First /// Second /// true if equals, false otherwise - public static bool Equals(UTF8String a, UTF8String b) { - return CompareTo(a, b) == 0; - } + public static bool Equals(UTF8String a, UTF8String b) => CompareTo(a, b) == 0; /// - public bool Equals(UTF8String other) { - return CompareTo(this, other) == 0; - } + public bool Equals(UTF8String other) => CompareTo(this, other) == 0; /// public override bool Equals(object obj) { @@ -291,18 +239,14 @@ public override bool Equals(object obj) { /// Value to find /// true if exists in string or is the /// empty string, else false - public bool Contains(string value) { - return String.Contains(value); - } + public bool Contains(string value) => String.Contains(value); /// /// Checks whether matches the end of this string /// /// Value /// - public bool EndsWith(string value) { - return String.EndsWith(value); - } + public bool EndsWith(string value) => String.EndsWith(value); /// /// Checks whether matches the end of this string @@ -311,9 +255,7 @@ public bool EndsWith(string value) { /// true to ignore case /// Culture info /// - public bool EndsWith(string value, bool ignoreCase, CultureInfo culture) { - return String.EndsWith(value, ignoreCase, culture); - } + public bool EndsWith(string value, bool ignoreCase, CultureInfo culture) => String.EndsWith(value, ignoreCase, culture); /// /// Checks whether matches the end of this string @@ -321,18 +263,14 @@ public bool EndsWith(string value, bool ignoreCase, CultureInfo culture) { /// Value /// Comparison type /// - public bool EndsWith(string value, StringComparison comparisonType) { - return String.EndsWith(value, comparisonType); - } + public bool EndsWith(string value, StringComparison comparisonType) => String.EndsWith(value, comparisonType); /// /// Checks whether matches the beginning of this string /// /// Value /// - public bool StartsWith(string value) { - return String.StartsWith(value); - } + public bool StartsWith(string value) => String.StartsWith(value); /// /// Checks whether matches the beginning of this string @@ -341,9 +279,7 @@ public bool StartsWith(string value) { /// true to ignore case /// Culture info /// - public bool StartsWith(string value, bool ignoreCase, CultureInfo culture) { - return String.StartsWith(value, ignoreCase, culture); - } + public bool StartsWith(string value, bool ignoreCase, CultureInfo culture) => String.StartsWith(value, ignoreCase, culture); /// /// Checks whether matches the beginning of this string @@ -351,27 +287,21 @@ public bool StartsWith(string value, bool ignoreCase, CultureInfo culture) { /// Value /// Comparison type /// - public bool StartsWith(string value, StringComparison comparisonType) { - return String.StartsWith(value, comparisonType); - } + public bool StartsWith(string value, StringComparison comparisonType) => String.StartsWith(value, comparisonType); /// /// Compares this instance with /// /// Other string /// < 0 if a < b, 0 if a == b, > 0 if a > b - public int CompareTo(string strB) { - return String.CompareTo(strB); - } + public int CompareTo(string strB) => String.CompareTo(strB); /// /// Returns the index of the first character in this string /// /// Character /// The index of or -1 if not found - public int IndexOf(char value) { - return String.IndexOf(value); - } + public int IndexOf(char value) => String.IndexOf(value); /// /// Returns the index of the first character in this string @@ -380,9 +310,7 @@ public int IndexOf(char value) { /// Character /// Start index /// The index of or -1 if not found - public int IndexOf(char value, int startIndex) { - return String.IndexOf(value, startIndex); - } + public int IndexOf(char value, int startIndex) => String.IndexOf(value, startIndex); /// /// Returns the index of the first character in this string @@ -393,18 +321,14 @@ public int IndexOf(char value, int startIndex) { /// Start index /// Max number of chars to scan /// The index of or -1 if not found - public int IndexOf(char value, int startIndex, int count) { - return String.IndexOf(value, startIndex, count); - } + public int IndexOf(char value, int startIndex, int count) => String.IndexOf(value, startIndex, count); /// /// Returns the index of the first sub string in this string /// /// String /// The index of or -1 if not found - public int IndexOf(string value) { - return String.IndexOf(value); - } + public int IndexOf(string value) => String.IndexOf(value); /// /// Returns the index of the first sub string in this string @@ -413,9 +337,7 @@ public int IndexOf(string value) { /// String /// Start index /// The index of or -1 if not found - public int IndexOf(string value, int startIndex) { - return String.IndexOf(value, startIndex); - } + public int IndexOf(string value, int startIndex) => String.IndexOf(value, startIndex); /// /// Returns the index of the first sub string in this string @@ -426,9 +348,7 @@ public int IndexOf(string value, int startIndex) { /// Start index /// Max number of chars to scan /// The index of or -1 if not found - public int IndexOf(string value, int startIndex, int count) { - return String.IndexOf(value, startIndex, count); - } + public int IndexOf(string value, int startIndex, int count) => String.IndexOf(value, startIndex, count); /// /// Returns the index of the first sub string in this string @@ -440,9 +360,7 @@ public int IndexOf(string value, int startIndex, int count) { /// Max number of chars to scan /// Comparison type /// The index of or -1 if not found - public int IndexOf(string value, int startIndex, int count, StringComparison comparisonType) { - return String.IndexOf(value, startIndex, count, comparisonType); - } + public int IndexOf(string value, int startIndex, int count, StringComparison comparisonType) => String.IndexOf(value, startIndex, count, comparisonType); /// /// Returns the index of the first sub string in this string @@ -452,9 +370,7 @@ public int IndexOf(string value, int startIndex, int count, StringComparison com /// Start index /// Comparison type /// The index of or -1 if not found - public int IndexOf(string value, int startIndex, StringComparison comparisonType) { - return String.IndexOf(value, startIndex, comparisonType); - } + public int IndexOf(string value, int startIndex, StringComparison comparisonType) => String.IndexOf(value, startIndex, comparisonType); /// /// Returns the index of the first sub string in this string @@ -462,18 +378,14 @@ public int IndexOf(string value, int startIndex, StringComparison comparisonType /// String /// Comparison type /// The index of or -1 if not found - public int IndexOf(string value, StringComparison comparisonType) { - return String.IndexOf(value, comparisonType); - } + public int IndexOf(string value, StringComparison comparisonType) => String.IndexOf(value, comparisonType); /// /// Returns the index of the last character in this string /// /// Character /// The index of or -1 if not found - public int LastIndexOf(char value) { - return String.LastIndexOf(value); - } + public int LastIndexOf(char value) => String.LastIndexOf(value); /// /// Returns the index of the last character in this string @@ -482,9 +394,7 @@ public int LastIndexOf(char value) { /// Character /// Start index /// The index of or -1 if not found - public int LastIndexOf(char value, int startIndex) { - return String.LastIndexOf(value, startIndex); - } + public int LastIndexOf(char value, int startIndex) => String.LastIndexOf(value, startIndex); /// /// Returns the index of the last character in this string @@ -495,18 +405,14 @@ public int LastIndexOf(char value, int startIndex) { /// Start index /// Max number of chars to scan /// The index of or -1 if not found - public int LastIndexOf(char value, int startIndex, int count) { - return String.LastIndexOf(value, startIndex, count); - } + public int LastIndexOf(char value, int startIndex, int count) => String.LastIndexOf(value, startIndex, count); /// /// Returns the index of the last sub string in this string /// /// String /// The index of or -1 if not found - public int LastIndexOf(string value) { - return String.LastIndexOf(value); - } + public int LastIndexOf(string value) => String.LastIndexOf(value); /// /// Returns the index of the last sub string in this string @@ -515,9 +421,7 @@ public int LastIndexOf(string value) { /// String /// Start index /// The index of or -1 if not found - public int LastIndexOf(string value, int startIndex) { - return String.LastIndexOf(value, startIndex); - } + public int LastIndexOf(string value, int startIndex) => String.LastIndexOf(value, startIndex); /// /// Returns the index of the last sub string in this string @@ -528,9 +432,7 @@ public int LastIndexOf(string value, int startIndex) { /// Start index /// Max number of chars to scan /// The index of or -1 if not found - public int LastIndexOf(string value, int startIndex, int count) { - return String.LastIndexOf(value, startIndex, count); - } + public int LastIndexOf(string value, int startIndex, int count) => String.LastIndexOf(value, startIndex, count); /// /// Returns the index of the last sub string in this string @@ -542,9 +444,7 @@ public int LastIndexOf(string value, int startIndex, int count) { /// Max number of chars to scan /// Comparison type /// The index of or -1 if not found - public int LastIndexOf(string value, int startIndex, int count, StringComparison comparisonType) { - return String.LastIndexOf(value, startIndex, count, comparisonType); - } + public int LastIndexOf(string value, int startIndex, int count, StringComparison comparisonType) => String.LastIndexOf(value, startIndex, count, comparisonType); /// /// Returns the index of the last sub string in this string @@ -554,9 +454,7 @@ public int LastIndexOf(string value, int startIndex, int count, StringComparison /// Start index /// Comparison type /// The index of or -1 if not found - public int LastIndexOf(string value, int startIndex, StringComparison comparisonType) { - return String.LastIndexOf(value, startIndex, comparisonType); - } + public int LastIndexOf(string value, int startIndex, StringComparison comparisonType) => String.LastIndexOf(value, startIndex, comparisonType); /// /// Returns the index of the last sub string in this string @@ -564,9 +462,7 @@ public int LastIndexOf(string value, int startIndex, StringComparison comparison /// String /// Comparison type /// The index of or -1 if not found - public int LastIndexOf(string value, StringComparison comparisonType) { - return String.LastIndexOf(value, comparisonType); - } + public int LastIndexOf(string value, StringComparison comparisonType) => String.LastIndexOf(value, comparisonType); /// /// Inserts string at a index @@ -575,18 +471,14 @@ public int LastIndexOf(string value, StringComparison comparisonType) { /// Value to insert /// A new instance with the inserted at position /// - public UTF8String Insert(int startIndex, string value) { - return new UTF8String(String.Insert(startIndex, value)); - } + public UTF8String Insert(int startIndex, string value) => new UTF8String(String.Insert(startIndex, value)); /// /// Removes all characters starting from position /// /// Start index /// A new instance - public UTF8String Remove(int startIndex) { - return new UTF8String(String.Remove(startIndex)); - } + public UTF8String Remove(int startIndex) => new UTF8String(String.Remove(startIndex)); /// /// Removes characters starting from position @@ -595,9 +487,7 @@ public UTF8String Remove(int startIndex) { /// Start index /// Number of characters to remove /// A new instance - public UTF8String Remove(int startIndex, int count) { - return new UTF8String(String.Remove(startIndex, count)); - } + public UTF8String Remove(int startIndex, int count) => new UTF8String(String.Remove(startIndex, count)); /// /// Replaces all characters with @@ -605,9 +495,7 @@ public UTF8String Remove(int startIndex, int count) { /// Character to find /// Character to replace all /// A new instance - public UTF8String Replace(char oldChar, char newChar) { - return new UTF8String(String.Replace(oldChar, newChar)); - } + public UTF8String Replace(char oldChar, char newChar) => new UTF8String(String.Replace(oldChar, newChar)); /// /// Replaces all sub strings with @@ -615,18 +503,14 @@ public UTF8String Replace(char oldChar, char newChar) { /// Sub string to find /// Sub string to replace all /// A new instance - public UTF8String Replace(string oldValue, string newValue) { - return new UTF8String(String.Replace(oldValue, newValue)); - } + public UTF8String Replace(string oldValue, string newValue) => new UTF8String(String.Replace(oldValue, newValue)); /// /// Returns a sub string of this string starting at offset /// /// Start index /// A new instance - public UTF8String Substring(int startIndex) { - return new UTF8String(String.Substring(startIndex)); - } + public UTF8String Substring(int startIndex) => new UTF8String(String.Substring(startIndex)); /// /// Returns a sub string of this string starting at offset . @@ -635,76 +519,56 @@ public UTF8String Substring(int startIndex) { /// Start index /// Length of sub string /// A new instance - public UTF8String Substring(int startIndex, int length) { - return new UTF8String(String.Substring(startIndex, length)); - } + public UTF8String Substring(int startIndex, int length) => new UTF8String(String.Substring(startIndex, length)); /// /// Returns the lower case version of this string /// /// A new instance - public UTF8String ToLower() { - return new UTF8String(String.ToLower()); - } + public UTF8String ToLower() => new UTF8String(String.ToLower()); /// /// Returns the lower case version of this string /// /// Culture info /// A new instance - public UTF8String ToLower(CultureInfo culture) { - return new UTF8String(String.ToLower(culture)); - } + public UTF8String ToLower(CultureInfo culture) => new UTF8String(String.ToLower(culture)); /// /// Returns the lower case version of this string using the invariant culture /// /// A new instance - public UTF8String ToLowerInvariant() { - return new UTF8String(String.ToLowerInvariant()); - } + public UTF8String ToLowerInvariant() => new UTF8String(String.ToLowerInvariant()); /// /// Returns the upper case version of this string /// /// A new instance - public UTF8String ToUpper() { - return new UTF8String(String.ToUpper()); - } + public UTF8String ToUpper() => new UTF8String(String.ToUpper()); /// /// Returns the upper case version of this string /// /// Culture info /// A new instance - public UTF8String ToUpper(CultureInfo culture) { - return new UTF8String(String.ToUpper(culture)); - } + public UTF8String ToUpper(CultureInfo culture) => new UTF8String(String.ToUpper(culture)); /// /// Returns the upper case version of this string using the invariant culture /// /// A new instance - public UTF8String ToUpperInvariant() { - return new UTF8String(String.ToUpperInvariant()); - } + public UTF8String ToUpperInvariant() => new UTF8String(String.ToUpperInvariant()); /// /// Removes all leading and trailing whitespace characters /// /// A new instance - public UTF8String Trim() { - return new UTF8String(String.Trim()); - } + public UTF8String Trim() => new UTF8String(String.Trim()); /// - public override int GetHashCode() { - return UTF8String.GetHashCode(this); - } + public override int GetHashCode() => UTF8String.GetHashCode(this); /// - public override string ToString() { - return String; - } + public override string ToString() => String; } } diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index dd0de3db9..48bacc764 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -16,14 +16,10 @@ public sealed class ByteArrayEqualityComparer : IEqualityComparer { public static readonly ByteArrayEqualityComparer Instance = new ByteArrayEqualityComparer(); /// - public bool Equals(byte[] x, byte[] y) { - return Utils.Equals(x, y); - } + public bool Equals(byte[] x, byte[] y) => Utils.Equals(x, y); /// - public int GetHashCode(byte[] obj) { - return Utils.GetHashCode(obj); - } + public int GetHashCode(byte[] obj) => Utils.GetHashCode(obj); } static class Utils { @@ -164,9 +160,7 @@ internal static int CompareTo(byte[] a, byte[] b) { /// First /// Second /// true if same, false otherwise - internal static bool Equals(byte[] a, byte[] b) { - return CompareTo(a, b) == 0; - } + internal static bool Equals(byte[] a, byte[] b) => CompareTo(a, b) == 0; /// /// Gets the hash code of a byte array @@ -219,9 +213,7 @@ internal static int CompareTo(Version a, Version b) { /// Version #1 or null to be treated as v0.0.0.0 /// Version #2 or null to be treated as v0.0.0.0 /// true if same, false otherwise - internal static bool Equals(Version a, Version b) { - return CompareTo(a, b) == 0; - } + internal static bool Equals(Version a, Version b) => CompareTo(a, b) == 0; /// /// Creates a new instance with no undefined version values (eg. @@ -235,9 +227,7 @@ internal static Version CreateVersionWithNoUndefinedValues(Version a) { return new Version(a.Major, a.Minor, GetDefaultVersionValue(a.Build), GetDefaultVersionValue(a.Revision)); } - static int GetDefaultVersionValue(int val) { - return val == -1 ? 0 : val; - } + static int GetDefaultVersionValue(int val) => val == -1 ? 0 : val; /// /// Parses a version string @@ -260,9 +250,7 @@ internal static Version ParseVersion(string versionString) { /// First /// Second /// < 0 if a < b, 0 if a == b, > 0 if a > b - internal static int LocaleCompareTo(UTF8String a, UTF8String b) { - return GetCanonicalLocale(a).CompareTo(GetCanonicalLocale(b)); - } + internal static int LocaleCompareTo(UTF8String a, UTF8String b) => GetCanonicalLocale(a).CompareTo(GetCanonicalLocale(b)); /// /// Compares two locales (cultures) @@ -270,9 +258,7 @@ internal static int LocaleCompareTo(UTF8String a, UTF8String b) { /// First /// Second /// true if same, false otherwise - internal static bool LocaleEquals(UTF8String a, UTF8String b) { - return LocaleCompareTo(a, b) == 0; - } + internal static bool LocaleEquals(UTF8String a, UTF8String b) => LocaleCompareTo(a, b) == 0; /// /// Compares two locales (cultures) @@ -280,9 +266,7 @@ internal static bool LocaleEquals(UTF8String a, UTF8String b) { /// First /// Second /// < 0 if a < b, 0 if a == b, > 0 if a > b - internal static int LocaleCompareTo(UTF8String a, string b) { - return GetCanonicalLocale(a).CompareTo(GetCanonicalLocale(b)); - } + internal static int LocaleCompareTo(UTF8String a, string b) => GetCanonicalLocale(a).CompareTo(GetCanonicalLocale(b)); /// /// Compares two locales (cultures) @@ -290,22 +274,16 @@ internal static int LocaleCompareTo(UTF8String a, string b) { /// First /// Second /// true if same, false otherwise - internal static bool LocaleEquals(UTF8String a, string b) { - return LocaleCompareTo(a, b) == 0; - } + internal static bool LocaleEquals(UTF8String a, string b) => LocaleCompareTo(a, b) == 0; /// /// Gets the hash code of a locale /// /// Value /// The hash code - internal static int GetHashCodeLocale(UTF8String a) { - return GetCanonicalLocale(a).GetHashCode(); - } + internal static int GetHashCodeLocale(UTF8String a) => GetCanonicalLocale(a).GetHashCode(); - static string GetCanonicalLocale(UTF8String locale) { - return GetCanonicalLocale(UTF8String.ToSystemStringOrEmpty(locale)); - } + static string GetCanonicalLocale(UTF8String locale) => GetCanonicalLocale(UTF8String.ToSystemStringOrEmpty(locale)); static string GetCanonicalLocale(string locale) { var s = locale.ToUpperInvariant(); @@ -319,18 +297,14 @@ static string GetCanonicalLocale(string locale) { /// /// Value /// Alignment - public static uint AlignUp(uint v, uint alignment) { - return (v + alignment - 1) & ~(alignment - 1); - } + public static uint AlignUp(uint v, uint alignment) => (v + alignment - 1) & ~(alignment - 1); /// /// Align up /// /// Value /// Alignment - public static int AlignUp(int v, uint alignment) { - return (int)AlignUp((uint)v, alignment); - } + public static int AlignUp(int v, uint alignment) => (int)AlignUp((uint)v, alignment); /// /// Gets length of compressed integer diff --git a/src/DotNet/VTableFixups.cs b/src/DotNet/VTableFixups.cs index 024012bdb..b1848d73c 100644 --- a/src/DotNet/VTableFixups.cs +++ b/src/DotNet/VTableFixups.cs @@ -26,47 +26,41 @@ public sealed class VTableFixups : IEnumerable { /// Gets/sets the RVA of the vtable fixups /// public RVA RVA { - get { return rva; } - set { rva = value; } + get => rva; + set => rva = value; } /// /// Gets all s /// - public ThreadSafe.IList VTables { - get { return vtables; } - } + public ThreadSafe.IList VTables => vtables; /// /// Default constructor /// - public VTableFixups() { - this.vtables = ThreadSafeListCreator.Create(); - } + public VTableFixups() => vtables = ThreadSafeListCreator.Create(); /// /// Constructor /// /// Module - public VTableFixups(ModuleDefMD module) { - Initialize(module); - } + public VTableFixups(ModuleDefMD module) => Initialize(module); void Initialize(ModuleDefMD module) { var info = module.MetaData.ImageCor20Header.VTableFixups; if (info.VirtualAddress == 0 || info.Size == 0) { - this.vtables = ThreadSafeListCreator.Create(); + vtables = ThreadSafeListCreator.Create(); return; } - this.rva = info.VirtualAddress; - this.vtables = ThreadSafeListCreator.Create((int)info.Size / 8); + rva = info.VirtualAddress; + vtables = ThreadSafeListCreator.Create((int)info.Size / 8); var peImage = module.MetaData.PEImage; using (var reader = peImage.CreateFullStream()) { reader.Position = (long)peImage.ToFileOffset(info.VirtualAddress); long endPos = reader.Position + info.Size; while (reader.Position + 8 <= endPos && reader.CanRead(8)) { - RVA tableRva = (RVA)reader.ReadUInt32(); + var tableRva = (RVA)reader.ReadUInt32(); int numSlots = reader.ReadUInt16(); var flags = (VTableFlags)reader.ReadUInt16(); var vtable = new VTable(tableRva, flags, numSlots); @@ -86,14 +80,10 @@ void Initialize(ModuleDefMD module) { } /// - public IEnumerator GetEnumerator() { - return vtables.GetEnumerator(); - } + public IEnumerator GetEnumerator() => vtables.GetEnumerator(); /// - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return GetEnumerator(); - } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); } /// @@ -139,45 +129,37 @@ public sealed class VTable : IEnumerable { /// Gets/sets the of this vtable /// public RVA RVA { - get { return rva; } - set { rva = value; } + get => rva; + set => rva = value; } /// /// Gets/sets the flags /// public VTableFlags Flags { - get { return flags; } - set { flags = value; } + get => flags; + set => flags = value; } /// /// true if each vtable slot is 32 bits in size /// - public bool Is32Bit { - get { return (flags & VTableFlags._32Bit) != 0; } - } + public bool Is32Bit => (flags & VTableFlags._32Bit) != 0; /// /// true if each vtable slot is 64 bits in size /// - public bool Is64Bit { - get { return (flags & VTableFlags._64Bit) != 0; } - } + public bool Is64Bit => (flags & VTableFlags._64Bit) != 0; /// /// Gets the vtable methods /// - public ThreadSafe.IList Methods { - get { return methods; } - } + public ThreadSafe.IList Methods => methods; /// /// Default constructor /// - public VTable() { - this.methods = ThreadSafeListCreator.Create(); - } + public VTable() => methods = ThreadSafeListCreator.Create(); /// /// Constructor @@ -185,7 +167,7 @@ public VTable() { /// Flags public VTable(VTableFlags flags) { this.flags = flags; - this.methods = ThreadSafeListCreator.Create(); + methods = ThreadSafeListCreator.Create(); } /// @@ -197,7 +179,7 @@ public VTable(VTableFlags flags) { public VTable(RVA rva, VTableFlags flags, int numSlots) { this.rva = rva; this.flags = flags; - this.methods = ThreadSafeListCreator.Create(numSlots); + methods = ThreadSafeListCreator.Create(numSlots); } /// @@ -213,20 +195,16 @@ public VTable(RVA rva, VTableFlags flags, IEnumerable methods) { } /// - public IEnumerator GetEnumerator() { - return methods.GetEnumerator(); - } + public IEnumerator GetEnumerator() => methods.GetEnumerator(); /// - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return GetEnumerator(); - } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); /// public override string ToString() { if (methods.Count == 0) - return string.Format("{0} {1:X8}", methods.Count, (uint)rva); - return string.Format("{0} {1:X8} {2}", methods.Count, (uint)rva, methods.Get(0, null)); + return $"{methods.Count} {(uint)rva:X8}"; + return $"{methods.Count} {(uint)rva:X8} {methods.Get(0, null)}"; } } } diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index b5483be8e..8d6f68c70 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -15,37 +15,30 @@ enum ClrAssembly { } static class WinMDHelpers { - struct ClassName : IEquatable { + readonly struct ClassName : IEquatable { public readonly UTF8String Namespace; public readonly UTF8String Name; // Not used when comparing for equality etc public readonly bool IsValueType; public ClassName(UTF8String ns, UTF8String name, bool isValueType = false) { - this.Namespace = ns; - this.Name = name; - this.IsValueType = isValueType; + Namespace = ns; + Name = name; + IsValueType = isValueType; } public ClassName(string ns, string name, bool isValueType = false) { - this.Namespace = ns; - this.Name = name; - this.IsValueType = isValueType; + Namespace = ns; + Name = name; + IsValueType = isValueType; } - public static bool operator ==(ClassName a, ClassName b) { - return a.Equals(b); - } - - public static bool operator !=(ClassName a, ClassName b) { - return !a.Equals(b); - } + public static bool operator ==(ClassName a, ClassName b) => a.Equals(b); + public static bool operator !=(ClassName a, ClassName b) => !a.Equals(b); - public bool Equals(ClassName other) { + public bool Equals(ClassName other) => // Don't check IsValueType - return UTF8String.Equals(Namespace, other.Namespace) && - UTF8String.Equals(Name, other.Name); - } + UTF8String.Equals(Namespace, other.Namespace) && UTF8String.Equals(Name, other.Name); public override bool Equals(object obj) { if (!(obj is ClassName)) @@ -53,14 +46,11 @@ public override bool Equals(object obj) { return Equals((ClassName)obj); } - public override int GetHashCode() { + public override int GetHashCode() => // Don't use IsValueType - return UTF8String.GetHashCode(Namespace) ^ UTF8String.GetHashCode(Name); - } + UTF8String.GetHashCode(Namespace) ^ UTF8String.GetHashCode(Name); - public override string ToString() { - return string.Format("{0}.{1}", Namespace, Name); - } + public override string ToString() => $"{Namespace}.{Name}"; } sealed class ProjectedClass { @@ -70,15 +60,13 @@ sealed class ProjectedClass { public readonly ClrAssembly ContractAssembly; public ProjectedClass(string mdns, string mdname, string clrns, string clrname, ClrAssembly clrAsm, ClrAssembly contractAsm, bool winMDValueType, bool clrValueType) { - this.WinMDClass = new ClassName(mdns, mdname, winMDValueType); - this.ClrClass = new ClassName(clrns, clrname, clrValueType); - this.ClrAssembly = clrAsm; - this.ContractAssembly = contractAsm; + WinMDClass = new ClassName(mdns, mdname, winMDValueType); + ClrClass = new ClassName(clrns, clrname, clrValueType); + ClrAssembly = clrAsm; + ContractAssembly = contractAsm; } - public override string ToString() { - return string.Format("{0} <-> {1}, {2}", WinMDClass, ClrClass, CreateAssembly(null, ContractAssembly)); - } + public override string ToString() => $"{WinMDClass} <-> {ClrClass}, {CreateAssembly(null, ContractAssembly)}"; } // See https://github.com/dotnet/coreclr/blob/master/src/inc/winrtprojectedtypes.h @@ -172,8 +160,7 @@ static WinMDHelpers() { } static AssemblyRef ToCLR(ModuleDef module, ref UTF8String ns, ref UTF8String name) { - ProjectedClass pc; - if (!winMDToCLR.TryGetValue(new ClassName(ns, name), out pc)) + if (!winMDToCLR.TryGetValue(new ClassName(ns, name), out var pc)) return null; ns = pc.ClrClass.Namespace; @@ -182,14 +169,12 @@ static AssemblyRef ToCLR(ModuleDef module, ref UTF8String ns, ref UTF8String nam } static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { - var mscorlib = module == null ? null : module.CorLibTypes.AssemblyRef; - + var mscorlib = module?.CorLibTypes.AssemblyRef; var asm = new AssemblyRefUser(GetName(clrAsm), contractAsmVersion, new PublicKeyToken(GetPublicKeyToken(clrAsm)), UTF8String.Empty); if (mscorlib != null && mscorlib.Name == mscorlibName && mscorlib.Version != invalidWinMDVersion) asm.Version = mscorlib.Version; - var mod = module as ModuleDefMD; - if (mod != null) { + if (module is ModuleDefMD mod) { Version ver = null; foreach (var asmRef in mod.GetAssemblyRefs()) { if (asmRef.IsContentTypeWindowsRuntime) @@ -258,10 +243,7 @@ static byte[] GetPublicKeyToken(ClrAssembly clrAsm) { /// Owner module or null /// Type /// - public static TypeRef ToCLR(ModuleDef module, TypeDef td) { - bool isClrValueType; - return ToCLR(module, td, out isClrValueType); - } + public static TypeRef ToCLR(ModuleDef module, TypeDef td) => ToCLR(module, td, out bool isClrValueType); /// /// Converts WinMD type to a CLR type. Returns null @@ -279,8 +261,7 @@ public static TypeRef ToCLR(ModuleDef module, TypeDef td, out bool isClrValueTyp if (asm == null || !asm.IsContentTypeWindowsRuntime) return null; - ProjectedClass pc; - if (!winMDToCLR.TryGetValue(new ClassName(td.Namespace, td.Name), out pc)) + if (!winMDToCLR.TryGetValue(new ClassName(td.Namespace, td.Name), out var pc)) return null; isClrValueType = pc.ClrClass.IsValueType; @@ -294,10 +275,7 @@ public static TypeRef ToCLR(ModuleDef module, TypeDef td, out bool isClrValueTyp /// Owner module or null /// Type /// - public static TypeRef ToCLR(ModuleDef module, TypeRef tr) { - bool isClrValueType; - return ToCLR(module, tr, out isClrValueType); - } + public static TypeRef ToCLR(ModuleDef module, TypeRef tr) => ToCLR(module, tr, out bool isClrValueType); /// /// Converts WinMD type to a CLR type. Returns null @@ -317,8 +295,7 @@ public static TypeRef ToCLR(ModuleDef module, TypeRef tr, out bool isClrValueTyp if (tr.DeclaringType != null) return null; - ProjectedClass pc; - if (!winMDToCLR.TryGetValue(new ClassName(tr.Namespace, tr.Name), out pc)) + if (!winMDToCLR.TryGetValue(new ClassName(tr.Namespace, tr.Name), out var pc)) return null; isClrValueType = pc.ClrClass.IsValueType; @@ -341,8 +318,7 @@ public static ExportedType ToCLR(ModuleDef module, ExportedType et) { if (et.DeclaringType != null) return null; - ProjectedClass pc; - if (!winMDToCLR.TryGetValue(new ClassName(et.TypeNamespace, et.TypeName), out pc)) + if (!winMDToCLR.TryGetValue(new ClassName(et.TypeNamespace, et.TypeName), out var pc)) return null; return new ExportedTypeUser(module, 0, pc.ClrClass.Namespace, pc.ClrClass.Name, et.Attributes, CreateAssembly(module, pc.ContractAssembly)); @@ -364,10 +340,9 @@ public static TypeSig ToCLR(ModuleDef module, TypeSig ts) { var tdr = ((ClassOrValueTypeSig)ts).TypeDefOrRef; - TypeDef td; TypeRef tr, newTr; bool isClrValueType; - if ((td = tdr as TypeDef) != null) { + if (tdr is TypeDef td) { newTr = ToCLR(module, td, out isClrValueType); if (newTr == null) return null; @@ -406,9 +381,8 @@ public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { var cl = mr.Class; IMemberRefParent newCl; - TypeRef tr; TypeSpec ts; - if ((tr = cl as TypeRef) != null) { + if (cl is TypeRef tr) { var newTr = ToCLR(module, tr); if (newTr == null || !IsIDisposable(newTr)) return null; @@ -423,8 +397,7 @@ public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { if (tr == null) return null; - bool isClrValueType; - var newTr = ToCLR(module, tr, out isClrValueType); + var newTr = ToCLR(module, tr, out bool isClrValueType); if (newTr == null || !IsIDisposable(newTr)) return null; @@ -440,9 +413,7 @@ public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { static readonly UTF8String CloseName = new UTF8String("Close"); static readonly UTF8String DisposeName = new UTF8String("Dispose"); - static bool IsIDisposable(TypeRef tr) { - return tr.Name == IDisposableName && tr.Namespace == IDisposableNamespace; - } + static bool IsIDisposable(TypeRef tr) => tr.Name == IDisposableName && tr.Namespace == IDisposableNamespace; static readonly UTF8String IDisposableNamespace = new UTF8String("System"); static readonly UTF8String IDisposableName = new UTF8String("IDisposable"); diff --git a/src/DotNet/Writer/BinaryReaderChunk.cs b/src/DotNet/Writer/BinaryReaderChunk.cs index 5d06428d5..b8030d8b5 100644 --- a/src/DotNet/Writer/BinaryReaderChunk.cs +++ b/src/DotNet/Writer/BinaryReaderChunk.cs @@ -17,19 +17,13 @@ public class BinaryReaderChunk : IChunk { /// /// Gets the data /// - public IBinaryReader Data { - get { return data; } - } + public IBinaryReader Data => data; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Constructor @@ -56,14 +50,10 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return (uint)data.Length; - } + public uint GetFileLength() => (uint)data.Length; /// - public uint GetVirtualSize() { - return virtualSize; - } + public uint GetVirtualSize() => virtualSize; /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index d86ceac2e..a941e9147 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -18,9 +18,7 @@ public sealed class BlobHeap : HeapBase, IOffsetHeap { Dictionary userRawData; /// - public override string Name { - get { return "#Blob"; } - } + public override string Name => "#Blob"; /// /// Populates blobs from an existing (eg. to preserve @@ -48,8 +46,7 @@ void Populate(IImageStream reader) { reader.Position = 1; while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; - uint len; - if (!reader.ReadCompressedUInt32(out len)) { + if (!reader.ReadCompressedUInt32(out uint len)) { if (offset == reader.Position) reader.Position++; continue; @@ -74,8 +71,7 @@ public uint Add(byte[] data) { if (data == null || data.Length == 0) return 0; - uint offset; - if (cachedDict.TryGetValue(data, out offset)) + if (cachedDict.TryGetValue(data, out uint offset)) return offset; return AddToCache(data); } @@ -100,9 +96,7 @@ uint AddToCache(byte[] data) { } /// - public override uint GetRawLength() { - return nextOffset; - } + public override uint GetRawLength() => nextOffset; /// protected override void WriteToImpl(BinaryWriter writer) { @@ -114,8 +108,7 @@ protected override void WriteToImpl(BinaryWriter writer) { uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var data in cached) { int rawLen = GetRawDataSize(data); - byte[] rawData; - if (userRawData != null && userRawData.TryGetValue(offset, out rawData)) { + if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); writer.Write(rawData); @@ -129,17 +122,13 @@ protected override void WriteToImpl(BinaryWriter writer) { } /// - public int GetRawDataSize(byte[] data) { - return Utils.GetCompressedUInt32Length((uint)data.Length) + data.Length; - } + public int GetRawDataSize(byte[] data) => Utils.GetCompressedUInt32Length((uint)data.Length) + data.Length; /// public void SetRawData(uint offset, byte[] rawData) { - if (rawData == null) - throw new ArgumentNullException("rawData"); if (userRawData == null) userRawData = new Dictionary(); - userRawData[offset] = rawData; + userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); } /// diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 75f1f9a89..041977026 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -14,21 +14,15 @@ public sealed class ByteArrayChunk : IChunk { RVA rva; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the data /// - public byte[] Data { - get { return array; } - } + public byte[] Data => array; /// /// Constructor @@ -38,9 +32,7 @@ public byte[] Data { /// return value will be different if you modify the array). If /// it's never inserted as a key in a dictionary, then the contents can be modified, /// but shouldn't be resized after has been called. - public ByteArrayChunk(byte[] array) { - this.array = array ?? new byte[0]; - } + public ByteArrayChunk(byte[] array) => this.array = array ?? new byte[0]; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -49,24 +41,16 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return (uint)array.Length; - } + public uint GetFileLength() => (uint)array.Length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { - writer.Write(array); - } + public void WriteTo(BinaryWriter writer) => writer.Write(array); /// - public override int GetHashCode() { - return Utils.GetHashCode(array); - } + public override int GetHashCode() => Utils.GetHashCode(array); /// public override bool Equals(object obj) { diff --git a/src/DotNet/Writer/ChunkList.cs b/src/DotNet/Writer/ChunkList.cs index 9b44b7f66..c04df817f 100644 --- a/src/DotNet/Writer/ChunkList.cs +++ b/src/DotNet/Writer/ChunkList.cs @@ -11,9 +11,7 @@ public class ChunkList : ChunkListBase where T : class, IChunk { /// /// Default constructor /// - public ChunkList() { - this.chunks = new List(); - } + public ChunkList() => chunks = new List(); /// /// Add a diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index ff81a54dd..4a9b566b6 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -23,7 +23,7 @@ public abstract class ChunkListBase : IChunk where T : IChunk { /// /// Helper struct /// - protected struct Elem { + protected readonly struct Elem { /// Data public readonly T chunk; /// Alignment @@ -50,31 +50,22 @@ protected sealed class ElemEqualityComparer : IEqualityComparer { /// Constructor /// /// Compares the chunk type - public ElemEqualityComparer(IEqualityComparer chunkComparer) { - this.chunkComparer = chunkComparer; - } + public ElemEqualityComparer(IEqualityComparer chunkComparer) => this.chunkComparer = chunkComparer; /// - public bool Equals(Elem x, Elem y) { - return x.alignment == y.alignment && - chunkComparer.Equals(x.chunk, y.chunk); - } + public bool Equals(Elem x, Elem y) => + x.alignment == y.alignment && + chunkComparer.Equals(x.chunk, y.chunk); /// - public int GetHashCode(Elem obj) { - return (int)obj.alignment + chunkComparer.GetHashCode(obj.chunk); - } + public int GetHashCode(Elem obj) => (int)obj.alignment + chunkComparer.GetHashCode(obj.chunk); } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// public virtual void SetOffset(FileOffset offset, RVA rva) { @@ -105,18 +96,14 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return virtualSize; - } + public uint GetVirtualSize() => virtualSize; /// public void WriteTo(BinaryWriter writer) { - FileOffset offset2 = offset; + var offset2 = offset; foreach (var elem in chunks) { if (elem.chunk.GetVirtualSize() == 0) continue; diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index b47623b1f..c2d979eb1 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -64,27 +64,25 @@ internal static byte[] Write(ICustomAttributeWriterHelper helper, IList outStream.ToArray(); void Write(CustomAttribute ca) { if (ca == null) { @@ -119,18 +117,9 @@ void Write(CustomAttribute ca) { if (ca.NamedArguments.Count > ushort.MaxValue) helper.Error("Custom attribute has too many named arguments"); - // A generic custom attribute isn't allowed by most .NET languages (eg. C#) but - // the CLR probably supports it. - var mrCtor = ca.Constructor as MemberRef; - if (mrCtor != null) { - var owner = mrCtor.Class as TypeSpec; - if (owner != null) { - var gis = owner.TypeSig as GenericInstSig; - if (gis != null) { - genericArguments = new GenericArguments(); - genericArguments.PushTypeArgs(gis.GenericArguments); - } - } + if (ca.Constructor is MemberRef mrCtor && mrCtor.Class is TypeSpec owner && owner.TypeSig is GenericInstSig gis) { + genericArguments = new GenericArguments(); + genericArguments.PushTypeArgs(gis.GenericArguments); } writer.Write((ushort)1); @@ -155,9 +144,7 @@ void Write(IList namedArgs) { Write(namedArgs[i]); } - TypeSig FixTypeSig(TypeSig type) { - return SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); - } + TypeSig FixTypeSig(TypeSig type) => SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); TypeSig SubstituteGenericParameter(TypeSig type) { if (genericArguments == null) @@ -175,8 +162,7 @@ void WriteValue(TypeSig argType, CAArgument value) { return; } - var arrayType = argType as SZArraySig; - if (arrayType != null) { + if (argType is SZArraySig arrayType) { var argsArray = value.Value as IList; if (argsArray == null && value.Value != null) helper.Error("CAArgument.Value is not null or an array"); @@ -252,8 +238,7 @@ static bool VerifyValue(object o, ElementType etype) { } static ulong ToUInt64(object o) { - ulong result; - ToUInt64(o, out result); + ToUInt64(o, out ulong result); return result; } @@ -318,8 +303,7 @@ static bool ToUInt64(object o, out ulong result) { } static double ToDouble(object o) { - double result; - ToDouble(o, out result); + ToDouble(o, out double result); return result; } @@ -512,8 +496,7 @@ void WriteElem(TypeSig argType, CAArgument value) { tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; if (CheckCorLibType(argType, "Type")) { if (CheckCorLibType(value.Type, "Type")) { - var ts = value.Value as TypeSig; - if (ts != null) + if (value.Value is TypeSig ts) WriteType(ts); else if (value.Value == null) WriteUTF8String(null); @@ -621,8 +604,7 @@ static TypeDef GetEnumTypeDef(TypeSig type) { /// A or null if we couldn't resolve the /// or if is a type spec static TypeDef GetTypeDef(TypeSig type) { - var tdr = type as TypeDefOrRefSig; - if (tdr != null) { + if (type is TypeDefOrRefSig tdr) { var td = tdr.TypeDef; if (td != null) return td; @@ -754,9 +736,7 @@ static bool CheckCorLibType(ITypeDefOrRef tdr, string name) { return tdr.TypeName == name && tdr.Namespace == "System"; } - static MethodSig GetMethodSig(ICustomAttributeType ctor) { - return ctor == null ? null : ctor.MethodSig; - } + static MethodSig GetMethodSig(ICustomAttributeType ctor) => ctor?.MethodSig; void WriteUTF8String(UTF8String s) { if ((object)s == null || s.Data == null) diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index 4f2b16acb..6197d0521 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -25,9 +25,7 @@ public sealed class DebugDirectoryEntry { /// Constructor /// /// Data - public DebugDirectoryEntry(IChunk chunk) { - Chunk = chunk; - } + public DebugDirectoryEntry(IChunk chunk) => Chunk = chunk; } /// @@ -44,30 +42,22 @@ public sealed class DebugDirectory : IChunk { readonly List entries; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Constructor /// - public DebugDirectory() { - entries = new List(); - } + public DebugDirectory() => entries = new List(); /// /// Adds data /// /// Data /// - public DebugDirectoryEntry Add(byte[] data) { - return Add(new ByteArrayChunk(data)); - } + public DebugDirectoryEntry Add(byte[] data) => Add(new ByteArrayChunk(data)); /// /// Adds data @@ -94,14 +84,10 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 62680dc34..d1a6f68ac 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Writer { /// /// Writes DeclSecurity blobs /// - public struct DeclSecurityWriter : ICustomAttributeWriterHelper { + public readonly struct DeclSecurityWriter : ICustomAttributeWriterHelper { readonly ModuleDef module; readonly IWriterError helper; readonly BinaryWriterContext context; @@ -20,13 +20,11 @@ public struct DeclSecurityWriter : ICustomAttributeWriterHelper { /// List of s /// Helps this class /// A DeclSecurity blob - public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper) { - return new DeclSecurityWriter(module, helper, null).Write(secAttrs); - } + public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper) => + new DeclSecurityWriter(module, helper, null).Write(secAttrs); - internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, BinaryWriterContext context) { - return new DeclSecurityWriter(module, helper, context).Write(secAttrs); - } + internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, BinaryWriterContext context) => + new DeclSecurityWriter(module, helper, context).Write(secAttrs); DeclSecurityWriter(ModuleDef module, IWriterError helper, BinaryWriterContext context) { this.module = module; @@ -44,9 +42,7 @@ byte[] Write(IList secAttrs) { return WriteFormat2(secAttrs); } - byte[] WriteFormat1(string xml) { - return Encoding.Unicode.GetBytes(xml); - } + byte[] WriteFormat1(string xml) => Encoding.Unicode.GetBytes(xml); byte[] WriteFormat2(IList secAttrs) { using (var stream = new MemoryStream()) @@ -87,20 +83,9 @@ byte[] WriteFormat2(IList secAttrs) { } } - uint WriteCompressedUInt32(BinaryWriter writer, uint value) { - return writer.WriteCompressedUInt32(helper, value); - } - - void Write(BinaryWriter writer, UTF8String s) { - writer.Write(helper, s); - } - - void IWriterError.Error(string message) { - helper.Error(message); - } - - bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) { - return FullNameCreator.MustUseAssemblyName(module, type); - } + uint WriteCompressedUInt32(BinaryWriter writer, uint value) => writer.WriteCompressedUInt32(helper, value); + void Write(BinaryWriter writer, UTF8String s) => writer.Write(helper, s); + void IWriterError.Error(string message) => helper.Error(message); + bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); } } diff --git a/src/DotNet/Writer/GuidHeap.cs b/src/DotNet/Writer/GuidHeap.cs index 3c27e846c..759b2e8a4 100644 --- a/src/DotNet/Writer/GuidHeap.cs +++ b/src/DotNet/Writer/GuidHeap.cs @@ -13,9 +13,7 @@ public sealed class GuidHeap : HeapBase, IOffsetHeap { Dictionary userRawData; /// - public override string Name { - get { return "#GUID"; } - } + public override string Name => "#GUID"; /// /// Adds a guid to the #GUID heap @@ -28,8 +26,7 @@ public uint Add(Guid? guid) { if (guid == null) return 0; - uint index; - if (guids.TryGetValue(guid.Value, out index)) + if (guids.TryGetValue(guid.Value, out uint index)) return index; index = (uint)guids.Count + 1; @@ -38,16 +35,13 @@ public uint Add(Guid? guid) { } /// - public override uint GetRawLength() { - return (uint)guids.Count * 16; - } + public override uint GetRawLength() => (uint)guids.Count * 16; /// protected override void WriteToImpl(BinaryWriter writer) { uint offset = 0; foreach (var kv in guids) { - byte[] rawData; - if (userRawData == null || !userRawData.TryGetValue(offset, out rawData)) + if (userRawData == null || !userRawData.TryGetValue(offset, out var rawData)) rawData = kv.Key.ToByteArray(); writer.Write(rawData); offset += 16; @@ -55,9 +49,7 @@ protected override void WriteToImpl(BinaryWriter writer) { } /// - public int GetRawDataSize(Guid data) { - return 16; - } + public int GetRawDataSize(Guid data) => 16; /// public void SetRawData(uint offset, byte[] rawData) { diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index 88c1e7934..99df18d24 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -19,34 +19,24 @@ public abstract class HeapBase : IHeap { protected bool isReadOnly; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// public abstract string Name { get; } /// - public bool IsEmpty { - get { return GetRawLength() <= 1; } - } + public bool IsEmpty => GetRawLength() <= 1; /// /// true if offsets require 4 bytes instead of 2 bytes. /// - public bool IsBig { - get { return GetFileLength() > 0xFFFF; } - } + public bool IsBig => GetFileLength() > 0xFFFF; /// - public void SetReadOnly() { - isReadOnly = true; - } + public void SetReadOnly() => isReadOnly = true; /// public virtual void SetOffset(FileOffset offset, RVA rva) { @@ -55,14 +45,10 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return Utils.AlignUp(GetRawLength(), ALIGNMENT); - } + public uint GetFileLength() => Utils.AlignUp(GetRawLength(), ALIGNMENT); /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// /// Gets the raw length of the heap @@ -83,8 +69,6 @@ public void WriteTo(BinaryWriter writer) { protected abstract void WriteToImpl(BinaryWriter writer); /// - public override string ToString() { - return Name; - } + public override string ToString() => Name; } } diff --git a/src/DotNet/Writer/HotHeap.cs b/src/DotNet/Writer/HotHeap.cs index 67c44b366..cd5d6d185 100644 --- a/src/DotNet/Writer/HotHeap.cs +++ b/src/DotNet/Writer/HotHeap.cs @@ -32,17 +32,13 @@ abstract class HotHeap : HeapBase { public abstract HotHeapVersion HotHeapVersion { get; } /// - public override string Name { - get { return "#!"; } - } + public override string Name => "#!"; /// /// Constructor /// /// Metadata owner - protected HotHeap(MetaData metadata) { - this.metadata = metadata; - } + protected HotHeap(MetaData metadata) => this.metadata = metadata; /// /// Creates a instance @@ -61,9 +57,7 @@ protected HotHeap(MetaData metadata) { /// /// Metadata owner /// Target module - public static HotHeap Create(MetaData metadata, ModuleDef module) { - return Create(metadata, GetHotHeapVersion(module)); - } + public static HotHeap Create(MetaData metadata, ModuleDef module) => Create(metadata, GetHotHeapVersion(module)); /// /// Creates a hot heap instance @@ -103,9 +97,7 @@ public void Add(HotTable hotTable) { /// Adds a hot pool /// /// The hot pool - public void Add(HotPool hotPool) { - hotPools.Add(hotPool); - } + public void Add(HotPool hotPool) => hotPools.Add(hotPool); /// public override void SetOffset(FileOffset offset, RVA rva) { @@ -149,9 +141,7 @@ static void Align(ref FileOffset offset, ref RVA rva) { } /// - public override uint GetRawLength() { - return totalLength; - } + public override uint GetRawLength() => totalLength; /// protected override void WriteToImpl(BinaryWriter writer) { @@ -217,9 +207,7 @@ static void WriteAlign(BinaryWriter writer, ref uint offs) { /// sealed class HotHeap20 : HotHeap { /// - public override HotHeapVersion HotHeapVersion { - get { return HotHeapVersion.CLR20; } - } + public override HotHeapVersion HotHeapVersion => HotHeapVersion.CLR20; /// /// Constructor @@ -229,14 +217,10 @@ public HotHeap20(MetaData metadata) : base(metadata) { } /// - public override HotTable CreateHotTable(IMDTable mdTable) { - return new HotTable20(metadata, mdTable); - } + public override HotTable CreateHotTable(IMDTable mdTable) => new HotTable20(metadata, mdTable); /// - public override HotPool CreateHotPool(HeapType heapType) { - return new HotPool20(heapType); - } + public override HotPool CreateHotPool(HeapType heapType) => new HotPool20(heapType); } /// @@ -244,9 +228,7 @@ public override HotPool CreateHotPool(HeapType heapType) { /// sealed class HotHeap40 : HotHeap { /// - public override HotHeapVersion HotHeapVersion { - get { return HotHeapVersion.CLR40; } - } + public override HotHeapVersion HotHeapVersion => HotHeapVersion.CLR40; /// /// Constructor @@ -256,13 +238,9 @@ public HotHeap40(MetaData metadata) : base(metadata) { } /// - public override HotTable CreateHotTable(IMDTable mdTable) { - return new HotTable40(metadata, mdTable); - } + public override HotTable CreateHotTable(IMDTable mdTable) => new HotTable40(metadata, mdTable); /// - public override HotPool CreateHotPool(HeapType heapType) { - return new HotPool40(heapType); - } + public override HotPool CreateHotPool(HeapType heapType) => new HotPool40(heapType); } } diff --git a/src/DotNet/Writer/HotPool.cs b/src/DotNet/Writer/HotPool.cs index 0b36b7c7e..e0700bbe7 100644 --- a/src/DotNet/Writer/HotPool.cs +++ b/src/DotNet/Writer/HotPool.cs @@ -31,59 +31,45 @@ internal class DataInfo { public uint PoolOffset; public readonly byte[] Data; public DataInfo(uint heapOffset, byte[] data) { - this.HeapOffset = heapOffset; - this.Data = data; + HeapOffset = heapOffset; + Data = data; } } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the offset of the data relative to the start of this chunk. This is valid only /// after has been called. /// - public uint DataOffset { - get { return dataOffset; } - } + public uint DataOffset => dataOffset; /// /// Gets the offset of the indexes relative to the start of this chunk. This is valid only /// after has been called. /// - public uint IndexesOffset { - get { return indexesOffset; } - } + public uint IndexesOffset => indexesOffset; /// /// Gets the offset of the rids relative to the start of this chunk. This is valid only /// after has been called. /// - public uint RidsOffset { - get { return ridsOffset; } - } + public uint RidsOffset => ridsOffset; /// /// Gets the offset of the header relative to the start of this chunk. This is valid only /// after has been called. /// - public uint HeaderOffset { - get { return headerOffset; } - } + public uint HeaderOffset => headerOffset; /// /// Gets the pool type /// - public HeapType HeapType { - get { return heapType; } - } + public HeapType HeapType => heapType; /// /// Constructor @@ -91,7 +77,7 @@ public HeapType HeapType { /// Pool type internal HotPool(HeapType heapType) { this.heapType = heapType; - this.allData = new Dictionary(); + allData = new Dictionary(); } /// @@ -140,9 +126,7 @@ public void SortData() { /// /// Creates the data and shuffles it /// - public void ShuffleData() { - ShuffleData(new Random()); - } + public void ShuffleData() => ShuffleData(new Random()); /// /// Creates the data and shuffles it @@ -202,14 +186,10 @@ internal uint GetDataSize() { } /// - public uint GetFileLength() { - return totalLength; - } + public uint GetFileLength() => totalLength; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/HotTable.cs b/src/DotNet/Writer/HotTable.cs index caefea991..b9cfe8d1d 100644 --- a/src/DotNet/Writer/HotTable.cs +++ b/src/DotNet/Writer/HotTable.cs @@ -48,25 +48,17 @@ public abstract class HotTable : IChunk { /// true if we can write a partial table, false if we must write /// the full table. /// - public bool CanWritePartialTable { - get { - return data == null && rids != null && rids.Count <= MAX_ROWS; - } - } + public bool CanWritePartialTable => data == null && rids != null && rids.Count <= MAX_ROWS; /// /// Gets the full size of the table /// - uint FullTableSize { - get { return (uint)(mdTable.Rows * mdTable.TableInfo.RowSize); } - } + uint FullTableSize => (uint)(mdTable.Rows * mdTable.TableInfo.RowSize); /// /// Gets the table type /// - public Table Table { - get { return mdTable.Table; } - } + public Table Table => mdTable.Table; /// /// Constructor @@ -90,18 +82,14 @@ internal HotTable(MetaData metadata, HotHeapVersion version, IMDTable mdTable) { throw new ArgumentException("Invalid hot heap version"); } - this.alignedHotTableHeaderSize = Utils.AlignUp(this.hotTableHeaderSize, HT_ALIGNMENT); + alignedHotTableHeaderSize = Utils.AlignUp(hotTableHeaderSize, HT_ALIGNMENT); } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -127,19 +115,13 @@ public void SetOffset(FileOffset offset, RVA rva) { /// Calculates the total size required to write a full table. It is only called if /// the full table will be written. /// - uint CalculateFullTableLength() { - return (uint)alignedHotTableHeaderSize + FullTableSize; - } + uint CalculateFullTableLength() => (uint)alignedHotTableHeaderSize + FullTableSize; /// - public uint GetFileLength() { - return totalLength; - } + public uint GetFileLength() => totalLength; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// /// Adds a row. This method must be called to write a partial table. If too many rows @@ -330,9 +312,7 @@ internal void WriteFirstLevelTable(BinaryWriter writer) { /// Writes the second level table /// /// Writer - internal void WriteSecondLevelTable(BinaryWriter writer) { - writer.Write(secondLevelTable); - } + internal void WriteSecondLevelTable(BinaryWriter writer) => writer.Write(secondLevelTable); } /// diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index c4c735497..8efb7c22f 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -60,7 +60,7 @@ public static partial class Extensions { public static void VerifyWriteTo(this IChunk chunk, BinaryWriter writer) { long pos = writer.BaseStream.Position; // Uncomment this to add some debug info, useful when comparing old vs new version - //System.Diagnostics.Debug.WriteLine(string.Format(" RVA 0x{0:X8} OFFS 0x{1:X8} VSIZE 0x{2:X8} {3}", (uint)chunk.RVA, (uint)chunk.FileOffset, chunk.GetVirtualSize(), chunk.GetType().FullName)); + //System.Diagnostics.Debug.WriteLine($" RVA 0x{(uint)chunk.RVA:X8} OFFS 0x{(uint)chunk.FileOffset:X8} VSIZE 0x{chunk.GetVirtualSize():X8} {chunk.GetType().FullName}"); chunk.WriteTo(writer); if (writer.BaseStream.Position - pos != chunk.GetFileLength()) throw new IOException("Did not write all bytes"); diff --git a/src/DotNet/Writer/ImageCor20Header.cs b/src/DotNet/Writer/ImageCor20Header.cs index f9eb362f5..c9f0d3514 100644 --- a/src/DotNet/Writer/ImageCor20Header.cs +++ b/src/DotNet/Writer/ImageCor20Header.cs @@ -50,9 +50,7 @@ public Cor20HeaderOptions() { /// Constructor /// /// Flags - public Cor20HeaderOptions(ComImageFlags flags) { - this.Flags = flags; - } + public Cor20HeaderOptions(ComImageFlags flags) => Flags = flags; /// /// Constructor @@ -61,9 +59,9 @@ public Cor20HeaderOptions(ComImageFlags flags) { /// Minor runtime version (default is ) /// Flags public Cor20HeaderOptions(ushort major, ushort minor, ComImageFlags flags) { - this.MajorRuntimeVersion = major; - this.MinorRuntimeVersion = minor; - this.Flags = flags; + MajorRuntimeVersion = major; + MinorRuntimeVersion = minor; + Flags = flags; } } @@ -93,22 +91,16 @@ public sealed class ImageCor20Header : IChunk { internal IChunk VtableFixups { get; set; } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Constructor /// /// Options - public ImageCor20Header(Cor20HeaderOptions options) { - this.options = options; - } + public ImageCor20Header(Cor20HeaderOptions options) => this.options = options; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -117,14 +109,10 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return 0x48; - } + public uint GetFileLength() => 0x48; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/ImportAddressTable.cs b/src/DotNet/Writer/ImportAddressTable.cs index 3b329795b..df35332c1 100644 --- a/src/DotNet/Writer/ImportAddressTable.cs +++ b/src/DotNet/Writer/ImportAddressTable.cs @@ -19,14 +19,10 @@ public sealed class ImportAddressTable : IChunk { public ImportDirectory ImportDirectory { get; set; } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; internal bool Enable { get; set; } @@ -34,9 +30,7 @@ public RVA RVA { /// Constructor /// /// true if it's a 64-bit PE file, false if it's a 32-bit PE file - public ImportAddressTable(bool is64bit) { - this.is64bit = is64bit; - } + public ImportAddressTable(bool is64bit) => this.is64bit = is64bit; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -52,9 +46,7 @@ public uint GetFileLength() { } /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index d23e377e5..e2bf2b162 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -28,34 +28,26 @@ public sealed class ImportDirectory : IChunk { /// /// Gets the RVA of _CorDllMain/_CorExeMain in the import lookup table /// - public RVA CorXxxMainRVA { - get { return corXxxMainRVA; } - } + public RVA CorXxxMainRVA => corXxxMainRVA; /// /// Gets RVA of _CorExeMain/_CorDllMain in the IAT /// - public RVA IatCorXxxMainRVA { - get { return ImportAddressTable.RVA; } - } + public RVA IatCorXxxMainRVA => ImportAddressTable.RVA; /// /// Gets/sets a value indicating whether this is a EXE or a DLL file /// public bool IsExeFile { - get { return isExeFile; } - set { isExeFile = value; } + get => isExeFile; + set => isExeFile = value; } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; internal bool Enable { get; set; } @@ -65,9 +57,7 @@ public RVA RVA { /// Constructor /// /// true if it's a 64-bit PE file, false if it's a 32-bit PE file - public ImportDirectory(bool is64bit) { - this.is64bit = is64bit; - } + public ImportDirectory(bool is64bit) => this.is64bit = is64bit; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -95,9 +85,7 @@ public uint GetFileLength() { } /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/MDTable.cs b/src/DotNet/Writer/MDTable.cs index b3874f9a9..a177aa458 100644 --- a/src/DotNet/Writer/MDTable.cs +++ b/src/DotNet/Writer/MDTable.cs @@ -69,49 +69,37 @@ public sealed class MDTable : IMDTable, IEnumerable where T : IRawRow { bool isReadOnly; /// - public Table Table { - get { return table; } - } + public Table Table => table; /// - public bool IsEmpty { - get { return cached.Count == 0; } - } + public bool IsEmpty => cached.Count == 0; /// - public int Rows { - get { return cached.Count; } - } + public int Rows => cached.Count; /// public bool IsSorted { - get { return isSorted; } - set { isSorted = value; } + get => isSorted; + set => isSorted = value; } /// - public bool IsReadOnly { - get { return isReadOnly; } - } + public bool IsReadOnly => isReadOnly; /// public TableInfo TableInfo { - get { return tableInfo; } - set { tableInfo = value; } + get => tableInfo; + set => tableInfo = value; } /// /// Gets the value with rid /// /// The row ID - public T this[uint rid] { - get { return cached[(int)rid - 1]; } - } + public T this[uint rid] => cached[(int)rid - 1]; /// - public IRawRow Get(uint rid) { - return this[rid]; - } + public IRawRow Get(uint rid) => this[rid]; /// /// Constructor @@ -120,14 +108,12 @@ public IRawRow Get(uint rid) { /// Equality comparer public MDTable(Table table, IEqualityComparer equalityComparer) { this.table = table; - this.cachedDict = new Dictionary(equalityComparer); - this.cached = new List(); + cachedDict = new Dictionary(equalityComparer); + cached = new List(); } /// - public void SetReadOnly() { - isReadOnly = true; - } + public void SetReadOnly() => isReadOnly = true; /// /// Adds a row. If the row already exists, returns a rid to the existing one, else @@ -137,9 +123,8 @@ public void SetReadOnly() { /// The RID (row ID) of the row public uint Add(T row) { if (isReadOnly) - throw new ModuleWriterException(string.Format("Trying to modify table {0} after it's been set to read-only", table)); - uint rid; - if (cachedDict.TryGetValue(row, out rid)) + throw new ModuleWriterException($"Trying to modify table {table} after it's been set to read-only"); + if (cachedDict.TryGetValue(row, out uint rid)) return rid; return Create(row); } @@ -151,7 +136,7 @@ public uint Add(T row) { /// The RID (row ID) of the row public uint Create(T row) { if (isReadOnly) - throw new ModuleWriterException(string.Format("Trying to modify table {0} after it's been set to read-only", table)); + throw new ModuleWriterException($"Trying to modify table {table} after it's been set to read-only"); uint rid = (uint)cached.Count + 1; if (!cachedDict.ContainsKey(row)) cachedDict[row] = rid; @@ -165,7 +150,7 @@ public uint Create(T row) { /// public void ReAddRows() { if (isReadOnly) - throw new ModuleWriterException(string.Format("Trying to modify table {0} after it's been set to read-only", table)); + throw new ModuleWriterException($"Trying to modify table {table} after it's been set to read-only"); cachedDict.Clear(); for (int i = 0; i < cached.Count; i++) { uint rid = (uint)i + 1; @@ -180,20 +165,16 @@ public void ReAddRows() { /// public void Reset() { if (isReadOnly) - throw new ModuleWriterException(string.Format("Trying to modify table {0} after it's been set to read-only", table)); + throw new ModuleWriterException($"Trying to modify table {table} after it's been set to read-only"); cachedDict.Clear(); cached.Clear(); } /// - public IEnumerator GetEnumerator() { - return cached.GetEnumerator(); - } + public IEnumerator GetEnumerator() => cached.GetEnumerator(); /// - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return GetEnumerator(); - } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); /// public IEnumerable GetRawRows() { diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index c14ee982b..78853ee75 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -90,7 +90,7 @@ public static void Write(this BinaryWriter writer, MetaData metadata, IMDTable t case Table.CustomDebugInformation: writer.Write(metadata, (MDTable)table); break; default: - Debug.Fail(string.Format("Unknown table: {0}, add a new method overload", table.Table)); + Debug.Fail($"Unknown table: {table.Table}, add a new method overload"); var cols = table.TableInfo.Columns; var stringsHeap = metadata.StringsHeap; foreach (var row in table.GetRawRows()) { diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 1d1ffe538..b5ffbda1a 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -29,56 +29,21 @@ sealed class ManagedExportsWriter { readonly CpuArch cpuArch; uint exportDirOffset; - bool Is64Bit { - get { return machine == Machine.IA64 || machine == Machine.AMD64 || machine == Machine.ARM64; } - } - - FileOffset ExportDirOffset { - get { return sdataChunk.FileOffset + exportDirOffset; } - } - - RVA ExportDirRVA { - get { return sdataChunk.RVA + exportDirOffset; } - } - - uint ExportDirSize { - get { return 0x28; } - } - - internal bool HasExports { - get { return vtables.Count != 0; } - } + bool Is64Bit => machine == Machine.IA64 || machine == Machine.AMD64 || machine == Machine.ARM64; + FileOffset ExportDirOffset => sdataChunk.FileOffset + exportDirOffset; + RVA ExportDirRVA => sdataChunk.RVA + exportDirOffset; + uint ExportDirSize => 0x28; + internal bool HasExports => vtables.Count != 0; sealed class ExportDir : IChunk { readonly ManagedExportsWriter owner; - - public FileOffset FileOffset { - get { return owner.ExportDirOffset; } - } - - public RVA RVA { - get { return owner.ExportDirRVA; } - } - - public ExportDir(ManagedExportsWriter owner) { - this.owner = owner; - } - - void IChunk.SetOffset(FileOffset offset, RVA rva) { - throw new NotSupportedException(); - } - - public uint GetFileLength() { - return owner.ExportDirSize; - } - - public uint GetVirtualSize() { - return GetFileLength(); - } - - void IChunk.WriteTo(BinaryWriter writer) { - throw new NotSupportedException(); - } + public FileOffset FileOffset => owner.ExportDirOffset; + public RVA RVA => owner.ExportDirRVA; + public ExportDir(ManagedExportsWriter owner) => this.owner = owner; + void IChunk.SetOffset(FileOffset offset, RVA rva) => throw new NotSupportedException(); + public uint GetFileLength() => owner.ExportDirSize; + public uint GetVirtualSize() => GetFileLength(); + void IChunk.WriteTo(BinaryWriter writer) => throw new NotSupportedException(); } sealed class VtableFixupsChunk : IChunk { @@ -86,35 +51,16 @@ sealed class VtableFixupsChunk : IChunk { FileOffset offset; RVA rva; internal uint length; - - public FileOffset FileOffset { - get { return offset; } - } - - public RVA RVA { - get { return rva; } - } - - public VtableFixupsChunk(ManagedExportsWriter owner) { - this.owner = owner; - } - + public FileOffset FileOffset => offset; + public RVA RVA => rva; + public VtableFixupsChunk(ManagedExportsWriter owner) => this.owner = owner; public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; } - - public uint GetFileLength() { - return length; - } - - public uint GetVirtualSize() { - return GetFileLength(); - } - - public void WriteTo(BinaryWriter writer) { - owner.WriteVtableFixups(writer); - } + public uint GetFileLength() => length; + public uint GetVirtualSize() => GetFileLength(); + public void WriteTo(BinaryWriter writer) => owner.WriteVtableFixups(writer); } sealed class StubsChunk : IChunk { @@ -122,35 +68,16 @@ sealed class StubsChunk : IChunk { FileOffset offset; RVA rva; internal uint length; - - public FileOffset FileOffset { - get { return offset; } - } - - public RVA RVA { - get { return rva; } - } - - public StubsChunk(ManagedExportsWriter owner) { - this.owner = owner; - } - + public FileOffset FileOffset => offset; + public RVA RVA => rva; + public StubsChunk(ManagedExportsWriter owner) => this.owner = owner; public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; } - - public uint GetFileLength() { - return length; - } - - public uint GetVirtualSize() { - return GetFileLength(); - } - - public void WriteTo(BinaryWriter writer) { - owner.WriteStubs(writer); - } + public uint GetFileLength() => length; + public uint GetVirtualSize() => GetFileLength(); + public void WriteTo(BinaryWriter writer) => owner.WriteStubs(writer); } sealed class SdataChunk : IChunk { @@ -158,35 +85,16 @@ sealed class SdataChunk : IChunk { FileOffset offset; RVA rva; internal uint length; - - public FileOffset FileOffset { - get { return offset; } - } - - public RVA RVA { - get { return rva; } - } - - public SdataChunk(ManagedExportsWriter owner) { - this.owner = owner; - } - + public FileOffset FileOffset => offset; + public RVA RVA => rva; + public SdataChunk(ManagedExportsWriter owner) => this.owner = owner; public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; } - - public uint GetFileLength() { - return length; - } - - public uint GetVirtualSize() { - return GetFileLength(); - } - - public void WriteTo(BinaryWriter writer) { - owner.WriteSdata(writer); - } + public uint GetFileLength() => length; + public uint GetVirtualSize() => GetFileLength(); + public void WriteTo(BinaryWriter writer) => owner.WriteSdata(writer); } internal delegate void LogError(string format, params object[] args); @@ -215,9 +123,7 @@ internal void AddTextChunks(PESection textSection) { textSection.Add(stubsChunk, cpuArch.GetStubAlignment(stubType)); } - internal void AddSdataChunks(PESection sdataSection) { - sdataSection.Add(sdataChunk, DEFAULT_SDATA_ALIGNMENT); - } + internal void AddSdataChunks(PESection sdataSection) => sdataSection.Add(sdataChunk, DEFAULT_SDATA_ALIGNMENT); internal void InitializeChunkProperties() { if (allMethodInfos.Count == 0) @@ -290,8 +196,7 @@ void Initialize(List methods, uint timestamp) { if ((exportInfo.Options & MethodExportInfoOptions.CallMostDerived) != 0) flags |= VTableFlags.CallMostDerived; - List list; - if (!dict.TryGetValue((int)flags, out list)) + if (!dict.TryGetValue((int)flags, out var list)) dict.Add((int)flags, list = new List()); if (list.Count == 0 || list[list.Count - 1].Methods.Count >= ushort.MaxValue) list.Add(new VTableInfo(flags)); @@ -331,11 +236,9 @@ struct NamesBlob { int methodNamesCount; bool methodNamesIsFrozen; - public int MethodNamesCount { - get { return methodNamesCount; } - } + public int MethodNamesCount => methodNamesCount; - struct NameInfo { + readonly struct NameInfo { public readonly uint Offset; public readonly byte[] Bytes; public NameInfo(uint offset, byte[] bytes) { @@ -364,13 +267,11 @@ public uint GetMethodNameOffset(string name, out byte[] bytes) { public uint GetOtherNameOffset(string name) { methodNamesIsFrozen = true; - byte[] bytes; - return GetOffset(name, out bytes); + return GetOffset(name, out var bytes); } uint GetOffset(string name, out byte[] bytes) { - NameInfo nameInfo; - if (nameOffsets.TryGetValue(name, out nameInfo)) { + if (nameOffsets.TryGetValue(name, out var nameInfo)) { bytes = nameInfo.Bytes; return nameInfo.Offset; } @@ -398,9 +299,7 @@ public void Write(BinaryWriter writer) { writer.Write(name); } - public uint[] GetMethodNameOffsets() { - return methodNameOffsets.ToArray(); - } + public uint[] GetMethodNameOffsets() => methodNameOffsets.ToArray(); } struct SdataBytesInfo { diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index ae650354a..57fb6619a 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet.Writer { /// /// Writes field marshal blobs /// - public struct MarshalBlobWriter : IDisposable, IFullNameCreatorHelper { + public readonly struct MarshalBlobWriter : IDisposable, IFullNameCreatorHelper { readonly ModuleDef module; readonly MemoryStream outStream; readonly BinaryWriter writer; @@ -28,8 +28,8 @@ public static byte[] Write(ModuleDef module, MarshalType marshalType, IWriterErr MarshalBlobWriter(ModuleDef module, IWriterError helper) { this.module = module; - this.outStream = new MemoryStream(); - this.writer = new BinaryWriter(outStream); + outStream = new MemoryStream(); + writer = new BinaryWriter(outStream); this.helper = helper; } @@ -114,7 +114,7 @@ byte[] Write(MarshalType marshalType) { bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { if (!canWriteMore) { if (isValid) - helper.Error(string.Format("MarshalType field {0} is valid even though a previous field was invalid", field)); + helper.Error($"MarshalType field {field} is valid even though a previous field was invalid"); return canWriteMore; } @@ -124,22 +124,13 @@ bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { return canWriteMore; } - uint WriteCompressedUInt32(uint value) { - return writer.WriteCompressedUInt32(helper, value); - } + uint WriteCompressedUInt32(uint value) => writer.WriteCompressedUInt32(helper, value); - void Write(UTF8String s) { - writer.Write(helper, s); - } + void Write(UTF8String s) => writer.Write(helper, s); /// - public void Dispose() { - if (outStream != null) - outStream.Dispose(); - } + public void Dispose() => outStream?.Dispose(); - bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) { - return FullNameCreator.MustUseAssemblyName(module, type); - } + bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); } } diff --git a/src/DotNet/Writer/MaxStackCalculator.cs b/src/DotNet/Writer/MaxStackCalculator.cs index 91d0ccafa..60b4c1fab 100644 --- a/src/DotNet/Writer/MaxStackCalculator.cs +++ b/src/DotNet/Writer/MaxStackCalculator.cs @@ -22,8 +22,7 @@ public struct MaxStackCalculator { /// All exception handlers /// Max stack value public static uint GetMaxStack(IList instructions, IList exceptionHandlers) { - uint maxStack; - new MaxStackCalculator(instructions, exceptionHandlers).Calculate(out maxStack); + new MaxStackCalculator(instructions, exceptionHandlers).Calculate(out uint maxStack); return maxStack; } @@ -34,26 +33,23 @@ public static uint GetMaxStack(IList instructions, IListAll exception handlers /// Updated with max stack value /// true if no errors were detected, false otherwise - public static bool GetMaxStack(IList instructions, IList exceptionHandlers, out uint maxStack) { - return new MaxStackCalculator(instructions, exceptionHandlers).Calculate(out maxStack); - } + public static bool GetMaxStack(IList instructions, IList exceptionHandlers, out uint maxStack) => + new MaxStackCalculator(instructions, exceptionHandlers).Calculate(out maxStack); - internal static MaxStackCalculator Create() { - return new MaxStackCalculator(true); - } + internal static MaxStackCalculator Create() => new MaxStackCalculator(true); MaxStackCalculator(bool dummy) { - this.instructions = null; - this.exceptionHandlers = null; - this.stackHeights = new Dictionary(); - this.errors = 0; + instructions = null; + exceptionHandlers = null; + stackHeights = new Dictionary(); + errors = 0; } MaxStackCalculator(IList instructions, IList exceptionHandlers) { this.instructions = instructions; this.exceptionHandlers = exceptionHandlers; - this.stackHeights = new Dictionary(); - this.errors = 0; + stackHeights = new Dictionary(); + errors = 0; } internal void Reset(IList instructions, IList exceptionHandlers) { @@ -94,8 +90,7 @@ internal bool Calculate(out uint maxStack) { errors++; } else { - int pushes, pops; - instr.CalculateStackUsage(out pushes, out pops); + instr.CalculateStackUsage(out int pushes, out int pops); if (pops == -1) stack = 0; else { @@ -125,8 +120,7 @@ internal bool Calculate(out uint maxStack) { case FlowControl.Cond_Branch: if (instr.OpCode.Code == Code.Switch) { - var targets = instr.Operand as IList; - if (targets != null) { + if (instr.Operand is IList targets) { foreach (var target in targets) WriteStack(target, stack); } @@ -154,8 +148,7 @@ int WriteStack(Instruction instr, int stack) { errors++; return stack; } - int stack2; - if (stackHeights.TryGetValue(instr, out stack2)) { + if (stackHeights.TryGetValue(instr, out int stack2)) { if (stack != stack2) errors++; return stack2; diff --git a/src/DotNet/Writer/MetaData.cs b/src/DotNet/Writer/MetaData.cs index 5ece4d273..e59e01b4d 100644 --- a/src/DotNet/Writer/MetaData.cs +++ b/src/DotNet/Writer/MetaData.cs @@ -177,32 +177,32 @@ public sealed class MetaDataOptions { /// Gets/sets the options. This is never null. /// public MetaDataHeaderOptions MetaDataHeaderOptions { - get { return metaDataHeaderOptions ?? (metaDataHeaderOptions = new MetaDataHeaderOptions()); } - set { metaDataHeaderOptions = value; } + get => metaDataHeaderOptions ?? (metaDataHeaderOptions = new MetaDataHeaderOptions()); + set => metaDataHeaderOptions = value; } /// /// Gets/sets the debug (portable PDB) options. This is never null. /// public MetaDataHeaderOptions DebugMetaDataHeaderOptions { - get { return debugMetaDataHeaderOptions ?? (debugMetaDataHeaderOptions = MetaDataHeaderOptions.CreatePortablePdbV1_0()); } - set { debugMetaDataHeaderOptions = value; } + get => debugMetaDataHeaderOptions ?? (debugMetaDataHeaderOptions = MetaDataHeaderOptions.CreatePortablePdbV1_0()); + set => debugMetaDataHeaderOptions = value; } /// /// Gets/sets the options. This is never null. /// public TablesHeapOptions TablesHeapOptions { - get { return tablesHeapOptions ?? (tablesHeapOptions = new TablesHeapOptions()); } - set { tablesHeapOptions = value; } + get => tablesHeapOptions ?? (tablesHeapOptions = new TablesHeapOptions()); + set => tablesHeapOptions = value; } /// /// Gets/sets the debug (portable PDB) options. This is never null. /// public TablesHeapOptions DebugTablesHeapOptions { - get { return tablesHeapOptions ?? (tablesHeapOptions = TablesHeapOptions.CreatePortablePdbV1_0()); } - set { tablesHeapOptions = value; } + get => tablesHeapOptions ?? (tablesHeapOptions = TablesHeapOptions.CreatePortablePdbV1_0()); + set => tablesHeapOptions = value; } /// @@ -213,16 +213,12 @@ public TablesHeapOptions DebugTablesHeapOptions { /// /// Any additional heaps that should be added to the beginning of the heaps list /// - public List OtherHeaps { - get { return otherHeaps ?? (otherHeaps = new List()); } - } + public List OtherHeaps => otherHeaps ?? (otherHeaps = new List()); /// /// Any additional heaps that should be added to end of the heaps list /// - public List OtherHeapsEnd { - get { return otherHeapsEnd ?? (otherHeapsEnd = new List()); } - } + public List OtherHeapsEnd => otherHeapsEnd ?? (otherHeapsEnd = new List()); /// /// Default constructor @@ -234,17 +230,13 @@ public MetaDataOptions() { /// Constructor /// /// Flags - public MetaDataOptions(MetaDataFlags flags) { - this.Flags = flags; - } + public MetaDataOptions(MetaDataFlags flags) => Flags = flags; /// /// Constructor /// /// Meta data header options - public MetaDataOptions(MetaDataHeaderOptions mdhOptions) { - this.metaDataHeaderOptions = mdhOptions; - } + public MetaDataOptions(MetaDataHeaderOptions mdhOptions) => metaDataHeaderOptions = mdhOptions; /// /// Constructor @@ -252,8 +244,8 @@ public MetaDataOptions(MetaDataHeaderOptions mdhOptions) { /// Meta data header options /// Flags public MetaDataOptions(MetaDataHeaderOptions mdhOptions, MetaDataFlags flags) { - this.Flags = flags; - this.metaDataHeaderOptions = mdhOptions; + Flags = flags; + metaDataHeaderOptions = mdhOptions; } } @@ -349,114 +341,90 @@ public abstract class MetaData : IChunk, ISignatureWriterHelper, ITokenCreator, /// Gets/sets the listener /// public IMetaDataListener Listener { - get { return listener ?? (listener = DummyMetaDataListener.Instance); } - set { listener = value; } + get => listener ?? (listener = DummyMetaDataListener.Instance); + set => listener = value; } /// /// Gets/sets the logger /// public ILogger Logger { - get { return logger; } - set { logger = value; } + get => logger; + set => logger = value; } /// /// Gets the module /// - public ModuleDef Module { - get { return module; } - } + public ModuleDef Module => module; /// /// Gets the constants /// - public UniqueChunkList Constants { - get { return constants; } - } + public UniqueChunkList Constants => constants; /// /// Gets the method body chunks /// - public MethodBodyChunks MethodBodyChunks { - get { return methodBodies; } - } + public MethodBodyChunks MethodBodyChunks => methodBodies; /// /// Gets the .NET resources /// - public NetResources NetResources { - get { return netResources; } - } + public NetResources NetResources => netResources; /// /// Gets the MD header /// - public MetaDataHeader MetaDataHeader { - get { return metaDataHeader; } - } + public MetaDataHeader MetaDataHeader => metaDataHeader; /// /// Gets/sets the hot heap (#!) /// HotHeap HotHeap { - get { return hotHeap; } - set { hotHeap = value; } + get => hotHeap; + set => hotHeap = value; } /// /// Gets the tables heap. Access to this heap is not recommended, but is useful if you /// want to add random table entries. /// - public TablesHeap TablesHeap { - get { return tablesHeap; } - } + public TablesHeap TablesHeap => tablesHeap; /// /// Gets the #Strings heap. Access to this heap is not recommended, but is useful if you /// want to add random strings. /// - public StringsHeap StringsHeap { - get { return stringsHeap; } - } + public StringsHeap StringsHeap => stringsHeap; /// /// Gets the #US heap. Access to this heap is not recommended, but is useful if /// you want to add random user strings. /// - public USHeap USHeap { - get { return usHeap; } - } + public USHeap USHeap => usHeap; /// /// Gets the #GUID heap. Access to this heap is not recommended, but is useful if you /// want to add random GUIDs. /// - public GuidHeap GuidHeap { - get { return guidHeap; } - } + public GuidHeap GuidHeap => guidHeap; /// /// Gets the #Blob heap. Access to this heap is not recommended, but is useful if you /// want to add random blobs. /// - public BlobHeap BlobHeap { - get { return blobHeap; } - } + public BlobHeap BlobHeap => blobHeap; /// /// Gets the #Pdb heap. It's only used if it's portable PDB metadata /// - public PdbHeap PdbHeap { - get { return pdbHeap; } - } + public PdbHeap PdbHeap => pdbHeap; /// /// Gets all exported methods /// - public List ExportedMethods { - get { return exportedMethods; } - } + public List ExportedMethods => exportedMethods; /// /// The public key that should be used instead of the one in . @@ -468,9 +436,9 @@ internal sealed class SortedRows where T : class where TRow : class { Dictionary toRid = new Dictionary(); bool isSorted; - public struct Info { - public T data; - public TRow row; + public readonly struct Info { + public readonly T data; + public readonly TRow row; public Info(T data, TRow row) { this.data = data; this.row = row; @@ -479,7 +447,7 @@ public Info(T data, TRow row) { public void Add(T data, TRow row) { if (isSorted) - throw new ModuleWriterException(string.Format("Adding a row after it's been sorted. Table: {0}", row.GetType())); + throw new ModuleWriterException($"Adding a row after it's been sorted. Table: {row.GetType()}"); infos.Add(new Info(data, row)); toRid[data] = (uint)toRid.Count + 1; } @@ -492,19 +460,16 @@ public void Sort(Comparison comparison) { isSorted = true; } - Comparison CreateComparison(Comparison comparison) { - return (a, b) => { + Comparison CreateComparison(Comparison comparison) => + (a, b) => { int c = comparison(a, b); if (c != 0) return c; // Make sure it's a stable sort return toRid[a.data].CompareTo(toRid[b.data]); }; - } - public uint Rid(T data) { - return toRid[data]; - } + public uint Rid(T data) => toRid[data]; public bool TryGetRid(T data, out uint rid) { if (data == null) { @@ -518,9 +483,7 @@ public bool TryGetRid(T data, out uint rid) { internal sealed class Rows where T : class { Dictionary dict = new Dictionary(); - public int Count { - get { return dict.Count; } - } + public int Count => dict.Count; public bool TryGetRid(T value, out uint rid) { if (value == null) { @@ -530,21 +493,10 @@ public bool TryGetRid(T value, out uint rid) { return dict.TryGetValue(value, out rid); } - public bool Exists(T value) { - return dict.ContainsKey(value); - } - - public void Add(T value, uint rid) { - dict.Add(value, rid); - } - - public uint Rid(T value) { - return dict[value]; - } - - public void SetRid(T value, uint rid) { - dict[value] = rid; - } + public bool Exists(T value) => dict.ContainsKey(value); + public void Add(T value, uint rid) => dict.Add(value, rid); + public uint Rid(T value) => dict[value]; + public void SetRid(T value, uint rid) => dict[value] = rid; } /// @@ -566,97 +518,71 @@ public static MetaData Create(ModuleDef module, UniqueChunkList } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the bit /// - public bool PreserveTypeRefRids { - get { return (options.Flags & MetaDataFlags.PreserveTypeRefRids) != 0; } - } + public bool PreserveTypeRefRids => (options.Flags & MetaDataFlags.PreserveTypeRefRids) != 0; /// /// Gets the bit /// - public bool PreserveTypeDefRids { - get { return (options.Flags & MetaDataFlags.PreserveTypeDefRids) != 0; } - } + public bool PreserveTypeDefRids => (options.Flags & MetaDataFlags.PreserveTypeDefRids) != 0; /// /// Gets the bit /// - public bool PreserveFieldRids { - get { return (options.Flags & MetaDataFlags.PreserveFieldRids) != 0; } - } + public bool PreserveFieldRids => (options.Flags & MetaDataFlags.PreserveFieldRids) != 0; /// /// Gets the bit /// - public bool PreserveMethodRids { - get { return (options.Flags & MetaDataFlags.PreserveMethodRids) != 0; } - } + public bool PreserveMethodRids => (options.Flags & MetaDataFlags.PreserveMethodRids) != 0; /// /// Gets the bit /// - public bool PreserveParamRids { - get { return (options.Flags & MetaDataFlags.PreserveParamRids) != 0; } - } + public bool PreserveParamRids => (options.Flags & MetaDataFlags.PreserveParamRids) != 0; /// /// Gets the bit /// - public bool PreserveMemberRefRids { - get { return (options.Flags & MetaDataFlags.PreserveMemberRefRids) != 0; } - } + public bool PreserveMemberRefRids => (options.Flags & MetaDataFlags.PreserveMemberRefRids) != 0; /// /// Gets the bit /// - public bool PreserveStandAloneSigRids { - get { return (options.Flags & MetaDataFlags.PreserveStandAloneSigRids) != 0; } - } + public bool PreserveStandAloneSigRids => (options.Flags & MetaDataFlags.PreserveStandAloneSigRids) != 0; /// /// Gets the bit /// - public bool PreserveEventRids { - get { return (options.Flags & MetaDataFlags.PreserveEventRids) != 0; } - } + public bool PreserveEventRids => (options.Flags & MetaDataFlags.PreserveEventRids) != 0; /// /// Gets the bit /// - public bool PreservePropertyRids { - get { return (options.Flags & MetaDataFlags.PreservePropertyRids) != 0; } - } + public bool PreservePropertyRids => (options.Flags & MetaDataFlags.PreservePropertyRids) != 0; /// /// Gets the bit /// - public bool PreserveTypeSpecRids { - get { return (options.Flags & MetaDataFlags.PreserveTypeSpecRids) != 0; } - } + public bool PreserveTypeSpecRids => (options.Flags & MetaDataFlags.PreserveTypeSpecRids) != 0; /// /// Gets the bit /// - public bool PreserveMethodSpecRids { - get { return (options.Flags & MetaDataFlags.PreserveMethodSpecRids) != 0; } - } + public bool PreserveMethodSpecRids => (options.Flags & MetaDataFlags.PreserveMethodSpecRids) != 0; /// /// Gets/sets the bit /// public bool PreserveStringsOffsets { - get { return (options.Flags & MetaDataFlags.PreserveStringsOffsets) != 0; } + get => (options.Flags & MetaDataFlags.PreserveStringsOffsets) != 0; set { if (value) options.Flags |= MetaDataFlags.PreserveStringsOffsets; @@ -669,7 +595,7 @@ public bool PreserveStringsOffsets { /// Gets/sets the bit /// public bool PreserveUSOffsets { - get { return (options.Flags & MetaDataFlags.PreserveUSOffsets) != 0; } + get => (options.Flags & MetaDataFlags.PreserveUSOffsets) != 0; set { if (value) options.Flags |= MetaDataFlags.PreserveUSOffsets; @@ -682,7 +608,7 @@ public bool PreserveUSOffsets { /// Gets/sets the bit /// public bool PreserveBlobOffsets { - get { return (options.Flags & MetaDataFlags.PreserveBlobOffsets) != 0; } + get => (options.Flags & MetaDataFlags.PreserveBlobOffsets) != 0; set { if (value) options.Flags |= MetaDataFlags.PreserveBlobOffsets; @@ -695,7 +621,7 @@ public bool PreserveBlobOffsets { /// Gets/sets the bit /// public bool PreserveExtraSignatureData { - get { return (options.Flags & MetaDataFlags.PreserveExtraSignatureData) != 0; } + get => (options.Flags & MetaDataFlags.PreserveExtraSignatureData) != 0; set { if (value) options.Flags |= MetaDataFlags.PreserveExtraSignatureData; @@ -708,7 +634,7 @@ public bool PreserveExtraSignatureData { /// Gets/sets the bit /// public bool KeepOldMaxStack { - get { return (options.Flags & MetaDataFlags.KeepOldMaxStack) != 0; } + get => (options.Flags & MetaDataFlags.KeepOldMaxStack) != 0; set { if (value) options.Flags |= MetaDataFlags.KeepOldMaxStack; @@ -721,7 +647,7 @@ public bool KeepOldMaxStack { /// Gets/sets the bit /// public bool AlwaysCreateGuidHeap { - get { return (options.Flags & MetaDataFlags.AlwaysCreateGuidHeap) != 0; } + get => (options.Flags & MetaDataFlags.AlwaysCreateGuidHeap) != 0; set { if (value) options.Flags |= MetaDataFlags.AlwaysCreateGuidHeap; @@ -734,7 +660,7 @@ public bool AlwaysCreateGuidHeap { /// Gets/sets the bit /// public bool AlwaysCreateStringsHeap { - get { return (options.Flags & MetaDataFlags.AlwaysCreateStringsHeap) != 0; } + get => (options.Flags & MetaDataFlags.AlwaysCreateStringsHeap) != 0; set { if (value) options.Flags |= MetaDataFlags.AlwaysCreateStringsHeap; @@ -747,7 +673,7 @@ public bool AlwaysCreateStringsHeap { /// Gets/sets the bit /// public bool AlwaysCreateUSHeap { - get { return (options.Flags & MetaDataFlags.AlwaysCreateUSHeap) != 0; } + get => (options.Flags & MetaDataFlags.AlwaysCreateUSHeap) != 0; set { if (value) options.Flags |= MetaDataFlags.AlwaysCreateUSHeap; @@ -760,7 +686,7 @@ public bool AlwaysCreateUSHeap { /// Gets/sets the bit /// public bool AlwaysCreateBlobHeap { - get { return (options.Flags & MetaDataFlags.AlwaysCreateBlobHeap) != 0; } + get => (options.Flags & MetaDataFlags.AlwaysCreateBlobHeap) != 0; set { if (value) options.Flags |= MetaDataFlags.AlwaysCreateBlobHeap; @@ -773,7 +699,7 @@ public bool AlwaysCreateBlobHeap { /// Gets/sets the bit /// public bool RoslynSortInterfaceImpl { - get { return (options.Flags & MetaDataFlags.RoslynSortInterfaceImpl) != 0; } + get => (options.Flags & MetaDataFlags.RoslynSortInterfaceImpl) != 0; set { if (value) options.Flags |= MetaDataFlags.RoslynSortInterfaceImpl; @@ -799,13 +725,13 @@ internal MetaData(ModuleDef module, UniqueChunkList constants, M this.methodBodies = methodBodies; this.netResources = netResources; this.options = options ?? new MetaDataOptions(); - this.metaDataHeader = new MetaDataHeader(isStandaloneDebugMetadata ? this.options.DebugMetaDataHeaderOptions : this.options.MetaDataHeaderOptions); - this.tablesHeap = new TablesHeap(this, isStandaloneDebugMetadata ? this.options.DebugTablesHeapOptions : this.options.TablesHeapOptions); - this.stringsHeap = new StringsHeap(); - this.usHeap = new USHeap(); - this.guidHeap = new GuidHeap(); - this.blobHeap = new BlobHeap(); - this.pdbHeap = new PdbHeap(); + metaDataHeader = new MetaDataHeader(isStandaloneDebugMetadata ? this.options.DebugMetaDataHeaderOptions : this.options.MetaDataHeaderOptions); + tablesHeap = new TablesHeap(this, isStandaloneDebugMetadata ? this.options.DebugTablesHeapOptions : this.options.TablesHeapOptions); + stringsHeap = new StringsHeap(); + usHeap = new USHeap(); + guidHeap = new GuidHeap(); + blobHeap = new BlobHeap(); + pdbHeap = new PdbHeap(); this.isStandaloneDebugMetadata = isStandaloneDebugMetadata; switch (debugKind) { @@ -819,7 +745,7 @@ internal MetaData(ModuleDef module, UniqueChunkList constants, M break; default: - throw new ArgumentOutOfRangeException("debugKind"); + throw new ArgumentOutOfRangeException(nameof(debugKind)); } } @@ -829,8 +755,7 @@ internal MetaData(ModuleDef module, UniqueChunkList constants, M /// Value /// Its new rid or 0 public uint GetRid(ModuleDef module) { - uint rid; - moduleDefInfos.TryGetRid(module, out rid); + moduleDefInfos.TryGetRid(module, out uint rid); return rid; } @@ -875,8 +800,7 @@ public uint GetRid(ModuleDef module) { /// Value /// Its new rid or 0 public uint GetRid(InterfaceImpl ii) { - uint rid; - interfaceImplInfos.TryGetRid(ii, out rid); + interfaceImplInfos.TryGetRid(ii, out uint rid); return rid; } @@ -893,8 +817,7 @@ public uint GetRid(InterfaceImpl ii) { /// Value /// Its new rid or 0 public uint GetConstantRid(IHasConstant hc) { - uint rid; - hasConstantInfos.TryGetRid(hc, out rid); + hasConstantInfos.TryGetRid(hc, out uint rid); return rid; } @@ -904,8 +827,7 @@ public uint GetConstantRid(IHasConstant hc) { /// Value /// Its new rid or 0 public uint GetCustomAttributeRid(CustomAttribute ca) { - uint rid; - customAttributeInfos.TryGetRid(ca, out rid); + customAttributeInfos.TryGetRid(ca, out uint rid); return rid; } @@ -915,8 +837,7 @@ public uint GetCustomAttributeRid(CustomAttribute ca) { /// Value /// Its new rid or 0 public uint GetFieldMarshalRid(IHasFieldMarshal hfm) { - uint rid; - fieldMarshalInfos.TryGetRid(hfm, out rid); + fieldMarshalInfos.TryGetRid(hfm, out uint rid); return rid; } @@ -926,8 +847,7 @@ public uint GetFieldMarshalRid(IHasFieldMarshal hfm) { /// Value /// Its new rid or 0 public uint GetRid(DeclSecurity ds) { - uint rid; - declSecurityInfos.TryGetRid(ds, out rid); + declSecurityInfos.TryGetRid(ds, out uint rid); return rid; } @@ -937,8 +857,7 @@ public uint GetRid(DeclSecurity ds) { /// Value /// Its new rid or 0 public uint GetClassLayoutRid(TypeDef td) { - uint rid; - classLayoutInfos.TryGetRid(td, out rid); + classLayoutInfos.TryGetRid(td, out uint rid); return rid; } @@ -948,8 +867,7 @@ public uint GetClassLayoutRid(TypeDef td) { /// Value /// Its new rid or 0 public uint GetFieldLayoutRid(FieldDef fd) { - uint rid; - fieldLayoutInfos.TryGetRid(fd, out rid); + fieldLayoutInfos.TryGetRid(fd, out uint rid); return rid; } @@ -966,8 +884,7 @@ public uint GetFieldLayoutRid(FieldDef fd) { /// Value /// Its new rid or 0 public uint GetEventMapRid(TypeDef td) { - uint rid; - eventMapInfos.TryGetRid(td, out rid); + eventMapInfos.TryGetRid(td, out uint rid); return rid; } @@ -984,8 +901,7 @@ public uint GetEventMapRid(TypeDef td) { /// Value /// Its new rid or 0 public uint GetPropertyMapRid(TypeDef td) { - uint rid; - propertyMapInfos.TryGetRid(td, out rid); + propertyMapInfos.TryGetRid(td, out uint rid); return rid; } @@ -1002,8 +918,7 @@ public uint GetPropertyMapRid(TypeDef td) { /// Value /// Its new rid or 0 public uint GetMethodSemanticsRid(MethodDef md) { - uint rid; - methodSemanticsInfos.TryGetRid(md, out rid); + methodSemanticsInfos.TryGetRid(md, out uint rid); return rid; } @@ -1013,8 +928,7 @@ public uint GetMethodSemanticsRid(MethodDef md) { /// Value /// Its new rid or 0 public uint GetRid(ModuleRef mr) { - uint rid; - moduleRefInfos.TryGetRid(mr, out rid); + moduleRefInfos.TryGetRid(mr, out uint rid); return rid; } @@ -1031,8 +945,7 @@ public uint GetRid(ModuleRef mr) { /// Value /// Its new rid or 0 public uint GetImplMapRid(IMemberForwarded mf) { - uint rid; - implMapInfos.TryGetRid(mf, out rid); + implMapInfos.TryGetRid(mf, out uint rid); return rid; } @@ -1042,8 +955,7 @@ public uint GetImplMapRid(IMemberForwarded mf) { /// Value /// Its new rid or 0 public uint GetFieldRVARid(FieldDef fd) { - uint rid; - fieldRVAInfos.TryGetRid(fd, out rid); + fieldRVAInfos.TryGetRid(fd, out uint rid); return rid; } @@ -1053,8 +965,7 @@ public uint GetFieldRVARid(FieldDef fd) { /// Value /// Its new rid or 0 public uint GetRid(AssemblyDef asm) { - uint rid; - assemblyInfos.TryGetRid(asm, out rid); + assemblyInfos.TryGetRid(asm, out uint rid); return rid; } @@ -1064,8 +975,7 @@ public uint GetRid(AssemblyDef asm) { /// Value /// Its new rid or 0 public uint GetRid(AssemblyRef asmRef) { - uint rid; - assemblyRefInfos.TryGetRid(asmRef, out rid); + assemblyRefInfos.TryGetRid(asmRef, out uint rid); return rid; } @@ -1075,8 +985,7 @@ public uint GetRid(AssemblyRef asmRef) { /// Value /// Its new rid or 0 public uint GetRid(FileDef fd) { - uint rid; - fileDefInfos.TryGetRid(fd, out rid); + fileDefInfos.TryGetRid(fd, out uint rid); return rid; } @@ -1086,8 +995,7 @@ public uint GetRid(FileDef fd) { /// Value /// Its new rid or 0 public uint GetRid(ExportedType et) { - uint rid; - exportedTypeInfos.TryGetRid(et, out rid); + exportedTypeInfos.TryGetRid(et, out uint rid); return rid; } @@ -1097,8 +1005,7 @@ public uint GetRid(ExportedType et) { /// Value /// Its new rid or 0 public uint GetManifestResourceRid(Resource resource) { - uint rid; - manifestResourceInfos.TryGetRid(resource, out rid); + manifestResourceInfos.TryGetRid(resource, out uint rid); return rid; } @@ -1108,8 +1015,7 @@ public uint GetManifestResourceRid(Resource resource) { /// Value /// Its new rid or 0 public uint GetNestedClassRid(TypeDef td) { - uint rid; - nestedClassInfos.TryGetRid(td, out rid); + nestedClassInfos.TryGetRid(td, out uint rid); return rid; } @@ -1119,8 +1025,7 @@ public uint GetNestedClassRid(TypeDef td) { /// Value /// Its new rid or 0 public uint GetRid(GenericParam gp) { - uint rid; - genericParamInfos.TryGetRid(gp, out rid); + genericParamInfos.TryGetRid(gp, out uint rid); return rid; } @@ -1137,8 +1042,7 @@ public uint GetRid(GenericParam gp) { /// Value /// Its new rid or 0 public uint GetRid(GenericParamConstraint gpc) { - uint rid; - genericParamConstraintInfos.TryGetRid(gpc, out rid); + genericParamConstraintInfos.TryGetRid(gpc, out uint rid); return rid; } @@ -1150,8 +1054,7 @@ public uint GetRid(GenericParamConstraint gpc) { public uint GetRid(PdbDocument doc) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.pdbDocumentInfos.TryGetRid(doc, out rid); + debugMetaData.pdbDocumentInfos.TryGetRid(doc, out uint rid); return rid; } @@ -1163,8 +1066,7 @@ public uint GetRid(PdbDocument doc) { public uint GetRid(PdbScope scope) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.localScopeInfos.TryGetRid(scope, out rid); + debugMetaData.localScopeInfos.TryGetRid(scope, out uint rid); return rid; } @@ -1176,8 +1078,7 @@ public uint GetRid(PdbScope scope) { public uint GetRid(PdbLocal local) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.localVariableInfos.TryGetRid(local, out rid); + debugMetaData.localVariableInfos.TryGetRid(local, out uint rid); return rid; } @@ -1189,8 +1090,8 @@ public uint GetRid(PdbLocal local) { public uint GetRid(PdbConstant constant) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.localConstantInfos.TryGetRid(constant, out rid); + + debugMetaData.localConstantInfos.TryGetRid(constant, out uint rid); return rid; } @@ -1202,8 +1103,7 @@ public uint GetRid(PdbConstant constant) { public uint GetRid(PdbImportScope importScope) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.importScopeInfos.TryGetRid(importScope, out rid); + debugMetaData.importScopeInfos.TryGetRid(importScope, out uint rid); return rid; } @@ -1215,8 +1115,7 @@ public uint GetRid(PdbImportScope importScope) { public uint GetStateMachineMethodRid(PdbAsyncMethodCustomDebugInfo asyncMethod) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.stateMachineMethodInfos.TryGetRid(asyncMethod, out rid); + debugMetaData.stateMachineMethodInfos.TryGetRid(asyncMethod, out uint rid); return rid; } @@ -1228,8 +1127,7 @@ public uint GetStateMachineMethodRid(PdbAsyncMethodCustomDebugInfo asyncMethod) public uint GetStateMachineMethodRid(PdbIteratorMethodCustomDebugInfo iteratorMethod) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.stateMachineMethodInfos.TryGetRid(iteratorMethod, out rid); + debugMetaData.stateMachineMethodInfos.TryGetRid(iteratorMethod, out uint rid); return rid; } @@ -1241,8 +1139,7 @@ public uint GetStateMachineMethodRid(PdbIteratorMethodCustomDebugInfo iteratorMe public uint GetCustomDebugInfoRid(PdbCustomDebugInfo cdi) { if (debugMetaData == null) return 0; - uint rid; - debugMetaData.customDebugInfos.TryGetRid(cdi, out rid); + debugMetaData.customDebugInfos.TryGetRid(cdi, out uint rid); return rid; } @@ -1255,8 +1152,7 @@ public uint GetCustomDebugInfoRid(PdbCustomDebugInfo cdi) { public MethodBody GetMethodBody(MethodDef md) { if (md == null) return null; - MethodBody mb; - methodToBody.TryGetValue(md, out mb); + methodToBody.TryGetValue(md, out var mb); return mb; } @@ -1265,10 +1161,7 @@ public MethodBody GetMethodBody(MethodDef md) { /// /// Method /// Locals sig token or 0 - public uint GetLocalVarSigToken(MethodDef md) { - var mb = GetMethodBody(md); - return mb == null ? 0 : mb.LocalVarSigTok; - } + public uint GetLocalVarSigToken(MethodDef md) => GetMethodBody(md)?.LocalVarSigTok ?? 0; /// /// Gets the where the resource data will be stored @@ -1279,8 +1172,7 @@ public uint GetLocalVarSigToken(MethodDef md) { public ByteArrayChunk GetChunk(EmbeddedResource er) { if (er == null) return null; - ByteArrayChunk chunk; - embeddedResourceToByteArray.TryGetValue(er, out chunk); + embeddedResourceToByteArray.TryGetValue(er, out var chunk); return chunk; } @@ -1293,32 +1185,25 @@ public ByteArrayChunk GetChunk(EmbeddedResource er) { public ByteArrayChunk GetInitialValueChunk(FieldDef fd) { if (fd == null) return null; - ByteArrayChunk chunk; - fieldToInitialValue.TryGetValue(fd, out chunk); + fieldToInitialValue.TryGetValue(fd, out var chunk); return chunk; } - ILogger GetLogger() { - return logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; - } + ILogger GetLogger() => logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; /// /// Called when an error is detected /// /// Error message /// Optional message arguments - protected void Error(string message, params object[] args) { - GetLogger().Log(this, LoggerEvent.Error, message, args); - } + protected void Error(string message, params object[] args) => GetLogger().Log(this, LoggerEvent.Error, message, args); /// /// Called to warn of something /// /// Warning message /// Optional message arguments - protected void Warning(string message, params object[] args) { - GetLogger().Log(this, LoggerEvent.Warning, message, args); - } + protected void Warning(string message, params object[] args) => GetLogger().Log(this, LoggerEvent.Warning, message, args); /// /// Creates the .NET metadata tables @@ -1329,8 +1214,7 @@ public void CreateTables() { if (module.Types.Count == 0 || module.Types[0] == null) throw new ModuleWriterException("Missing global type"); - var moduleDefMD = module as ModuleDefMD; - if (moduleDefMD != null) { + if (module is ModuleDefMD moduleDefMD) { if (PreserveStringsOffsets) stringsHeap.Populate(moduleDefMD.StringsStream); if (PreserveUSOffsets) @@ -1633,8 +1517,7 @@ void AddExportedTypes() { /// a , it will have already been added. /// void InitializeEntryPoint() { - var epFile = module.ManagedEntryPoint as FileDef; - if (epFile != null) + if (module.ManagedEntryPoint is FileDef epFile) AddFile(epFile); } @@ -1934,20 +1817,16 @@ protected static bool IsEmpty(IList list) where T : class { /// public MDToken GetToken(object o) { - var tp = o as IMDTokenProvider; - if (tp != null) + if (o is IMDTokenProvider tp) return new MDToken(tp.MDToken.Table, AddMDTokenProvider(tp)); - var s = o as string; - if (s != null) + if (o is string s) return new MDToken((Table)0x70, usHeap.Add(s)); - var methodSig = o as MethodSig; - if (methodSig != null) + if (o is MethodSig methodSig) return new MDToken(Table.StandAloneSig, AddStandAloneSig(methodSig, methodSig.OriginalToken)); - var fieldSig = o as FieldSig; - if (fieldSig != null) + if (o is FieldSig fieldSig) return new MDToken(Table.StandAloneSig, AddStandAloneSig(fieldSig, 0)); if (o == null) @@ -2121,8 +2000,7 @@ protected uint AddTypeDefOrRef(ITypeDefOrRef tdr) { } var token = new MDToken(tdr.MDToken.Table, AddMDTokenProvider(tdr)); - uint encodedToken; - if (!CodedToken.TypeDefOrRef.Encode(token, out encodedToken)) { + if (!CodedToken.TypeDefOrRef.Encode(token, out uint encodedToken)) { Error("Can't encode TypeDefOrRef token {0:X8}", token.Raw); encodedToken = 0; } @@ -2141,8 +2019,7 @@ protected uint AddResolutionScope(IResolutionScope rs) { } var token = new MDToken(rs.MDToken.Table, AddMDTokenProvider(rs)); - uint encodedToken; - if (!CodedToken.ResolutionScope.Encode(token, out encodedToken)) { + if (!CodedToken.ResolutionScope.Encode(token, out uint encodedToken)) { Error("Can't encode ResolutionScope token {0:X8}", token.Raw); encodedToken = 0; } @@ -2161,8 +2038,7 @@ protected uint AddMethodDefOrRef(IMethodDefOrRef mdr) { } var token = new MDToken(mdr.MDToken.Table, AddMDTokenProvider(mdr)); - uint encodedToken; - if (!CodedToken.MethodDefOrRef.Encode(token, out encodedToken)) { + if (!CodedToken.MethodDefOrRef.Encode(token, out uint encodedToken)) { Error("Can't encode MethodDefOrRef token {0:X8}", token.Raw); encodedToken = 0; } @@ -2181,8 +2057,7 @@ protected uint AddMemberRefParent(IMemberRefParent parent) { } var token = new MDToken(parent.MDToken.Table, AddMDTokenProvider(parent)); - uint encodedToken; - if (!CodedToken.MemberRefParent.Encode(token, out encodedToken)) { + if (!CodedToken.MemberRefParent.Encode(token, out uint encodedToken)) { Error("Can't encode MemberRefParent token {0:X8}", token.Raw); encodedToken = 0; } @@ -2201,8 +2076,7 @@ protected uint AddImplementation(IImplementation impl) { } var token = new MDToken(impl.MDToken.Table, AddMDTokenProvider(impl)); - uint encodedToken; - if (!CodedToken.Implementation.Encode(token, out encodedToken)) { + if (!CodedToken.Implementation.Encode(token, out uint encodedToken)) { Error("Can't encode Implementation token {0:X8}", token.Raw); encodedToken = 0; } @@ -2221,8 +2095,7 @@ protected uint AddCustomAttributeType(ICustomAttributeType cat) { } var token = new MDToken(cat.MDToken.Table, AddMDTokenProvider(cat)); - uint encodedToken; - if (!CodedToken.CustomAttributeType.Encode(token, out encodedToken)) { + if (!CodedToken.CustomAttributeType.Encode(token, out uint encodedToken)) { Error("Can't encode CustomAttributeType token {0:X8}", token.Raw); encodedToken = 0; } @@ -2257,8 +2130,7 @@ protected uint AddModule(ModuleDef module) { } if (this.module != module) Error("Module {0} must be referenced with a ModuleRef, not a ModuleDef", module); - uint rid; - if (moduleDefInfos.TryGetRid(module, out rid)) + if (moduleDefInfos.TryGetRid(module, out uint rid)) return rid; var row = new RawModuleRow(module.Generation, stringsHeap.Add(module.Name), @@ -2282,8 +2154,7 @@ protected uint AddModuleRef(ModuleRef modRef) { Error("ModuleRef is null"); return 0; } - uint rid; - if (moduleRefInfos.TryGetRid(modRef, out rid)) + if (moduleRefInfos.TryGetRid(modRef, out uint rid)) return rid; var row = new RawModuleRefRow(stringsHeap.Add(modRef.Name)); rid = tablesHeap.ModuleRefTable.Add(row); @@ -2303,8 +2174,7 @@ protected uint AddAssemblyRef(AssemblyRef asmRef) { Error("AssemblyRef is null"); return 0; } - uint rid; - if (assemblyRefInfos.TryGetRid(asmRef, out rid)) + if (assemblyRefInfos.TryGetRid(asmRef, out uint rid)) return rid; var version = Utils.CreateVersionWithNoUndefinedValues(asmRef.Version); var row = new RawAssemblyRefRow((ushort)version.Major, @@ -2334,8 +2204,7 @@ protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { Error("Assembly is null"); return 0; } - uint rid; - if (assemblyInfos.TryGetRid(asm, out rid)) + if (assemblyInfos.TryGetRid(asm, out uint rid)) return rid; var asmAttrs = asm.Attributes; @@ -2384,8 +2253,7 @@ protected void AddGenericParam(MDToken owner, GenericParam gp) { Error("GenericParam is null"); return; } - uint encodedOwner; - if (!CodedToken.TypeOrMethodDef.Encode(owner, out encodedOwner)) { + if (!CodedToken.TypeOrMethodDef.Encode(owner, out uint encodedOwner)) { Error("Can't encode TypeOrMethodDef token {0:X8}", owner.Raw); encodedOwner = 0; } @@ -2470,8 +2338,7 @@ protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { if (hfm == null || hfm.MarshalType == null) return; var fieldMarshal = hfm.MarshalType; - uint encodedParent; - if (!CodedToken.HasFieldMarshal.Encode(parent, out encodedParent)) { + if (!CodedToken.HasFieldMarshal.Encode(parent, out uint encodedParent)) { Error("Can't encode HasFieldMarshal token {0:X8}", parent.Raw); encodedParent = 0; } @@ -2523,8 +2390,7 @@ protected void AddImplMap(MDToken parent, IMemberForwarded mf) { if (mf == null || mf.ImplMap == null) return; var implMap = mf.ImplMap; - uint encodedParent; - if (!CodedToken.MemberForwarded.Encode(parent, out encodedParent)) { + if (!CodedToken.MemberForwarded.Encode(parent, out uint encodedParent)) { Error("Can't encode MemberForwarded token {0:X8}", parent.Raw); encodedParent = 0; } @@ -2544,8 +2410,7 @@ protected void AddConstant(MDToken parent, IHasConstant hc) { if (hc == null || hc.Constant == null) return; var constant = hc.Constant; - uint encodedParent; - if (!CodedToken.HasConstant.Encode(parent, out encodedParent)) { + if (!CodedToken.HasConstant.Encode(parent, out uint encodedParent)) { Error("Can't encode HasConstant token {0:X8}", parent.Raw); encodedParent = 0; } @@ -2638,8 +2503,7 @@ void VerifyConstantType(ElementType realType, ElementType expectedType) { protected void AddDeclSecurities(MDToken parent, IList declSecurities) { if (declSecurities == null) return; - uint encodedParent; - if (!CodedToken.HasDeclSecurity.Encode(parent, out encodedParent)) { + if (!CodedToken.HasDeclSecurity.Encode(parent, out uint encodedParent)) { Error("Can't encode HasDeclSecurity token {0:X8}", parent.Raw); encodedParent = 0; } @@ -2705,8 +2569,7 @@ void AddMethodSemantics(MDToken owner, MethodDef method, MethodSemanticsAttribut uint methodRid = GetRid(method); if (methodRid == 0) return; - uint encodedOwner; - if (!CodedToken.HasSemantic.Encode(owner, out encodedOwner)) { + if (!CodedToken.HasSemantic.Encode(owner, out uint encodedOwner)) { Error("Can't encode HasSemantic token {0:X8}", owner.Raw); encodedOwner = 0; } @@ -2751,20 +2614,17 @@ void AddResources(IList resources) { } void AddResource(Resource resource) { - var er = resource as EmbeddedResource; - if (er != null) { + if (resource is EmbeddedResource er) { AddEmbeddedResource(er); return; } - var alr = resource as AssemblyLinkedResource; - if (alr != null) { + if (resource is AssemblyLinkedResource alr) { AddAssemblyLinkedResource(alr); return; } - var lr = resource as LinkedResource; - if (lr != null) { + if (resource is LinkedResource lr) { AddLinkedResource(lr); return; } @@ -2781,8 +2641,7 @@ uint AddEmbeddedResource(EmbeddedResource er) { Error("EmbeddedResource is null"); return 0; } - uint rid; - if (manifestResourceInfos.TryGetRid(er, out rid)) + if (manifestResourceInfos.TryGetRid(er, out uint rid)) return rid; var row = new RawManifestResourceRow(netResources.NextOffset, (uint)er.Attributes, @@ -2801,8 +2660,7 @@ uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { Error("AssemblyLinkedResource is null"); return 0; } - uint rid; - if (manifestResourceInfos.TryGetRid(alr, out rid)) + if (manifestResourceInfos.TryGetRid(alr, out uint rid)) return rid; var row = new RawManifestResourceRow(0, (uint)alr.Attributes, @@ -2820,8 +2678,7 @@ uint AddLinkedResource(LinkedResource lr) { Error("LinkedResource is null"); return 0; } - uint rid; - if (manifestResourceInfos.TryGetRid(lr, out rid)) + if (manifestResourceInfos.TryGetRid(lr, out uint rid)) return rid; var row = new RawManifestResourceRow(0, (uint)lr.Attributes, @@ -2844,8 +2701,7 @@ protected uint AddFile(FileDef file) { Error("FileDef is null"); return 0; } - uint rid; - if (fileDefInfos.TryGetRid(file, out rid)) + if (fileDefInfos.TryGetRid(file, out uint rid)) return rid; var row = new RawFileRow((uint)file.Flags, stringsHeap.Add(file.Name), @@ -2867,8 +2723,7 @@ protected uint AddExportedType(ExportedType et) { Error("ExportedType is null"); return 0; } - uint rid; - if (exportedTypeInfos.TryGetRid(et, out rid)) + if (exportedTypeInfos.TryGetRid(et, out uint rid)) return rid; exportedTypeInfos.Add(et, 0); // Prevent inf recursion var row = new RawExportedTypeRow((uint)et.Attributes, @@ -2937,9 +2792,7 @@ void AppendExtraData(ref byte[] blob, byte[] extraData) { /// Owner table /// New owner rid /// Onwer - protected void AddCustomAttributes(Table table, uint rid, IHasCustomAttribute hca) { - AddCustomAttributes(table, rid, hca.CustomAttributes); - } + protected void AddCustomAttributes(Table table, uint rid, IHasCustomAttribute hca) => AddCustomAttributes(table, rid, hca.CustomAttributes); void AddCustomAttributes(Table table, uint rid, CustomAttributeCollection caList) { var token = new MDToken(table, rid); @@ -2952,8 +2805,7 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { Error("Custom attribute is null"); return; } - uint encodedToken; - if (!CodedToken.HasCustomAttribute.Encode(token, out encodedToken)) { + if (!CodedToken.HasCustomAttribute.Encode(token, out uint encodedToken)) { Error("Can't encode HasCustomAttribute token {0:X8}", token.Raw); encodedToken = 0; } @@ -2983,9 +2835,7 @@ void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken if (body == null) return; - bool hasNoSeqPoints; - PdbDocument singleDoc, firstDoc; - GetSingleDocument(body, out singleDoc, out firstDoc, out hasNoSeqPoints); + GetSingleDocument(body, out var singleDoc, out var firstDoc, out bool hasNoSeqPoints); if (hasNoSeqPoints) return; @@ -3070,8 +2920,7 @@ void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken uint VerifyGetRid(PdbDocument doc) { Debug.Assert(debugMetaData != null); - uint rid; - if (!debugMetaData.pdbDocumentInfos.TryGetRid(doc, out rid)) { + if (!debugMetaData.pdbDocumentInfos.TryGetRid(doc, out uint rid)) { Error("PDB document has been removed"); return 0; } @@ -3139,8 +2988,7 @@ void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodConte Debug.Assert(cdis.Count != 0); var token = new MDToken(table, rid); - uint encodedToken; - if (!CodedToken.HasCustomDebugInformation.Encode(token, out encodedToken)) { + if (!CodedToken.HasCustomDebugInformation.Encode(token, out uint encodedToken)) { Error("Couldn't encode HasCustomDebugInformation token {0:X8}", token.Raw); return; } @@ -3244,8 +3092,7 @@ uint AddPdbDocument(PdbDocument doc) { Error("PdbDocument is null"); return 0; } - uint rid; - if (debugMetaData.pdbDocumentInfos.TryGetRid(doc, out rid)) + if (debugMetaData.pdbDocumentInfos.TryGetRid(doc, out uint rid)) return rid; var row = new RawDocumentRow(GetDocumentNameBlobOffset(doc.Url), debugMetaData.guidHeap.Add(doc.CheckSumAlgorithmId), @@ -3291,8 +3138,7 @@ uint AddImportScope(PdbImportScope scope) { Debug.Assert(debugMetaData != null); if (scope == null) return 0; - uint rid; - if (debugMetaData.importScopeInfos.TryGetRid(scope, out rid)) { + if (debugMetaData.importScopeInfos.TryGetRid(scope, out uint rid)) { if (rid == 0) Error("PdbImportScope has an infinite Parent loop"); return rid; @@ -3366,8 +3212,7 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, byte[] pdbId for (int i = 0; i < pdbId.Length; i++) pdbHeap.PdbId[i] = pdbId[i]; - ulong systemTablesMask; - tablesHeap.GetSystemTableRows(out systemTablesMask, pdbHeap.TypeSystemTableRows); + tablesHeap.GetSystemTableRows(out ulong systemTablesMask, pdbHeap.TypeSystemTableRows); debugMetaData.tablesHeap.SetSystemTableRows(pdbHeap.TypeSystemTableRows); if (!debugMetaData.methodDebugInformationInfosUsed) debugMetaData.tablesHeap.MethodDebugInformationTable.Reset(); @@ -3379,19 +3224,13 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, byte[] pdbId } /// - uint ISignatureWriterHelper.ToEncodedToken(ITypeDefOrRef typeDefOrRef) { - return AddTypeDefOrRef(typeDefOrRef); - } + uint ISignatureWriterHelper.ToEncodedToken(ITypeDefOrRef typeDefOrRef) => AddTypeDefOrRef(typeDefOrRef); /// - void IWriterError.Error(string message) { - Error(message); - } + void IWriterError.Error(string message) => Error(message); /// - bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) { - return FullNameCreator.MustUseAssemblyName(module, type); - } + bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); /// /// Called before any other methods @@ -3555,14 +3394,10 @@ IList GetHeaps() { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/MetaDataHeader.cs b/src/DotNet/Writer/MetaDataHeader.cs index 6c7c0ee7a..a368def51 100644 --- a/src/DotNet/Writer/MetaDataHeader.cs +++ b/src/DotNet/Writer/MetaDataHeader.cs @@ -62,8 +62,8 @@ public sealed class MetaDataHeaderOptions { /// Creates portable PDB v1.0 options /// /// - public static MetaDataHeaderOptions CreatePortablePdbV1_0() { - return new MetaDataHeaderOptions() { + public static MetaDataHeaderOptions CreatePortablePdbV1_0() => + new MetaDataHeaderOptions() { Signature = DEFAULT_SIGNATURE, MajorVersion = 1, MinorVersion = 1, @@ -72,7 +72,6 @@ public static MetaDataHeaderOptions CreatePortablePdbV1_0() { StorageFlags = 0, Reserved2 = 0, }; - } } /// @@ -86,21 +85,17 @@ public sealed class MetaDataHeader : IChunk { RVA rva; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets/sets the heaps /// public IList Heaps { - get { return heaps; } - set { heaps = value; } + get => heaps; + set => heaps = value; } /// @@ -114,9 +109,7 @@ public MetaDataHeader() /// Constructor /// /// Options - public MetaDataHeader(MetaDataHeaderOptions options) { - this.options = options ?? new MetaDataHeaderOptions(); - } + public MetaDataHeader(MetaDataHeaderOptions options) => this.options = options ?? new MetaDataHeaderOptions(); /// public void SetOffset(FileOffset offset, RVA rva) { @@ -135,14 +128,10 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { @@ -162,17 +151,12 @@ public void WriteTo(BinaryWriter writer) { writer.Write(heap.GetFileLength()); writer.Write(s = GetAsciizName(heap.Name)); if (s.Length > 32) - throw new ModuleWriterException(string.Format("Heap name '{0}' is > 32 bytes", heap.Name)); + throw new ModuleWriterException($"Heap name '{heap.Name}' is > 32 bytes"); writer.WriteZeros(Utils.AlignUp(s.Length, 4) - s.Length); } } - byte[] GetVersionString() { - return Encoding.UTF8.GetBytes((options.VersionString ?? MetaDataHeaderOptions.DEFAULT_VERSION_STRING) + "\0"); - } - - byte[] GetAsciizName(string s) { - return Encoding.ASCII.GetBytes(s + "\0"); - } + byte[] GetVersionString() => Encoding.UTF8.GetBytes((options.VersionString ?? MetaDataHeaderOptions.DEFAULT_VERSION_STRING) + "\0"); + byte[] GetAsciizName(string s) => Encoding.ASCII.GetBytes(s + "\0"); } } diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 8c8da069e..8b2b08db3 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -20,56 +20,40 @@ public sealed class MethodBody : IChunk { uint localVarSigTok; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the code /// - public byte[] Code { - get { return code; } - } + public byte[] Code => code; /// /// Gets the extra sections (exception handlers) or null /// - public byte[] ExtraSections { - get { return extraSections; } - } + public byte[] ExtraSections => extraSections; /// /// Gets the token of the locals /// - public uint LocalVarSigTok { - get { return localVarSigTok; } - } + public uint LocalVarSigTok => localVarSigTok; /// /// true if it's a fat body /// - public bool IsFat { - get { return !isTiny; } - } + public bool IsFat => !isTiny; /// /// true if it's a tiny body /// - public bool IsTiny { - get { return isTiny; } - } + public bool IsTiny => isTiny; /// /// true if there's an extra section /// - public bool HasExtraSections { - get { return extraSections != null && extraSections.Length > 0; } - } + public bool HasExtraSections => extraSections != null && extraSections.Length > 0; /// /// Constructor @@ -95,7 +79,7 @@ public MethodBody(byte[] code, byte[] extraSections) /// Extra sections or null /// Token of locals public MethodBody(byte[] code, byte[] extraSections, uint localVarSigTok) { - this.isTiny = (code[0] & 3) == 2; + isTiny = (code[0] & 3) == 2; this.code = code; this.extraSections = extraSections; this.localVarSigTok = localVarSigTok; @@ -119,7 +103,7 @@ public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; if (HasExtraSections) { - RVA rva2 = rva + (uint)code.Length; + var rva2 = rva + (uint)code.Length; rva2 = rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT); rva2 += (uint)extraSections.Length; length = (uint)rva2 - (uint)rva; @@ -129,29 +113,23 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { writer.Write(code); if (HasExtraSections) { - RVA rva2 = rva + (uint)code.Length; + var rva2 = rva + (uint)code.Length; writer.WriteZeros((int)rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT) - (int)rva2); writer.Write(extraSections); } } /// - public override int GetHashCode() { - return Utils.GetHashCode(code) + Utils.GetHashCode(extraSections); - } + public override int GetHashCode() => Utils.GetHashCode(code) + Utils.GetHashCode(extraSections); /// public override bool Equals(object obj) { diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index 41ab6149d..df273590c 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -25,21 +25,15 @@ public sealed class MethodBodyChunks : IChunk { uint savedBytes; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the number of bytes saved by re-using method bodies /// - public uint SavedBytes { - get { return savedBytes; } - } + public uint SavedBytes => savedBytes; /// /// Constructor @@ -47,7 +41,7 @@ public uint SavedBytes { /// true if bodies can be shared public MethodBodyChunks(bool shareBodies) { this.shareBodies = shareBodies; - this.alignFatBodies = true; + alignFatBodies = true; if (shareBodies) { tinyMethodsDict = new Dictionary(); fatMethodsDict = new Dictionary(); @@ -66,8 +60,7 @@ public MethodBody Add(MethodBody methodBody) { throw new InvalidOperationException("SetOffset() has already been called"); if (shareBodies) { var dict = methodBody.IsFat ? fatMethodsDict : tinyMethodsDict; - MethodBody cached; - if (dict.TryGetValue(methodBody, out cached)) { + if (dict.TryGetValue(methodBody, out var cached)) { savedBytes += (uint)methodBody.GetSizeOfMethodBody(); return cached; } @@ -111,14 +104,10 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 77d6f36ff..abe48e35e 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -46,24 +46,18 @@ public sealed class MethodBodyWriter : MethodBodyWriterBase { /// The size of this array is not necessarily a multiple of 4, even if there are exception /// handlers present. See also /// - public byte[] Code { - get { return code; } - } + public byte[] Code => code; /// /// Gets the extra sections (exception handlers) as a byte array or null if there /// are no exception handlers. This is valid only after calling /// - public byte[] ExtraSections { - get { return extraSections; } - } + public byte[] ExtraSections => extraSections; /// /// Gets the token of the locals /// - public uint LocalVarSigTok { - get { return localVarSigTok; } - } + public uint LocalVarSigTok => localVarSigTok; /// /// Constructor @@ -88,9 +82,7 @@ public MethodBodyWriter(ITokenCreator helper, CilBody cilBody, bool keepMaxStack this.keepMaxStack = keepMaxStack; } - internal MethodBodyWriter(ITokenCreator helper) { - this.helper = helper; - } + internal MethodBodyWriter(ITokenCreator helper) => this.helper = helper; internal void Reset(CilBody cilBody, bool keepMaxStack) { Reset(cilBody.Instructions, cilBody.ExceptionHandlers); @@ -294,38 +286,24 @@ void WriteSmallExceptionClauses(BinaryWriter writer) { } /// - protected override void ErrorImpl(string message) { - helper.Error(message); - } + protected override void ErrorImpl(string message) => helper.Error(message); /// - protected override void WriteInlineField(BinaryWriter writer, Instruction instr) { - writer.Write(helper.GetToken(instr.Operand).Raw); - } + protected override void WriteInlineField(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineMethod(BinaryWriter writer, Instruction instr) { - writer.Write(helper.GetToken(instr.Operand).Raw); - } + protected override void WriteInlineMethod(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineSig(BinaryWriter writer, Instruction instr) { - writer.Write(helper.GetToken(instr.Operand).Raw); - } + protected override void WriteInlineSig(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineString(BinaryWriter writer, Instruction instr) { - writer.Write(helper.GetToken(instr.Operand).Raw); - } + protected override void WriteInlineString(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineTok(BinaryWriter writer, Instruction instr) { - writer.Write(helper.GetToken(instr.Operand).Raw); - } + protected override void WriteInlineTok(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineType(BinaryWriter writer, Instruction instr) { - writer.Write(helper.GetToken(instr.Operand).Raw); - } + protected override void WriteInlineType(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); } } diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index 09fd5dddd..74aeae575 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -21,9 +21,7 @@ public abstract class MethodBodyWriterBase { /// /// true if there was at least one error /// - public bool ErrorDetected { - get { return errors > 0; } - } + public bool ErrorDetected => errors > 0; internal MethodBodyWriterBase() { } @@ -70,9 +68,8 @@ protected virtual void ErrorImpl(string message) { protected uint GetMaxStack() { if (instructions.Count == 0) return 0; - uint maxStack; maxStackCalculator.Reset(instructions, exceptionHandlers); - if (!maxStackCalculator.Calculate(out maxStack)) { + if (!maxStackCalculator.Calculate(out uint maxStack)) { Error("Error calculating max stack value. If the method's obfuscated, set CilBody.KeepOldMaxStack or MetaDataOptions.Flags (KeepOldMaxStack, global option) to ignore this error. Otherwise fix your generated CIL code so it conforms to the ECMA standard."); maxStack += 8; } @@ -90,8 +87,7 @@ protected uint GetOffset(Instruction instr) { Error("Instruction is null"); return 0; } - uint offset; - if (offsets.TryGetValue(instr, out offset)) + if (offsets.TryGetValue(instr, out uint offset)) return offset; Error("Found some other method's instruction or a removed instruction. You probably removed an instruction that is the target of a branch instruction or an instruction that's the first/last instruction in an exception handler."); return 0; @@ -117,9 +113,7 @@ protected uint InitializeInstructionOffsets() { /// /// The instruction /// Size of the instruction in bytes - protected virtual uint GetSizeOfInstruction(Instruction instr) { - return (uint)instr.GetSize(); - } + protected virtual uint GetSizeOfInstruction(Instruction instr) => (uint)instr.GetSize(); /// /// Writes all instructions to at its current offset @@ -142,9 +136,7 @@ protected uint WriteInstructions(BinaryWriter writer) { /// /// The instruction writer /// Current offset, relative to the first written instruction - protected uint ToInstructionOffset(BinaryWriter writer) { - return (uint)writer.BaseStream.Position - firstInstructionOffset; - } + protected uint ToInstructionOffset(BinaryWriter writer) => (uint)writer.BaseStream.Position - firstInstructionOffset; /// /// Writes an instruction diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 078144a6f..1504e7c71 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -60,99 +60,73 @@ public sealed class ModuleWriter : ModuleWriterBase { bool needStartupStub; /// - public override ModuleDef Module { - get { return module; } - } + public override ModuleDef Module => module; /// - public override ModuleWriterOptionsBase TheOptions { - get { return Options; } - } + public override ModuleWriterOptionsBase TheOptions => Options; /// /// Gets/sets the writer options. This is never null /// public ModuleWriterOptions Options { - get { return options ?? (options = new ModuleWriterOptions(module)); } - set { options = value; } + get => options ?? (options = new ModuleWriterOptions(module)); + set => options = value; } /// /// Gets all s /// - public override List Sections { - get { return sections; } - } + public override List Sections => sections; /// /// Gets the .text section /// - public override PESection TextSection { - get { return textSection; } - } + public override PESection TextSection => textSection; /// /// Gets the .sdata section /// - internal PESection SdataSection { - get { return sdataSection; } - } + internal PESection SdataSection => sdataSection; /// /// Gets the .rsrc section or null if none /// - public override PESection RsrcSection { - get { return rsrcSection; } - } + public override PESection RsrcSection => rsrcSection; /// /// Gets the .reloc section /// - public PESection RelocSection { - get { return relocSection; } - } + public PESection RelocSection => relocSection; /// /// Gets the PE headers /// - public PEHeaders PEHeaders { - get { return peHeaders; } - } + public PEHeaders PEHeaders => peHeaders; /// /// Gets the IAT or null if there's none /// - public ImportAddressTable ImportAddressTable { - get { return importAddressTable; } - } + public ImportAddressTable ImportAddressTable => importAddressTable; /// /// Gets the .NET header /// - public ImageCor20Header ImageCor20Header { - get { return imageCor20Header; } - } + public ImageCor20Header ImageCor20Header => imageCor20Header; /// /// Gets the import directory or null if there's none /// - public ImportDirectory ImportDirectory { - get { return importDirectory; } - } + public ImportDirectory ImportDirectory => importDirectory; /// /// Gets the startup stub or null if there's none /// - public StartupStub StartupStub { - get { return startupStub; } - } + public StartupStub StartupStub => startupStub; /// /// Gets the reloc directory or null if there's none /// - public RelocDirectory RelocDirectory { - get { return relocDirectory; } - } + public RelocDirectory RelocDirectory => relocDirectory; /// /// Constructor @@ -191,9 +165,7 @@ void Initialize() { } /// - protected override Win32Resources GetWin32Resources() { - return Options.Win32Resources ?? module.Win32Resources; - } + protected override Win32Resources GetWin32Resources() => Options.Win32Resources ?? module.Win32Resources; void CreateSections() { sections = new List(); @@ -321,12 +293,10 @@ void InitializeChunkProperties() { } uint GetEntryPoint() { - var methodEntryPoint = module.ManagedEntryPoint as MethodDef; - if (methodEntryPoint != null) + if (module.ManagedEntryPoint is MethodDef methodEntryPoint) return new MDToken(Table.Method, metaData.GetRid(methodEntryPoint)).Raw; - var fileEntryPoint = module.ManagedEntryPoint as FileDef; - if (fileEntryPoint != null) + if (module.ManagedEntryPoint is FileDef fileEntryPoint) return new MDToken(Table.File, metaData.GetRid(fileEntryPoint)).Raw; uint nativeEntryPoint = (uint)module.NativeEntryPoint; diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 3c5965d1e..d647527c3 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -33,8 +33,8 @@ public class ModuleWriterOptionsBase { /// Gets/sets the listener /// public IModuleWriterListener Listener { - get { return listener; } - set { listener = value; } + get => listener; + set => listener = value; } /// @@ -43,8 +43,8 @@ public IModuleWriterListener Listener { /// create your own logger or use . /// public ILogger Logger { - get { return logger; } - set { logger = value; } + get => logger; + set => logger = value; } /// @@ -52,32 +52,32 @@ public ILogger Logger { /// . /// public ILogger MetaDataLogger { - get { return metaDataLogger; } - set { metaDataLogger = value; } + get => metaDataLogger; + set => metaDataLogger = value; } /// /// Gets/sets the options. This is never null. /// public PEHeadersOptions PEHeadersOptions { - get { return peHeadersOptions ?? (peHeadersOptions = new PEHeadersOptions()); } - set { peHeadersOptions = value; } + get => peHeadersOptions ?? (peHeadersOptions = new PEHeadersOptions()); + set => peHeadersOptions = value; } /// /// Gets/sets the options. This is never null. /// public Cor20HeaderOptions Cor20HeaderOptions { - get { return cor20HeaderOptions ?? (cor20HeaderOptions = new Cor20HeaderOptions()); } - set { cor20HeaderOptions = value; } + get => cor20HeaderOptions ?? (cor20HeaderOptions = new Cor20HeaderOptions()); + set => cor20HeaderOptions = value; } /// /// Gets/sets the options. This is never null. /// public MetaDataOptions MetaDataOptions { - get { return metaDataOptions ?? (metaDataOptions = new MetaDataOptions()); } - set { metaDataOptions = value; } + get => metaDataOptions ?? (metaDataOptions = new MetaDataOptions()); + set => metaDataOptions = value; } /// @@ -85,8 +85,8 @@ public MetaDataOptions MetaDataOptions { /// Win32 resources if any. /// public Win32Resources Win32Resources { - get { return win32Resources; } - set { win32Resources = value; } + get => win32Resources; + set => win32Resources = value; } /// @@ -95,8 +95,8 @@ public Win32Resources Win32Resources { /// public key from your strong name key file, execute sn -p mykey.snk mypublickey.snk /// public bool DelaySign { - get { return delaySign; } - set { delaySign = value; } + get => delaySign; + set => delaySign = value; } /// @@ -109,8 +109,8 @@ public bool DelaySign { /// to initialize this property if you use enhanced strong name signing. /// public StrongNameKey StrongNameKey { - get { return strongNameKey; } - set { strongNameKey = value; } + get => strongNameKey; + set => strongNameKey = value; } /// @@ -122,8 +122,8 @@ public StrongNameKey StrongNameKey { /// to initialize this property if you use enhanced strong name signing. /// public StrongNamePublicKey StrongNamePublicKey { - get { return strongNamePublicKey; } - set { strongNamePublicKey = value; } + get => strongNamePublicKey; + set => strongNamePublicKey = value; } /// @@ -161,12 +161,7 @@ public bool Is64Bit { /// true if it should be written as an EXE file, false if it should be /// written as a DLL file. /// - public bool IsExeFile { - get { - return ModuleKind != ModuleKind.Dll && - ModuleKind != ModuleKind.NetModule; - } - } + public bool IsExeFile => ModuleKind != ModuleKind.Dll && ModuleKind != ModuleKind.NetModule; /// /// Set it to true to enable writing a PDB file. Default is false (a PDB file @@ -388,58 +383,44 @@ public abstract class ModuleWriterBase : IMetaDataListener, ILogger { /// Gets/sets the module writer listener /// protected IModuleWriterListener Listener { - get { return listener ?? DummyModuleWriterListener.Instance; } - set { listener = value; } + get => listener ?? DummyModuleWriterListener.Instance; + set => listener = value; } /// /// Gets the destination stream /// - public Stream DestinationStream { - get { return destStream; } - } + public Stream DestinationStream => destStream; /// /// Gets the constants /// - public UniqueChunkList Constants { - get { return constants; } - } + public UniqueChunkList Constants => constants; /// /// Gets the method bodies /// - public MethodBodyChunks MethodBodies { - get { return methodBodies; } - } + public MethodBodyChunks MethodBodies => methodBodies; /// /// Gets the .NET resources /// - public NetResources NetResources { - get { return netResources; } - } + public NetResources NetResources => netResources; /// /// Gets the .NET metadata /// - public MetaData MetaData { - get { return metaData; } - } + public MetaData MetaData => metaData; /// /// Gets the Win32 resources or null if there's none /// - public Win32ResourcesChunk Win32Resources { - get { return win32Resources; } - } + public Win32ResourcesChunk Win32Resources => win32Resources; /// /// Gets the strong name signature or null if there's none /// - public StrongNameSignature StrongNameSignature { - get { return strongNameSignature; } - } + public StrongNameSignature StrongNameSignature => strongNameSignature; /// /// Gets all s @@ -459,17 +440,13 @@ public StrongNameSignature StrongNameSignature { /// /// Gets the debug directory or null if there's none /// - public DebugDirectory DebugDirectory { - get { return debugDirectory; } - } + public DebugDirectory DebugDirectory => debugDirectory; /// /// true if this is a , false if /// this is a . /// - public bool IsNativeWriter { - get { return this is NativeModuleWriter; } - } + public bool IsNativeWriter => this is NativeModuleWriter; /// /// null if we're not writing a PDB @@ -646,9 +623,7 @@ protected void StrongNameSign(long snSigOffset) { snSigner.WriteSignature(TheOptions.StrongNameKey, snSigOffset); } - bool CanWritePdb() { - return pdbState != null; - } + bool CanWritePdb() => pdbState != null; /// /// Creates the debug directory if a PDB file should be written @@ -709,8 +684,7 @@ void WriteWindowsPdb(PdbState pdbState) { pdbWriter.Logger = TheOptions.Logger; pdbWriter.Write(); - IMAGE_DEBUG_DIRECTORY idd; - var data = pdbWriter.GetDebugInfo(out idd); + var data = pdbWriter.GetDebugInfo(out var idd); var entry = debugDirectory.Add(data); entry.DebugDirectory = idd; entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); @@ -748,10 +722,7 @@ ISymbolWriter2 GetWindowsPdbSymbolWriter() { return SymbolWriterCreator.Create(createdPdbFileName); } - static string GetStreamName(Stream stream) { - var fs = stream as FileStream; - return fs == null ? null : fs.Name; - } + static string GetStreamName(Stream stream) => (stream as FileStream)?.Name; static string GetModuleName(ModuleDef module) { var name = module.Name ?? string.Empty; @@ -1040,36 +1011,29 @@ void IMetaDataListener.OnMetaDataEvent(MetaData metaData, MetaDataEvent evt) { } } - ILogger GetLogger() { - return TheOptions.Logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; - } + ILogger GetLogger() => TheOptions.Logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; /// - void ILogger.Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) { + void ILogger.Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) => GetLogger().Log(this, loggerEvent, format, args); - } /// - bool ILogger.IgnoresEvent(LoggerEvent loggerEvent) { - return GetLogger().IgnoresEvent(loggerEvent); - } + bool ILogger.IgnoresEvent(LoggerEvent loggerEvent) => GetLogger().IgnoresEvent(loggerEvent); /// /// Logs an error message /// /// Format /// Format args - protected void Error(string format, params object[] args) { + protected void Error(string format, params object[] args) => GetLogger().Log(this, LoggerEvent.Error, format, args); - } /// /// Logs a warning message /// /// Format /// Format args - protected void Warning(string format, params object[] args) { + protected void Warning(string format, params object[] args) => GetLogger().Log(this, LoggerEvent.Warning, format, args); - } } } diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index b59a62140..875e3a712 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -108,9 +108,8 @@ public sealed class OrigSection : IDisposable { /// Constructor /// /// PE section - public OrigSection(ImageSectionHeader peSection) { - this.PESection = peSection; - } + public OrigSection(ImageSectionHeader peSection) => + PESection = peSection; /// public void Dispose() { @@ -123,62 +122,48 @@ public void Dispose() { /// public override string ToString() { uint offs = Chunk.Data is IImageStream ? (uint)((IImageStream)Chunk.Data).FileOffset : 0; - return string.Format("{0} FO:{1:X8} L:{2:X8}", PESection.DisplayName, offs, (uint)Chunk.Data.Length); + return $"{PESection.DisplayName} FO:{offs:X8} L:{(uint)Chunk.Data.Length:X8}"; } } /// /// Gets the module /// - public ModuleDefMD ModuleDefMD { - get { return module; } - } + public ModuleDefMD ModuleDefMD => module; /// - public override ModuleDef Module { - get { return module; } - } + public override ModuleDef Module => module; /// - public override ModuleWriterOptionsBase TheOptions { - get { return Options; } - } + public override ModuleWriterOptionsBase TheOptions => Options; /// /// Gets/sets the writer options. This is never null /// public NativeModuleWriterOptions Options { - get { return options ?? (options = new NativeModuleWriterOptions(module)); } - set { options = value; } + get => options ?? (options = new NativeModuleWriterOptions(module)); + set => options = value; } /// /// Gets all s /// - public override List Sections { - get { return sections; } - } + public override List Sections => sections; /// /// Gets the original PE sections and their data /// - public List OrigSections { - get { return origSections; } - } + public List OrigSections => origSections; /// /// Gets the .text section /// - public override PESection TextSection { - get { return textSection; } - } + public override PESection TextSection => textSection; /// /// Gets the .rsrc section or null if there's none /// - public override PESection RsrcSection { - get { return rsrcSection; } - } + public override PESection RsrcSection => rsrcSection; /// /// Constructor @@ -188,7 +173,7 @@ public override PESection RsrcSection { public NativeModuleWriter(ModuleDefMD module, NativeModuleWriterOptions options) { this.module = module; this.options = options; - this.peImage = module.MetaData.PEImage; + peImage = module.MetaData.PEImage; } /// @@ -341,8 +326,7 @@ uint GetLastFileSectionOffset() { } long WriteFile() { - uint entryPointToken; - bool entryPointIsManagedOrNoEntryPoint = GetEntryPoint(out entryPointToken); + bool entryPointIsManagedOrNoEntryPoint = GetEntryPoint(out uint entryPointToken); Listener.OnWriterEvent(this, ModuleWriterEvent.BeginWritePdb); WritePdbFile(); @@ -393,9 +377,7 @@ long WriteFile() { /// /// true if image is 64-bit /// - bool Is64Bit() { - return peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader64; - } + bool Is64Bit() => peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader64; Characteristics GetCharacteristics() { var ch = module.Characteristics; @@ -675,16 +657,13 @@ void UpdateVTableFixups(BinaryWriter writer) { } uint GetMethodToken(IMethod method) { - var md = method as MethodDef; - if (md != null) + if (method is MethodDef md) return new MDToken(Table.Method, metaData.GetRid(md)).Raw; - var mr = method as MemberRef; - if (mr != null) + if (method is MemberRef mr) return new MDToken(Table.MemberRef, metaData.GetRid(mr)).Raw; - var ms = method as MethodSpec; - if (ms != null) + if (method is MethodSpec ms) return new MDToken(Table.MethodSpec, metaData.GetRid(ms)).Raw; if (method == null) @@ -707,13 +686,11 @@ bool GetEntryPoint(out uint ep) { return ep == 0 || ((Options.Cor20HeaderOptions.Flags ?? 0) & ComImageFlags.NativeEntryPoint) == 0; } - var epMethod = module.ManagedEntryPoint as MethodDef; - if (epMethod != null) { + if (module.ManagedEntryPoint is MethodDef epMethod) { ep = new MDToken(Table.Method, metaData.GetRid(epMethod)).Raw; return true; } - var file = module.ManagedEntryPoint as FileDef; - if (file != null) { + if (module.ManagedEntryPoint is FileDef file) { ep = new MDToken(Table.File, metaData.GetRid(file)).Raw; return true; } diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index 3f8a85427..442bc7dce 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -19,30 +19,22 @@ public sealed class NetResources : IChunk { RVA rva; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets offset of next resource. This offset is relative to the start of /// the .NET resources and is always aligned. /// - public uint NextOffset { - get { return length; } - } + public uint NextOffset => length; /// /// Constructor /// /// Alignment of all resources - public NetResources(uint alignment) { - this.alignment = alignment; - } + public NetResources(uint alignment) => this.alignment = alignment; /// /// Adds a resource @@ -73,18 +65,14 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { - RVA rva2 = rva; + var rva2 = rva; foreach (var resourceData in resources) { writer.Write(resourceData.GetFileLength()); resourceData.VerifyWriteTo(writer); diff --git a/src/DotNet/Writer/NormalMetaData.cs b/src/DotNet/Writer/NormalMetaData.cs index c0033051f..562d2c343 100644 --- a/src/DotNet/Writer/NormalMetaData.cs +++ b/src/DotNet/Writer/NormalMetaData.cs @@ -20,9 +20,7 @@ sealed class NormalMetaData : MetaData { readonly Rows typeSpecInfos = new Rows(); readonly Rows methodSpecInfos = new Rows(); - protected override int NumberOfMethods { - get { return methodDefInfos.Count; } - } + protected override int NumberOfMethods => methodDefInfos.Count; public NormalMetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options, DebugMetaDataKind debugKind, bool isStandaloneDebugMetadata) : base(module, constants, methodBodies, netResources, options, debugKind, isStandaloneDebugMetadata) { @@ -128,15 +126,13 @@ protected override void AllocateMemberDefRids() { /// public override uint GetRid(TypeRef tr) { - uint rid; - typeRefInfos.TryGetRid(tr, out rid); + typeRefInfos.TryGetRid(tr, out uint rid); return rid; } /// public override uint GetRid(TypeDef td) { - uint rid; - if (typeDefInfos.TryGetRid(td, out rid)) + if (typeDefInfos.TryGetRid(td, out uint rid)) return rid; if (td == null) Error("TypeDef is null"); @@ -147,8 +143,7 @@ public override uint GetRid(TypeDef td) { /// public override uint GetRid(FieldDef fd) { - uint rid; - if (fieldDefInfos.TryGetRid(fd, out rid)) + if (fieldDefInfos.TryGetRid(fd, out uint rid)) return rid; if (fd == null) Error("Field is null"); @@ -159,8 +154,7 @@ public override uint GetRid(FieldDef fd) { /// public override uint GetRid(MethodDef md) { - uint rid; - if (methodDefInfos.TryGetRid(md, out rid)) + if (methodDefInfos.TryGetRid(md, out uint rid)) return rid; if (md == null) Error("Method is null"); @@ -171,8 +165,7 @@ public override uint GetRid(MethodDef md) { /// public override uint GetRid(ParamDef pd) { - uint rid; - if (paramDefInfos.TryGetRid(pd, out rid)) + if (paramDefInfos.TryGetRid(pd, out uint rid)) return rid; if (pd == null) Error("Param is null"); @@ -183,22 +176,19 @@ public override uint GetRid(ParamDef pd) { /// public override uint GetRid(MemberRef mr) { - uint rid; - memberRefInfos.TryGetRid(mr, out rid); + memberRefInfos.TryGetRid(mr, out uint rid); return rid; } /// public override uint GetRid(StandAloneSig sas) { - uint rid; - standAloneSigInfos.TryGetRid(sas, out rid); + standAloneSigInfos.TryGetRid(sas, out uint rid); return rid; } /// public override uint GetRid(EventDef ed) { - uint rid; - if (eventDefInfos.TryGetRid(ed, out rid)) + if (eventDefInfos.TryGetRid(ed, out uint rid)) return rid; if (ed == null) Error("Event is null"); @@ -209,8 +199,7 @@ public override uint GetRid(EventDef ed) { /// public override uint GetRid(PropertyDef pd) { - uint rid; - if (propertyDefInfos.TryGetRid(pd, out rid)) + if (propertyDefInfos.TryGetRid(pd, out uint rid)) return rid; if (pd == null) Error("Property is null"); @@ -221,15 +210,13 @@ public override uint GetRid(PropertyDef pd) { /// public override uint GetRid(TypeSpec ts) { - uint rid; - typeSpecInfos.TryGetRid(ts, out rid); + typeSpecInfos.TryGetRid(ts, out uint rid); return rid; } /// public override uint GetRid(MethodSpec ms) { - uint rid; - methodSpecInfos.TryGetRid(ms, out rid); + methodSpecInfos.TryGetRid(ms, out uint rid); return rid; } @@ -239,8 +226,7 @@ protected override uint AddTypeRef(TypeRef tr) { Error("TypeRef is null"); return 0; } - uint rid; - if (typeRefInfos.TryGetRid(tr, out rid)) { + if (typeRefInfos.TryGetRid(tr, out uint rid)) { if (rid == 0) Error("TypeRef {0:X8} has an infinite ResolutionScope loop", tr.MDToken.Raw); return rid; @@ -262,8 +248,7 @@ protected override uint AddTypeSpec(TypeSpec ts) { Error("TypeSpec is null"); return 0; } - uint rid; - if (typeSpecInfos.TryGetRid(ts, out rid)) { + if (typeSpecInfos.TryGetRid(ts, out uint rid)) { if (rid == 0) Error("TypeSpec {0:X8} has an infinite TypeSig loop", ts.MDToken.Raw); return rid; @@ -283,8 +268,8 @@ protected override uint AddMemberRef(MemberRef mr) { Error("MemberRef is null"); return 0; } - uint rid; - if (memberRefInfos.TryGetRid(mr, out rid)) + + if (memberRefInfos.TryGetRid(mr, out uint rid)) return rid; var row = new RawMemberRefRow(AddMemberRefParent(mr.Class), stringsHeap.Add(mr.Name), @@ -302,8 +287,7 @@ protected override uint AddStandAloneSig(StandAloneSig sas) { Error("StandAloneSig is null"); return 0; } - uint rid; - if (standAloneSigInfos.TryGetRid(sas, out rid)) + if (standAloneSigInfos.TryGetRid(sas, out uint rid)) return rid; var row = new RawStandAloneSigRow(GetSignature(sas.Signature)); rid = tablesHeap.StandAloneSigTable.Add(row); @@ -319,8 +303,7 @@ protected override uint AddMethodSpec(MethodSpec ms) { Error("MethodSpec is null"); return 0; } - uint rid; - if (methodSpecInfos.TryGetRid(ms, out rid)) + if (methodSpecInfos.TryGetRid(ms, out uint rid)) return rid; var row = new RawMethodSpecRow(AddMethodDefOrRef(ms.Method), GetSignature(ms.Instantiation)); diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 21f2e51c4..77c9c2829 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -162,9 +162,7 @@ public sealed class PEHeadersOptions { /// Creates a new time date stamp using current time /// /// A new time date stamp - public static uint CreateNewTimeDateStamp() { - return (uint)(DateTime.UtcNow - Epoch).TotalSeconds; - } + public static uint CreateNewTimeDateStamp() => (uint)(DateTime.UtcNow - Epoch).TotalSeconds; static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); } @@ -244,48 +242,38 @@ public sealed class PEHeaders : IChunk { /// /// Gets the image base /// - public ulong ImageBase { - get { return imageBase; } - } + public ulong ImageBase => imageBase; /// /// Gets/sets a value indicating whether this is a EXE or a DLL file /// public bool IsExeFile { - get { return isExeFile; } - set { isExeFile = value; } + get => isExeFile; + set => isExeFile = value; } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the section alignment /// - public uint SectionAlignment { - get { return sectionAlignment; } - } + public uint SectionAlignment => sectionAlignment; /// /// Gets the file alignment /// - public uint FileAlignment { - get { return fileAlignment; } - } + public uint FileAlignment => fileAlignment; /// /// Gets/sets the s /// public IList PESections { - get { return sections; } - set { sections = value; } + get => sections; + set => sections = value; } /// @@ -301,8 +289,8 @@ public PEHeaders() /// Options public PEHeaders(PEHeadersOptions options) { this.options = options ?? new PEHeadersOptions(); - this.sectionAlignment = this.options.SectionAlignment ?? 0x2000; - this.fileAlignment = this.options.FileAlignment ?? 0x200; + sectionAlignment = this.options.SectionAlignment ?? 0x2000; + fileAlignment = this.options.FileAlignment ?? 0x200; } /// @@ -333,14 +321,10 @@ int SectionsCount { } /// - public uint GetFileLength() { - return length; - } + public uint GetFileLength() => length; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); IEnumerable GetSectionSizeInfos() { foreach (var section in sections) { @@ -482,9 +466,7 @@ public void WriteCheckSum(BinaryWriter writer, long length) { writer.Write(checkSum); } - Machine GetMachine() { - return options.Machine ?? Machine.I386; - } + Machine GetMachine() => options.Machine ?? Machine.I386; bool Use32BitOptionalHeader() { var mach = GetMachine(); diff --git a/src/DotNet/Writer/PESection.cs b/src/DotNet/Writer/PESection.cs index 1ca3fbcd9..ecb085dcc 100644 --- a/src/DotNet/Writer/PESection.cs +++ b/src/DotNet/Writer/PESection.cs @@ -16,38 +16,32 @@ public sealed class PESection : ChunkList { /// Gets the name /// public string Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Gets the Characteristics /// public uint Characteristics { - get { return characteristics; } - set { characteristics = value; } + get => characteristics; + set => characteristics = value; } /// /// true if this is a code section /// - public bool IsCode { - get { return (characteristics & 0x20) != 0; } - } + public bool IsCode => (characteristics & 0x20) != 0; /// /// true if this is an initialized data section /// - public bool IsInitializedData { - get { return (characteristics & 0x40) != 0; } - } + public bool IsInitializedData => (characteristics & 0x40) != 0; /// /// true if this is an uninitialized data section /// - public bool IsUninitializedData { - get { return (characteristics & 0x80) != 0; } - } + public bool IsUninitializedData => (characteristics & 0x80) != 0; /// /// Constructor diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs index 6be6fbcd3..454905e44 100644 --- a/src/DotNet/Writer/PdbHeap.cs +++ b/src/DotNet/Writer/PdbHeap.cs @@ -9,24 +9,20 @@ namespace dnlib.DotNet.Writer { /// public sealed class PdbHeap : HeapBase { /// - public override string Name { - get { return "#Pdb"; } - } + public override string Name => "#Pdb"; /// /// Gets the PDB ID. This is always 20 bytes in size. /// - public byte[] PdbId { - get { return pdbId; } - } + public byte[] PdbId => pdbId; readonly byte[] pdbId; /// /// Gets/sets the entry point token /// public uint EntryPoint { - get { return entryPoint; } - set { entryPoint = value; } + get => entryPoint; + set => entryPoint = value; } uint entryPoint; @@ -61,9 +57,7 @@ public ulong ReferencedTypeSystemTables { /// /// Gets the type system table rows. This table has 64 elements. /// - public uint[] TypeSystemTableRows { - get { return typeSystemTableRows; } - } + public uint[] TypeSystemTableRows => typeSystemTableRows; readonly uint[] typeSystemTableRows; /// diff --git a/src/DotNet/Writer/PreserveTokensMetaData.cs b/src/DotNet/Writer/PreserveTokensMetaData.cs index f04a835da..e0d15671e 100644 --- a/src/DotNet/Writer/PreserveTokensMetaData.cs +++ b/src/DotNet/Writer/PreserveTokensMetaData.cs @@ -40,9 +40,9 @@ sealed class MemberDefInfo where T : IMDTokenProvider { public uint NewRid; public MemberDefInfo(T def, uint rid) { - this.Def = def; - this.Rid = rid; - this.NewRid = rid; + Def = def; + Rid = rid; + NewRid = rid; } } @@ -67,23 +67,17 @@ sealed class MemberDefDict where T : IMDTokenProvider { /// Gets total number of defs in the list. It does not necessarily return /// the table size. Use for that. /// - public int Count { - get { return defs.Count; } - } + public int Count => defs.Count; /// /// Gets the number of rows that need to be created in the table /// - public int TableSize { - get { return tableSize; } - } + public int TableSize => tableSize; /// /// Returns true if the ptr table (eg. MethodPtr) is needed /// - public bool NeedPtrTable { - get { return preserveRids && !wasSorted; } - } + public bool NeedPtrTable => preserveRids && !wasSorted; public MemberDefDict(Type defMDType, bool preserveRids) : this(defMDType, preserveRids, false) { @@ -95,13 +89,10 @@ public MemberDefDict(Type defMDType, bool preserveRids, bool enableRidToInfo) { this.enableRidToInfo = enableRidToInfo; } - public uint Rid(T def) { - return defToInfo[def].Rid; - } + public uint Rid(T def) => defToInfo[def].Rid; public bool TryGetRid(T def, out uint rid) { - MemberDefInfo info; - if (def == null || !defToInfo.TryGetValue(def, out info)) { + if (def == null || !defToInfo.TryGetValue(def, out var info)) { rid = 0; return false; } @@ -132,17 +123,11 @@ public void Sort(Comparison> comparer) { } } - public MemberDefInfo Get(int i) { - return defs[i]; - } - - public MemberDefInfo GetSorted(int i) { - return sortedDefs[i]; - } + public MemberDefInfo Get(int i) => defs[i]; + public MemberDefInfo GetSorted(int i) => sortedDefs[i]; public MemberDefInfo GetByRid(uint rid) { - MemberDefInfo info; - ridToInfo.TryGetValue(rid, out info); + ridToInfo.TryGetValue(rid, out var info); return info; } @@ -198,14 +183,10 @@ public void SortDefs() { throw new ModuleWriterException("Table is too big"); } - public int GetCollectionPosition(T def) { - return collectionPositions[def]; - } + public int GetCollectionPosition(T def) => collectionPositions[def]; } - protected override int NumberOfMethods { - get { return methodDefInfos.Count; } - } + protected override int NumberOfMethods => methodDefInfos.Count; public PreserveTokensMetaData(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetaDataOptions options, DebugMetaDataKind debugKind, bool isStandaloneDebugMetadata) : base(module, constants, methodBodies, netResources, options, debugKind, isStandaloneDebugMetadata) { @@ -216,8 +197,7 @@ public PreserveTokensMetaData(ModuleDef module, UniqueChunkList /// public override uint GetRid(TypeRef tr) { - uint rid; - typeRefInfos.TryGetRid(tr, out rid); + typeRefInfos.TryGetRid(tr, out uint rid); return rid; } @@ -227,8 +207,7 @@ public override uint GetRid(TypeDef td) { Error("TypeDef is null"); return 0; } - uint rid; - if (typeToRid.TryGetValue(td, out rid)) + if (typeToRid.TryGetValue(td, out uint rid)) return rid; Error("TypeDef {0} ({1:X8}) is not defined in this module ({2}). A type was removed that is still referenced by this module.", td, td.MDToken.Raw, module); return 0; @@ -236,8 +215,7 @@ public override uint GetRid(TypeDef td) { /// public override uint GetRid(FieldDef fd) { - uint rid; - if (fieldDefInfos.TryGetRid(fd, out rid)) + if (fieldDefInfos.TryGetRid(fd, out uint rid)) return rid; if (fd == null) Error("Field is null"); @@ -248,8 +226,7 @@ public override uint GetRid(FieldDef fd) { /// public override uint GetRid(MethodDef md) { - uint rid; - if (methodDefInfos.TryGetRid(md, out rid)) + if (methodDefInfos.TryGetRid(md, out uint rid)) return rid; if (md == null) Error("Method is null"); @@ -260,8 +237,7 @@ public override uint GetRid(MethodDef md) { /// public override uint GetRid(ParamDef pd) { - uint rid; - if (paramDefInfos.TryGetRid(pd, out rid)) + if (paramDefInfos.TryGetRid(pd, out uint rid)) return rid; if (pd == null) Error("Param is null"); @@ -272,22 +248,19 @@ public override uint GetRid(ParamDef pd) { /// public override uint GetRid(MemberRef mr) { - uint rid; - memberRefInfos.TryGetRid(mr, out rid); + memberRefInfos.TryGetRid(mr, out uint rid); return rid; } /// public override uint GetRid(StandAloneSig sas) { - uint rid; - standAloneSigInfos.TryGetRid(sas, out rid); + standAloneSigInfos.TryGetRid(sas, out uint rid); return rid; } /// public override uint GetRid(EventDef ed) { - uint rid; - if (eventDefInfos.TryGetRid(ed, out rid)) + if (eventDefInfos.TryGetRid(ed, out uint rid)) return rid; if (ed == null) Error("Event is null"); @@ -298,8 +271,7 @@ public override uint GetRid(EventDef ed) { /// public override uint GetRid(PropertyDef pd) { - uint rid; - if (propertyDefInfos.TryGetRid(pd, out rid)) + if (propertyDefInfos.TryGetRid(pd, out uint rid)) return rid; if (pd == null) Error("Property is null"); @@ -310,15 +282,13 @@ public override uint GetRid(PropertyDef pd) { /// public override uint GetRid(TypeSpec ts) { - uint rid; - typeSpecInfos.TryGetRid(ts, out rid); + typeSpecInfos.TryGetRid(ts, out uint rid); return rid; } /// public override uint GetRid(MethodSpec ms) { - uint rid; - methodSpecInfos.TryGetRid(ms, out rid); + methodSpecInfos.TryGetRid(ms, out uint rid); return rid; } @@ -681,7 +651,7 @@ void ReUseDeletedFieldRows() { var frow = tablesHeap.FieldTable[frid]; frow.Flags = (ushort)(FieldAttributes.Public | FieldAttributes.Static); - frow.Name = stringsHeap.Add(string.Format("f{0:X6}", frid)); + frow.Name = stringsHeap.Add($"f{frid:X6}"); frow.Signature = fieldSig; tablesHeap.FieldPtrTable.Create(new RawFieldPtrRow(frid)); } @@ -717,7 +687,7 @@ void ReUseDeletedMethodRows() { mrow.RVA = 0; mrow.ImplFlags = (ushort)(MethodImplAttributes.IL | MethodImplAttributes.Managed); mrow.Flags = (ushort)(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Abstract); - mrow.Name = stringsHeap.Add(string.Format("m{0:X6}", mrid)); + mrow.Name = stringsHeap.Add($"m{mrid:X6}"); mrow.Signature = methodSig; mrow.ParamList = (uint)paramDefInfos.Count; tablesHeap.MethodPtrTable.Create(new RawMethodPtrRow(mrid)); @@ -757,13 +727,13 @@ void ReUseDeletedParamRows() { var prow = tablesHeap.ParamTable[prid]; prow.Flags = 0; prow.Sequence = 0; // Return type parameter - prow.Name = stringsHeap.Add(string.Format("p{0:X6}", prid)); + prow.Name = stringsHeap.Add($"p{prid:X6}"); uint ptrRid = tablesHeap.ParamPtrTable.Create(new RawParamPtrRow(prid)); var mrow = new RawMethodRow(0, (ushort)(MethodImplAttributes.IL | MethodImplAttributes.Managed), (ushort)(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Abstract), - stringsHeap.Add(string.Format("mp{0:X6}", prid)), + stringsHeap.Add($"mp{prid:X6}"), methodSig, ptrRid); uint mrid = tablesHeap.MethodTable.Create(mrow); @@ -801,7 +771,7 @@ void ReUseDeletedEventRows() { var frow = tablesHeap.EventTable[erid]; frow.EventFlags = 0; - frow.Name = stringsHeap.Add(string.Format("E{0:X6}", erid)); + frow.Name = stringsHeap.Add($"E{erid:X6}"); frow.EventType = eventType; tablesHeap.EventPtrTable.Create(new RawEventPtrRow(erid)); } @@ -836,7 +806,7 @@ void ReUseDeletedPropertyRows() { var frow = tablesHeap.PropertyTable[prid]; frow.PropFlags = 0; - frow.Name = stringsHeap.Add(string.Format("P{0:X6}", prid)); + frow.Name = stringsHeap.Add($"P{prid:X6}"); frow.Type = propertySig; tablesHeap.PropertyPtrTable.Create(new RawPropertyPtrRow(prid)); } @@ -929,7 +899,7 @@ void FindMemberDefs() { paramDefInfos.SortDefs(); } - void SortFields() { + void SortFields() => fieldDefInfos.Sort((a, b) => { var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; @@ -939,9 +909,8 @@ void SortFields() { return dta.CompareTo(dtb); return fieldDefInfos.GetCollectionPosition(a.Def).CompareTo(fieldDefInfos.GetCollectionPosition(b.Def)); }); - } - void SortMethods() { + void SortMethods() => methodDefInfos.Sort((a, b) => { var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; @@ -951,9 +920,8 @@ void SortMethods() { return dta.CompareTo(dtb); return methodDefInfos.GetCollectionPosition(a.Def).CompareTo(methodDefInfos.GetCollectionPosition(b.Def)); }); - } - void SortParameters() { + void SortParameters() => paramDefInfos.Sort((a, b) => { var dma = a.Def.DeclaringMethod == null ? 0 : methodDefInfos.Rid(a.Def.DeclaringMethod); var dmb = b.Def.DeclaringMethod == null ? 0 : methodDefInfos.Rid(b.Def.DeclaringMethod); @@ -963,9 +931,8 @@ void SortParameters() { return dma.CompareTo(dmb); return paramDefInfos.GetCollectionPosition(a.Def).CompareTo(paramDefInfos.GetCollectionPosition(b.Def)); }); - } - void SortEvents() { + void SortEvents() => eventDefInfos.Sort((a, b) => { var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; @@ -975,9 +942,8 @@ void SortEvents() { return dta.CompareTo(dtb); return eventDefInfos.GetCollectionPosition(a.Def).CompareTo(eventDefInfos.GetCollectionPosition(b.Def)); }); - } - void SortProperties() { + void SortProperties() => propertyDefInfos.Sort((a, b) => { var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; @@ -987,7 +953,6 @@ void SortProperties() { return dta.CompareTo(dtb); return propertyDefInfos.GetCollectionPosition(a.Def).CompareTo(propertyDefInfos.GetCollectionPosition(b.Def)); }); - } void InitializeMethodAndFieldList() { uint fieldList = 1, methodList = 1; @@ -1047,8 +1012,7 @@ protected override uint AddTypeRef(TypeRef tr) { Error("TypeRef is null"); return 0; } - uint rid; - if (typeRefInfos.TryGetRid(tr, out rid)) { + if (typeRefInfos.TryGetRid(tr, out uint rid)) { if (rid == 0) Error("TypeRef {0:X8} has an infinite ResolutionScope loop", tr.MDToken.Raw); return rid; @@ -1069,17 +1033,14 @@ protected override uint AddTypeRef(TypeRef tr) { } /// - protected override uint AddTypeSpec(TypeSpec ts) { - return AddTypeSpec(ts, false); - } + protected override uint AddTypeSpec(TypeSpec ts) => AddTypeSpec(ts, false); uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { if (ts == null) { Error("TypeSpec is null"); return 0; } - uint rid; - if (typeSpecInfos.TryGetRid(ts, out rid)) { + if (typeSpecInfos.TryGetRid(ts, out uint rid)) { if (rid == 0) Error("TypeSpec {0:X8} has an infinite TypeSig loop", ts.MDToken.Raw); return rid; @@ -1098,17 +1059,14 @@ uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { } /// - protected override uint AddMemberRef(MemberRef mr) { - return AddMemberRef(mr, false); - } + protected override uint AddMemberRef(MemberRef mr) => AddMemberRef(mr, false); uint AddMemberRef(MemberRef mr, bool forceIsOld) { if (mr == null) { Error("MemberRef is null"); return 0; } - uint rid; - if (memberRefInfos.TryGetRid(mr, out rid)) + if (memberRefInfos.TryGetRid(mr, out uint rid)) return rid; bool isOld = forceIsOld || (PreserveMemberRefRids && mod.ResolveMemberRef(mr.Rid) == mr); @@ -1125,17 +1083,14 @@ uint AddMemberRef(MemberRef mr, bool forceIsOld) { } /// - protected override uint AddStandAloneSig(StandAloneSig sas) { - return AddStandAloneSig(sas, false); - } + protected override uint AddStandAloneSig(StandAloneSig sas) => AddStandAloneSig(sas, false); uint AddStandAloneSig(StandAloneSig sas, bool forceIsOld) { if (sas == null) { Error("StandAloneSig is null"); return 0; } - uint rid; - if (standAloneSigInfos.TryGetRid(sas, out rid)) + if (standAloneSigInfos.TryGetRid(sas, out uint rid)) return rid; bool isOld = forceIsOld || (PreserveStandAloneSigRids && mod.ResolveStandAloneSig(sas.Rid) == sas); @@ -1184,8 +1139,7 @@ protected override uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { uint AddStandAloneSig(CallingConventionSig callConvSig, uint origToken) { uint sig = GetSignature(callConvSig); - uint otherSig; - if (callConvTokenToSignature.TryGetValue(origToken, out otherSig)) { + if (callConvTokenToSignature.TryGetValue(origToken, out uint otherSig)) { if (sig == otherSig) return MDToken.ToRID(origToken); Warning("Could not preserve StandAloneSig token {0:X8}", origToken); @@ -1221,17 +1175,14 @@ bool IsValidStandAloneSigToken(uint token) { } /// - protected override uint AddMethodSpec(MethodSpec ms) { - return AddMethodSpec(ms, false); - } + protected override uint AddMethodSpec(MethodSpec ms) => AddMethodSpec(ms, false); uint AddMethodSpec(MethodSpec ms, bool forceIsOld) { if (ms == null) { Error("MethodSpec is null"); return 0; } - uint rid; - if (methodSpecInfos.TryGetRid(ms, out rid)) + if (methodSpecInfos.TryGetRid(ms, out uint rid)) return rid; bool isOld = forceIsOld || (PreserveMethodSpecRids && mod.ResolveMethodSpec(ms.Rid) == ms); @@ -1247,8 +1198,6 @@ uint AddMethodSpec(MethodSpec ms, bool forceIsOld) { } /// - protected override void BeforeSortingCustomAttributes() { - InitializeUninitializedTableRows(); - } + protected override void BeforeSortingCustomAttributes() => InitializeUninitializedTableRows(); } } diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index 2a704a7a4..e71d02d43 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -19,7 +19,7 @@ public sealed class RelocDirectory : IChunk { RVA rva; uint totalSize; - struct RelocInfo { + readonly struct RelocInfo { public readonly IChunk Chunk; public readonly uint OffsetOrRva; public RelocInfo(IChunk chunk, uint offset) { @@ -29,26 +29,18 @@ public RelocInfo(IChunk chunk, uint offset) { } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; - internal bool NeedsRelocSection { - get { return allRelocRvas.Count != 0; } - } + internal bool NeedsRelocSection => allRelocRvas.Count != 0; /// /// Constructor /// /// Machine - public RelocDirectory(Machine machine) { - this.machine = machine; - } + public RelocDirectory(Machine machine) => this.machine = machine; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -85,14 +77,10 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return totalSize; - } + public uint GetFileLength() => totalSize; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/SectionSizes.cs b/src/DotNet/Writer/SectionSizes.cs index ba994cfff..7f81580d9 100644 --- a/src/DotNet/Writer/SectionSizes.cs +++ b/src/DotNet/Writer/SectionSizes.cs @@ -4,7 +4,7 @@ using dnlib.Utils; namespace dnlib.DotNet.Writer { - struct SectionSizeInfo { + readonly struct SectionSizeInfo { /// /// Length of section /// @@ -29,7 +29,7 @@ public SectionSizeInfo(uint length, uint characteristics) { /// /// Calculates the optional header section sizes /// - struct SectionSizes { + readonly struct SectionSizes { public readonly uint SizeOfHeaders; public readonly uint SizeOfImage; public readonly uint BaseOfData, BaseOfCode; diff --git a/src/DotNet/Writer/SerializerMethodContext.cs b/src/DotNet/Writer/SerializerMethodContext.cs index a9dd30232..2e90b80d6 100644 --- a/src/DotNet/Writer/SerializerMethodContext.cs +++ b/src/DotNet/Writer/SerializerMethodContext.cs @@ -13,9 +13,7 @@ sealed class SerializerMethodContext { uint bodySize; bool dictInitd; - public bool HasBody { - get { return body != null; } - } + public bool HasBody => body != null; public SerializerMethodContext(IWriterError helper) { toOffset = new Dictionary(); @@ -26,7 +24,7 @@ internal void SetBody(MethodDef method) { if (this.method != method) { toOffset.Clear(); this.method = method; - this.body = method == null ? null : method.Body; + body = method?.Body; dictInitd = false; } } @@ -40,16 +38,13 @@ public uint GetOffset(Instruction instr) { } if (instr == null) return bodySize; - uint offset; - if (toOffset.TryGetValue(instr, out offset)) + if (toOffset.TryGetValue(instr, out uint offset)) return offset; helper.Error("Couldn't find an instruction, maybe it was removed. It's still being referenced by some code or by the PDB"); return bodySize; } - public bool IsSameMethod(MethodDef method) { - return this.method == method; - } + public bool IsSameMethod(MethodDef method) => this.method == method; void InitializeDict() { Debug.Assert(body != null); diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index cf4b4384b..c4e448e7e 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -67,33 +67,25 @@ internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig SignatureWriter(ISignatureWriterHelper helper) { this.helper = helper; - this.recursionCounter = new RecursionCounter(); - this.outStream = new MemoryStream(); - this.writer = new BinaryWriter(outStream); - this.disposeStream = true; + recursionCounter = new RecursionCounter(); + outStream = new MemoryStream(); + writer = new BinaryWriter(outStream); + disposeStream = true; } SignatureWriter(ISignatureWriterHelper helper, BinaryWriterContext context) { this.helper = helper; - this.recursionCounter = new RecursionCounter(); - this.outStream = context.OutStream; - this.writer = context.Writer; - this.disposeStream = false; + recursionCounter = new RecursionCounter(); + outStream = context.OutStream; + writer = context.Writer; + disposeStream = false; outStream.SetLength(0); outStream.Position = 0; } - byte[] GetResult() { - return outStream.ToArray(); - } - - uint WriteCompressedUInt32(uint value) { - return writer.WriteCompressedUInt32(helper, value); - } - - int WriteCompressedInt32(int value) { - return writer.WriteCompressedInt32(helper, value); - } + byte[] GetResult() => outStream.ToArray(); + uint WriteCompressedUInt32(uint value) => writer.WriteCompressedUInt32(helper, value); + int WriteCompressedInt32(int value) => writer.WriteCompressedInt32(helper, value); void Write(TypeSig typeSig) { const ElementType DEFAULT_ELEMENT_TYPE = ElementType.Boolean; diff --git a/src/DotNet/Writer/StartupStub.cs b/src/DotNet/Writer/StartupStub.cs index c1c627712..aca949da9 100644 --- a/src/DotNet/Writer/StartupStub.cs +++ b/src/DotNet/Writer/StartupStub.cs @@ -28,27 +28,18 @@ public sealed class StartupStub : IChunk { public PEHeaders PEHeaders { get; set; } /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Gets the address of the JMP instruction /// - public RVA EntryPointRVA { - get { return rva + (cpuArch == null ? 0 : cpuArch.GetStubCodeOffset(stubType)); } - } + public RVA EntryPointRVA => rva + (cpuArch == null ? 0 : cpuArch.GetStubCodeOffset(stubType)); internal bool Enable { get; set; } - - internal uint Alignment { - get { return cpuArch == null ? 1 : cpuArch.GetStubAlignment(stubType); } - } + internal uint Alignment => cpuArch == null ? 1 : cpuArch.GetStubAlignment(stubType); internal delegate void LogError(string format, params object[] args); @@ -91,9 +82,7 @@ public uint GetFileLength() { } /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index b3090428c..dac807e24 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -32,15 +32,11 @@ public StringsOffsetInfo(UTF8String value, uint stringsId) { public readonly UTF8String Value; public readonly uint StringsId; public uint StringsOffset; - public override string ToString() { - return string.Format("{0:X8} {1:X4} {2}", StringsId, StringsOffset, Value.String); - } + public override string ToString() => $"{StringsId:X8} {StringsOffset:X4} {Value.String}"; } /// - public override string Name { - get { return "#Strings"; } - } + public override string Name => "#Strings"; /// /// Populates strings from an existing (eg. to preserve @@ -142,11 +138,9 @@ public uint Add(UTF8String s) { if (UTF8String.IsNullOrEmpty(s)) return 0; - StringsOffsetInfo info; - if (toStringsOffsetInfo.TryGetValue(s, out info)) + if (toStringsOffsetInfo.TryGetValue(s, out var info)) return info.StringsId; - uint offset; - if (cachedDict.TryGetValue(s, out offset)) + if (cachedDict.TryGetValue(s, out uint offset)) return offset; if (Array.IndexOf(s.Data, (byte)0) >= 0) @@ -171,12 +165,11 @@ public uint GetOffset(uint offsetId) { throw new ModuleWriterException("This method can only be called after all strings have been added and this heap is read-only"); if ((offsetId & STRINGS_ID_FLAG) == 0) return offsetId; - StringsOffsetInfo info; - if (offsetIdToInfo.TryGetValue(offsetId, out info)) { + if (offsetIdToInfo.TryGetValue(offsetId, out var info)) { Debug.Assert(info.StringsOffset != 0); return info.StringsOffset; } - throw new ArgumentOutOfRangeException("offsetId"); + throw new ArgumentOutOfRangeException(nameof(offsetId)); } /// @@ -203,9 +196,7 @@ uint AddToCache(UTF8String s) { } /// - public override uint GetRawLength() { - return nextOffset; - } + public override uint GetRawLength() => nextOffset; /// protected override void WriteToImpl(BinaryWriter writer) { @@ -216,8 +207,7 @@ protected override void WriteToImpl(BinaryWriter writer) { uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { - byte[] rawData; - if (userRawData != null && userRawData.TryGetValue(offset, out rawData)) { + if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != s.Data.Length + 1) throw new InvalidOperationException("Invalid length of raw data"); writer.Write(rawData); @@ -231,17 +221,13 @@ protected override void WriteToImpl(BinaryWriter writer) { } /// - public int GetRawDataSize(UTF8String data) { - return data.Data.Length + 1; - } + public int GetRawDataSize(UTF8String data) => data.Data.Length + 1; /// public void SetRawData(uint offset, byte[] rawData) { - if (rawData == null) - throw new ArgumentNullException("rawData"); if (userRawData == null) userRawData = new Dictionary(); - userRawData[offset] = rawData; + userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); } /// diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index 048998068..c26e93cc8 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -14,22 +14,16 @@ public sealed class StrongNameSignature : IChunk { int size; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Constructor /// /// Size of strong name signature - public StrongNameSignature(int size) { - this.size = size; - } + public StrongNameSignature(int size) => this.size = size; /// public void SetOffset(FileOffset offset, RVA rva) { @@ -38,18 +32,12 @@ public void SetOffset(FileOffset offset, RVA rva) { } /// - public uint GetFileLength() { - return (uint)this.size; - } + public uint GetFileLength() => (uint)size; /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { - writer.WriteZeros(size); - } + public void WriteTo(BinaryWriter writer) => writer.WriteZeros(size); } } diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 089e6ef3d..bab75f80f 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -51,8 +51,8 @@ public sealed class TablesHeapOptions { /// Creates portable PDB v1.0 options /// /// - public static TablesHeapOptions CreatePortablePdbV1_0() { - return new TablesHeapOptions { + public static TablesHeapOptions CreatePortablePdbV1_0() => + new TablesHeapOptions { Reserved1 = 0, MajorVersion = 2, MinorVersion = 0, @@ -60,7 +60,6 @@ public static TablesHeapOptions CreatePortablePdbV1_0() { ExtraData = null, HasDeletedRows = null, }; - } } /// @@ -80,14 +79,10 @@ public sealed class TablesHeap : IHeap { RVA rva; /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; #pragma warning disable 1591 // XML doc comment public readonly MDTable ModuleTable = new MDTable(Table.Module, RawRowEqualityComparer.Instance); @@ -151,14 +146,10 @@ public RVA RVA { public readonly IMDTable[] Tables; /// - public string Name { - get { return IsENC ? "#-" : "#~"; } - } + public string Name => IsENC ? "#-" : "#~"; /// - public bool IsEmpty { - get { return false; } - } + public bool IsEmpty => false; /// /// true if the Edit 'N Continue name will be used (#-) @@ -197,32 +188,32 @@ public bool IsENC { /// Its name has been renamed to _Deleted). /// public bool HasDeletedRows { - get { return hasDeletedRows; } - set { hasDeletedRows = value; } + get => hasDeletedRows; + set => hasDeletedRows = value; } /// /// true if #Strings heap size > 0xFFFF /// public bool BigStrings { - get { return bigStrings; } - set { bigStrings = value; } + get => bigStrings; + set => bigStrings = value; } /// /// true if #GUID heap size > 0xFFFF /// public bool BigGuid { - get { return bigGuid; } - set { bigGuid = value; } + get => bigGuid; + set => bigGuid = value; } /// /// true if #Blob heap size > 0xFFFF /// public bool BigBlob { - get { return bigBlob; } - set { bigBlob = value; } + get => bigBlob; + set => bigBlob = value; } /// @@ -233,8 +224,8 @@ public bool BigBlob { public TablesHeap(MetaData metadata, TablesHeapOptions options) { this.metadata = metadata; this.options = options ?? new TablesHeapOptions(); - this.hasDeletedRows = this.options.HasDeletedRows ?? false; - this.Tables = new IMDTable[] { + hasDeletedRows = this.options.HasDeletedRows ?? false; + Tables = new IMDTable[] { ModuleTable, TypeRefTable, TypeDefTable, @@ -297,22 +288,12 @@ public TablesHeap(MetaData metadata, TablesHeapOptions options) { sealed class RawDummyRow : IRawRow { public static readonly IEqualityComparer Comparer = new RawDummyRowEqualityComparer(); sealed class RawDummyRowEqualityComparer : IEqualityComparer { - public bool Equals(RawDummyRow x, RawDummyRow y) { - throw new NotSupportedException(); - } - - public int GetHashCode(RawDummyRow obj) { - throw new NotSupportedException(); - } - } - - public uint Read(int index) { - throw new NotSupportedException(); + public bool Equals(RawDummyRow x, RawDummyRow y) => throw new NotSupportedException(); + public int GetHashCode(RawDummyRow obj) => throw new NotSupportedException(); } - public void Write(int index, uint value) { - throw new NotSupportedException(); - } + public uint Read(int index) => throw new NotSupportedException(); + public void Write(int index, uint value) => throw new NotSupportedException(); } /// @@ -335,9 +316,7 @@ public uint GetFileLength() { } /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// /// Calculates the length. This will set all MD tables to read-only. @@ -400,9 +379,7 @@ internal void GetSystemTableRows(out ulong mask, uint[] tables) { } } - internal void SetSystemTableRows(uint[] systemTables) { - this.systemTables = (uint[])systemTables.Clone(); - } + internal void SetSystemTableRows(uint[] systemTables) => this.systemTables = (uint[])systemTables.Clone(); uint[] systemTables; /// @@ -516,8 +493,6 @@ ulong GetSortedMask() { } /// - public override string ToString() { - return Name; - } + public override string ToString() => Name; } } diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index de200a5bc..c2c6d8a67 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -18,9 +18,7 @@ public sealed class USHeap : HeapBase, IOffsetHeap { Dictionary userRawData; /// - public override string Name { - get { return "#US"; } - } + public override string Name => "#US"; /// /// Populates strings from an existing (eg. to preserve @@ -47,8 +45,7 @@ void Populate(IImageStream reader) { reader.Position = 1; while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; - uint len; - if (!reader.ReadCompressedUInt32(out len)) { + if (!reader.ReadCompressedUInt32(out uint len)) { if (offset == reader.Position) reader.Position++; continue; @@ -81,8 +78,7 @@ public uint Add(string s) { if (s == null) s = string.Empty; - uint offset; - if (cachedDict.TryGetValue(s, out offset)) + if (cachedDict.TryGetValue(s, out uint offset)) return offset; return AddToCache(s); } @@ -109,9 +105,7 @@ uint AddToCache(string s) { } /// - public override uint GetRawLength() { - return nextOffset; - } + public override uint GetRawLength() => nextOffset; /// protected override void WriteToImpl(BinaryWriter writer) { @@ -123,8 +117,7 @@ protected override void WriteToImpl(BinaryWriter writer) { uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { int rawLen = GetRawDataSize(s); - byte[] rawData; - if (userRawData != null && userRawData.TryGetValue(offset, out rawData)) { + if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); writer.Write(rawData); @@ -148,17 +141,13 @@ void WriteString(BinaryWriter writer, string s) { } /// - public int GetRawDataSize(string data) { - return Utils.GetCompressedUInt32Length((uint)data.Length * 2 + 1) + data.Length * 2 + 1; - } + public int GetRawDataSize(string data) => Utils.GetCompressedUInt32Length((uint)data.Length * 2 + 1) + data.Length * 2 + 1; /// public void SetRawData(uint offset, byte[] rawData) { - if (rawData == null) - throw new ArgumentNullException("rawData"); if (userRawData == null) userRawData = new Dictionary(); - userRawData[offset] = rawData; + userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); } /// diff --git a/src/DotNet/Writer/UniqueChunkList.cs b/src/DotNet/Writer/UniqueChunkList.cs index cb6f32cc7..65b85daa6 100644 --- a/src/DotNet/Writer/UniqueChunkList.cs +++ b/src/DotNet/Writer/UniqueChunkList.cs @@ -25,8 +25,8 @@ public UniqueChunkList() /// /// Compares the chunk type public UniqueChunkList(IEqualityComparer chunkComparer) { - this.chunks = new List(); - this.dict = new Dictionary(new ElemEqualityComparer(chunkComparer)); + chunks = new List(); + dict = new Dictionary(new ElemEqualityComparer(chunkComparer)); } /// @@ -47,8 +47,7 @@ public T Add(T chunk, uint alignment) { if (chunk == null) return null; var elem = new Elem(chunk, alignment); - Elem other; - if (dict.TryGetValue(elem, out other)) + if (dict.TryGetValue(elem, out var other)) return other.chunk; dict[elem] = elem; chunks.Add(elem); diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 514c92e63..bae414afb 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -27,22 +27,16 @@ public sealed class Win32ResourcesChunk : IChunk { readonly List dataList = new List(); /// - public FileOffset FileOffset { - get { return offset; } - } + public FileOffset FileOffset => offset; /// - public RVA RVA { - get { return rva; } - } + public RVA RVA => rva; /// /// Constructor /// /// Win32 resources - public Win32ResourcesChunk(Win32Resources win32Resources) { - this.win32Resources = win32Resources; - } + public Win32ResourcesChunk(Win32Resources win32Resources) => this.win32Resources = win32Resources; /// /// Returns the and of a @@ -55,12 +49,10 @@ public Win32ResourcesChunk(Win32Resources win32Resources) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(ResourceDirectoryEntry dirEntry, out FileOffset fileOffset, out RVA rva) { - var dir = dirEntry as ResourceDirectory; - if (dir != null) + if (dirEntry is ResourceDirectory dir) return GetFileOffsetAndRvaOf(dir, out fileOffset, out rva); - var dataHeader = dirEntry as ResourceData; - if (dataHeader != null) + if (dirEntry is ResourceData dataHeader) return GetFileOffsetAndRvaOf(dataHeader, out fileOffset, out rva); fileOffset = 0; @@ -75,9 +67,7 @@ public bool GetFileOffsetAndRvaOf(ResourceDirectoryEntry dirEntry, out FileOffse /// A /// The file offset or 0 if is invalid public FileOffset GetFileOffset(ResourceDirectoryEntry dirEntry) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(dirEntry, out fileOffset, out rva); + GetFileOffsetAndRvaOf(dirEntry, out var fileOffset, out var rva); return fileOffset; } @@ -88,9 +78,7 @@ public FileOffset GetFileOffset(ResourceDirectoryEntry dirEntry) { /// A /// The RVA or 0 if is invalid public RVA GetRVA(ResourceDirectoryEntry dirEntry) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(dirEntry, out fileOffset, out rva); + GetFileOffsetAndRvaOf(dirEntry, out var fileOffset, out var rva); return rva; } @@ -105,8 +93,7 @@ public RVA GetRVA(ResourceDirectoryEntry dirEntry) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(ResourceDirectory dir, out FileOffset fileOffset, out RVA rva) { - uint offs; - if (dir == null || !dirDict.TryGetValue(dir, out offs)) { + if (dir == null || !dirDict.TryGetValue(dir, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -124,9 +111,7 @@ public bool GetFileOffsetAndRvaOf(ResourceDirectory dir, out FileOffset fileOffs /// A /// The file offset or 0 if is invalid public FileOffset GetFileOffset(ResourceDirectory dir) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(dir, out fileOffset, out rva); + GetFileOffsetAndRvaOf(dir, out var fileOffset, out var rva); return fileOffset; } @@ -137,9 +122,7 @@ public FileOffset GetFileOffset(ResourceDirectory dir) { /// A /// The RVA or 0 if is invalid public RVA GetRVA(ResourceDirectory dir) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(dir, out fileOffset, out rva); + GetFileOffsetAndRvaOf(dir, out var fileOffset, out var rva); return rva; } @@ -154,8 +137,7 @@ public RVA GetRVA(ResourceDirectory dir) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(ResourceData dataHeader, out FileOffset fileOffset, out RVA rva) { - uint offs; - if (dataHeader == null || !dataHeaderDict.TryGetValue(dataHeader, out offs)) { + if (dataHeader == null || !dataHeaderDict.TryGetValue(dataHeader, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -173,9 +155,7 @@ public bool GetFileOffsetAndRvaOf(ResourceData dataHeader, out FileOffset fileOf /// A /// The file offset or 0 if is invalid public FileOffset GetFileOffset(ResourceData dataHeader) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(dataHeader, out fileOffset, out rva); + GetFileOffsetAndRvaOf(dataHeader, out var fileOffset, out var rva); return fileOffset; } @@ -186,9 +166,7 @@ public FileOffset GetFileOffset(ResourceData dataHeader) { /// A /// The RVA or 0 if is invalid public RVA GetRVA(ResourceData dataHeader) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(dataHeader, out fileOffset, out rva); + GetFileOffsetAndRvaOf(dataHeader, out var fileOffset, out var rva); return rva; } @@ -203,8 +181,7 @@ public RVA GetRVA(ResourceData dataHeader) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(IBinaryReader data, out FileOffset fileOffset, out RVA rva) { - uint offs; - if (data == null || !dataDict.TryGetValue(data, out offs)) { + if (data == null || !dataDict.TryGetValue(data, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -222,9 +199,7 @@ public bool GetFileOffsetAndRvaOf(IBinaryReader data, out FileOffset fileOffset, /// A 's /// The file offset or 0 if is invalid public FileOffset GetFileOffset(IBinaryReader data) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(data, out fileOffset, out rva); + GetFileOffsetAndRvaOf(data, out var fileOffset, out var rva); return fileOffset; } @@ -235,9 +210,7 @@ public FileOffset GetFileOffset(IBinaryReader data) { /// A 's /// The RVA or 0 if is invalid public RVA GetRVA(IBinaryReader data) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(data, out fileOffset, out rva); + GetFileOffsetAndRvaOf(data, out var fileOffset, out var rva); return rva; } @@ -253,8 +226,7 @@ public RVA GetRVA(IBinaryReader data) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(string name, out FileOffset fileOffset, out RVA rva) { - uint offs; - if (name == null || !stringsDict.TryGetValue(name, out offs)) { + if (name == null || !stringsDict.TryGetValue(name, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -272,9 +244,7 @@ public bool GetFileOffsetAndRvaOf(string name, out FileOffset fileOffset, out RV /// The name of a /// The file offset or 0 if is invalid public FileOffset GetFileOffset(string name) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(name, out fileOffset, out rva); + GetFileOffsetAndRvaOf(name, out var fileOffset, out var rva); return fileOffset; } @@ -285,9 +255,7 @@ public FileOffset GetFileOffset(string name) { /// The name of a /// The RVA or 0 if is invalid public RVA GetRVA(string name) { - FileOffset fileOffset; - RVA rva; - GetFileOffsetAndRvaOf(name, out fileOffset, out rva); + GetFileOffsetAndRvaOf(name, out var fileOffset, out var rva); return rva; } @@ -319,7 +287,7 @@ public void SetOffset(FileOffset offset, RVA rva) { maxAlignment = Math.Max(maxAlignment, RESOURCE_STRING_ALIGNMENT); maxAlignment = Math.Max(maxAlignment, RESOURCE_DATA_ALIGNMENT); if (((uint)offset & (maxAlignment - 1)) != 0) - throw new ModuleWriterException(string.Format("Win32 resources section isn't {0}-byte aligned", maxAlignment)); + throw new ModuleWriterException($"Win32 resources section isn't {maxAlignment}-byte aligned"); if (maxAlignment > ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT) throw new ModuleWriterException("maxAlignment > DEFAULT_WIN32_RESOURCES_ALIGNMENT"); @@ -368,9 +336,7 @@ void AddString(ResourceName name) { stringsDict.Add(name.Name, 0); } - void FindDirectoryEntries() { - FindDirectoryEntries(win32Resources.Root); - } + void FindDirectoryEntries() => FindDirectoryEntries(win32Resources.Root); void FindDirectoryEntries(ResourceDirectory dir) { if (dirDict.ContainsKey(dir)) @@ -388,14 +354,10 @@ void FindDirectoryEntries(ResourceDirectory dir) { } /// - public uint GetFileLength() { - return Utils.AlignUp(length, ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT); - } + public uint GetFileLength() => Utils.AlignUp(length, ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT); /// - public uint GetVirtualSize() { - return GetFileLength(); - } + public uint GetVirtualSize() => GetFileLength(); /// public void WriteTo(BinaryWriter writer) { @@ -436,7 +398,7 @@ public void WriteTo(BinaryWriter writer) { offset += 2 + (uint)bytes.Length; } - byte[] dataBuffer = new byte[0x2000]; + var dataBuffer = new byte[0x2000]; foreach (var data in dataList) { uint padding = Utils.AlignUp(offset, RESOURCE_DATA_ALIGNMENT) - offset; writer.WriteZeros((int)padding); @@ -457,9 +419,7 @@ uint WriteTo(BinaryWriter writer, ResourceDirectory dir) { writer.Write(dir.MajorVersion); writer.Write(dir.MinorVersion); - List named; - List ids; - GetNamedAndIds(dir, out named, out ids); + GetNamedAndIds(dir, out var named, out var ids); if (named.Count > ushort.MaxValue || ids.Count > ushort.MaxValue) throw new ModuleWriterException("Too many named/id Win32 resource entries"); writer.Write((ushort)named.Count); diff --git a/src/IO/BinaryReaderStream.cs b/src/IO/BinaryReaderStream.cs index 0f6c55c3d..4a06ca510 100644 --- a/src/IO/BinaryReaderStream.cs +++ b/src/IO/BinaryReaderStream.cs @@ -31,39 +31,29 @@ public BinaryReaderStream(IBinaryReader reader, bool ownsReader) { } /// - public override bool CanRead { - get { return true; } - } + public override bool CanRead => true; /// - public override bool CanSeek { - get { return true; } - } + public override bool CanSeek => true; /// - public override bool CanWrite { - get { return false; } - } + public override bool CanWrite => false; /// public override void Flush() { } /// - public override long Length { - get { return reader.Length; } - } + public override long Length => reader.Length; /// public override long Position { - get { return reader.Position; } - set { reader.Position = value; } + get => reader.Position; + set => reader.Position = value; } /// - public override int Read(byte[] buffer, int offset, int count) { - return reader.Read(buffer, offset, count); - } + public override int Read(byte[] buffer, int offset, int count) => reader.Read(buffer, offset, count); /// public override int ReadByte() { @@ -86,14 +76,10 @@ public override long Seek(long offset, SeekOrigin origin) { } /// - public override void SetLength(long value) { - throw new NotImplementedException(); - } + public override void SetLength(long value) => throw new NotImplementedException(); /// - public override void Write(byte[] buffer, int offset, int count) { - throw new NotImplementedException(); - } + public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException(); /// protected override void Dispose(bool disposing) { diff --git a/src/IO/FileOffset.cs b/src/IO/FileOffset.cs index 25931cc1b..8e2b592a8 100644 --- a/src/IO/FileOffset.cs +++ b/src/IO/FileOffset.cs @@ -13,17 +13,13 @@ partial class IOExtensions { /// /// this /// Alignment - public static FileOffset AlignUp(this FileOffset offset, uint alignment) { - return (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); - } + public static FileOffset AlignUp(this FileOffset offset, uint alignment) => (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); /// /// Align up /// /// this /// Alignment - public static FileOffset AlignUp(this FileOffset offset, int alignment) { - return (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); - } + public static FileOffset AlignUp(this FileOffset offset, int alignment) => (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); } } diff --git a/src/IO/FileSection.cs b/src/IO/FileSection.cs index 1237f05fb..6230cca08 100644 --- a/src/IO/FileSection.cs +++ b/src/IO/FileSection.cs @@ -19,22 +19,17 @@ public class FileSection : IFileSection { protected uint size; /// - public FileOffset StartOffset { - get { return startOffset; } - } + public FileOffset StartOffset => startOffset; /// - public FileOffset EndOffset { - get { return startOffset + size; } - } + public FileOffset EndOffset => startOffset + size; /// /// Set to 's current position /// /// The reader - protected void SetStartOffset(IImageStream reader) { + protected void SetStartOffset(IImageStream reader) => startOffset = (FileOffset)reader.Position; - } /// /// Set according to 's current position diff --git a/src/IO/IBinaryReader.cs b/src/IO/IBinaryReader.cs index 14b2b21ca..a21a2f17c 100644 --- a/src/IO/IBinaryReader.cs +++ b/src/IO/IBinaryReader.cs @@ -335,9 +335,7 @@ public static byte[] ReadAllBytes(this IBinaryReader reader) { /// this /// The boolean /// An I/O error occurs - public static bool ReadBoolean(this IBinaryReader self) { - return self.ReadByte() != 0; - } + public static bool ReadBoolean(this IBinaryReader self) => self.ReadByte() != 0; /// /// Reads a from the current position and increments by 2 @@ -345,9 +343,7 @@ public static bool ReadBoolean(this IBinaryReader self) { /// this /// The char /// An I/O error occurs - public static char ReadChar(this IBinaryReader self) { - return self.ReadChar(Encoding.UTF8); - } + public static char ReadChar(this IBinaryReader self) => self.ReadChar(Encoding.UTF8); /// /// Reads a from the current position and increments by 2 @@ -360,8 +356,8 @@ public static char ReadChar(this IBinaryReader self, Encoding encoding) { // This is slow but this method should rarely be called... var decoder = encoding.GetDecoder(); bool twoBytes = encoding is UnicodeEncoding; - byte[] bytes = new byte[2]; - char[] chars = new char[1]; + var bytes = new byte[2]; + var chars = new char[1]; while (true) { bytes[0] = self.ReadByte(); if (twoBytes) @@ -379,9 +375,7 @@ public static char ReadChar(this IBinaryReader self, Encoding encoding) { /// /// this /// The string - public static string ReadString(this IBinaryReader reader) { - return reader.ReadString(Encoding.UTF8); - } + public static string ReadString(this IBinaryReader reader) => reader.ReadString(Encoding.UTF8); /// /// Reads a from the current position and increments @@ -527,8 +521,7 @@ public static bool ReadCompressedInt32(this IBinaryReader reader, out int val) { /// The reader /// The value public static uint ReadCompressedUInt32(this IBinaryReader reader) { - uint val; - if (!reader.ReadCompressedUInt32(out val)) + if (!reader.ReadCompressedUInt32(out uint val)) throw new IOException("Could not read a compressed UInt32"); return val; } @@ -539,8 +532,7 @@ public static uint ReadCompressedUInt32(this IBinaryReader reader) { /// The reader /// The value public static int ReadCompressedInt32(this IBinaryReader reader) { - int val; - if (!reader.ReadCompressedInt32(out val)) + if (!reader.ReadCompressedInt32(out int val)) throw new IOException("Could not read a compressed Int32"); return val; } @@ -568,9 +560,7 @@ public static uint Read7BitEncodedUInt32(this IBinaryReader reader) { /// /// this /// The decoded integer - public static int Read7BitEncodedInt32(this IBinaryReader reader) { - return (int)reader.Read7BitEncodedUInt32(); - } + public static int Read7BitEncodedInt32(this IBinaryReader reader) => (int)reader.Read7BitEncodedUInt32(); /// /// Creates a using . The created @@ -579,9 +569,7 @@ public static int Read7BitEncodedInt32(this IBinaryReader reader) { /// /// this /// A new instance - public static Stream CreateStream(this IBinaryReader reader) { - return new BinaryReaderStream(reader); - } + public static Stream CreateStream(this IBinaryReader reader) => new BinaryReaderStream(reader); /// /// Creates a using @@ -590,27 +578,21 @@ public static Stream CreateStream(this IBinaryReader reader) { /// true if the created owns /// /// A new instance - public static Stream CreateStream(this IBinaryReader reader, bool ownsReader) { - return new BinaryReaderStream(reader, ownsReader); - } + public static Stream CreateStream(this IBinaryReader reader, bool ownsReader) => new BinaryReaderStream(reader, ownsReader); /// /// Checks whether we can read bytes /// /// Reader /// Size in bytes - public static bool CanRead(this IBinaryReader reader, int size) { - return (reader.Position + size <= reader.Length && reader.Position + size >= reader.Position) || size == 0; - } + public static bool CanRead(this IBinaryReader reader, int size) => (reader.Position + size <= reader.Length && reader.Position + size >= reader.Position) || size == 0; /// /// Checks whether we can read bytes /// /// Reader /// Size in bytes - public static bool CanRead(this IBinaryReader reader, uint size) { - return (reader.Position + size <= reader.Length && reader.Position + size >= reader.Position) || size == 0; - } + public static bool CanRead(this IBinaryReader reader, uint size) => (reader.Position + size <= reader.Length && reader.Position + size >= reader.Position) || size == 0; /// /// Writes , starting at 's current diff --git a/src/IO/IImageStream.cs b/src/IO/IImageStream.cs index 8cd43d7ae..beac2f319 100644 --- a/src/IO/IImageStream.cs +++ b/src/IO/IImageStream.cs @@ -26,17 +26,13 @@ static partial class IOExtensions { /// this /// Offset relative to the beginning of the stream /// A new stream - public static IImageStream Create(this IImageStream self, FileOffset offset) { - return self.Create(offset, long.MaxValue); - } + public static IImageStream Create(this IImageStream self, FileOffset offset) => self.Create(offset, long.MaxValue); /// /// Clones this /// /// this /// A new instance - public static IImageStream Clone(this IImageStream self) { - return self.Create(0, long.MaxValue); - } + public static IImageStream Clone(this IImageStream self) => self.Create(0, long.MaxValue); } } diff --git a/src/IO/IImageStreamCreator.cs b/src/IO/IImageStreamCreator.cs index 6e344acf6..c08826bce 100644 --- a/src/IO/IImageStreamCreator.cs +++ b/src/IO/IImageStreamCreator.cs @@ -39,8 +39,6 @@ static partial class IOExtensions { /// this /// Offset within the original data /// A new stream - public static IImageStream Create(this IImageStreamCreator self, FileOffset offset) { - return self.Create(offset, long.MaxValue); - } + public static IImageStream Create(this IImageStreamCreator self, FileOffset offset) => self.Create(offset, long.MaxValue); } } diff --git a/src/IO/ImageStreamCreator.cs b/src/IO/ImageStreamCreator.cs index 882425587..c0618693d 100644 --- a/src/IO/ImageStreamCreator.cs +++ b/src/IO/ImageStreamCreator.cs @@ -24,9 +24,7 @@ static ImageStreamCreator() { /// /// Filename /// A new instance - public static IImageStreamCreator Create(string fileName) { - return Create(fileName, false); - } + public static IImageStreamCreator Create(string fileName) => Create(fileName, false); /// /// Creates a . It will be a @@ -57,9 +55,7 @@ static MemoryMappedFileStreamCreator CreateMemoryMappedFileStreamCreator(string /// /// Filename /// A new instance - public static IImageStream CreateImageStream(string fileName) { - return CreateImageStream(fileName, false); - } + public static IImageStream CreateImageStream(string fileName) => CreateImageStream(fileName, false); /// /// Creates a diff --git a/src/IO/MemoryImageStream.cs b/src/IO/MemoryImageStream.cs index 192269610..d1a0ad967 100644 --- a/src/IO/MemoryImageStream.cs +++ b/src/IO/MemoryImageStream.cs @@ -21,9 +21,7 @@ public sealed class MemoryImageStream : IImageStream { /// /// Data /// A new instance - public static MemoryImageStream Create(byte[] data) { - return new MemoryImageStream(0, data, 0, data.Length); - } + public static MemoryImageStream Create(byte[] data) => new MemoryImageStream(0, data, 0, data.Length); /// /// Creates a new instance @@ -32,9 +30,7 @@ public static MemoryImageStream Create(byte[] data) { /// Start offset in /// Length of data /// A new instance - public static MemoryImageStream Create(byte[] data, int offset, int len) { - return new MemoryImageStream(0, data, offset, len); - } + public static MemoryImageStream Create(byte[] data, int offset, int len) => new MemoryImageStream(0, data, offset, len); /// /// Constructor @@ -47,37 +43,29 @@ public MemoryImageStream(FileOffset fileOffset, byte[] data, int dataOffset, int this.fileOffset = fileOffset; this.data = data; this.dataOffset = dataOffset; - this.dataEnd = dataOffset + dataLength; - this.position = dataOffset; + dataEnd = dataOffset + dataLength; + position = dataOffset; } /// /// Gets the data /// - internal byte[] DataArray { - get { return data; } - } + internal byte[] DataArray => data; /// /// Gets the start of the data in used by this stream /// - internal int DataOffset { - get { return dataOffset; } - } + internal int DataOffset => dataOffset; /// - public FileOffset FileOffset { - get { return fileOffset; } - } + public FileOffset FileOffset => fileOffset; /// - public long Length { - get { return dataEnd - dataOffset; } - } + public long Length => dataEnd - dataOffset; /// public long Position { - get { return position - dataOffset; } + get => position - dataOffset; set { long newPos = dataOffset + value; if (newPos < dataOffset || newPos > int.MaxValue) @@ -89,9 +77,7 @@ public long Position { /// /// Creates an empty instance /// - public static MemoryImageStream CreateEmpty() { - return new MemoryImageStream(0, new byte[0], 0, 0); - } + public static MemoryImageStream CreateEmpty() => new MemoryImageStream(0, new byte[0], 0, 0); /// public IImageStream Create(FileOffset offset, long length) { diff --git a/src/IO/MemoryMappedFileStreamCreator.cs b/src/IO/MemoryMappedFileStreamCreator.cs index 5b77b368d..74e7e4451 100644 --- a/src/IO/MemoryMappedFileStreamCreator.cs +++ b/src/IO/MemoryMappedFileStreamCreator.cs @@ -73,21 +73,20 @@ static class Windows { public static void Mmap(MemoryMappedFileStreamCreator creator, bool mapAsImage) { using (var fileHandle = CreateFile(creator.theFileName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)) { if (fileHandle.IsInvalid) - throw new IOException(string.Format("Could not open file {0} for reading. Error: {1:X8}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new IOException($"Could not open file {creator.theFileName} for reading. Error: {Marshal.GetLastWin32Error():X8}"); - uint sizeHi; - uint sizeLo = GetFileSize(fileHandle, out sizeHi); + uint sizeLo = GetFileSize(fileHandle, out uint sizeHi); int hr; if (sizeLo == INVALID_FILE_SIZE && (hr = Marshal.GetLastWin32Error()) != NO_ERROR) - throw new IOException(string.Format("Could not get file size. File: {0}, error: {1:X8}", creator.theFileName, hr)); + throw new IOException($"Could not get file size. File: {creator.theFileName}, error: {hr:X8}"); var fileSize = ((long)sizeHi << 32) | sizeLo; using (var fileMapping = CreateFileMapping(fileHandle, IntPtr.Zero, PAGE_READONLY | (mapAsImage ? SEC_IMAGE : 0), 0, 0, null)) { if (fileMapping.IsInvalid) - throw new MemoryMappedIONotSupportedException(string.Format("Could not create a file mapping object. File: {0}, error: {1:X8}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new MemoryMappedIONotSupportedException($"Could not create a file mapping object. File: {creator.theFileName}, error: {Marshal.GetLastWin32Error():X8}"); creator.data = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, UIntPtr.Zero); if (creator.data == IntPtr.Zero) - throw new MemoryMappedIONotSupportedException(string.Format("Could not map file {0}. Error: {1:X8}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new MemoryMappedIONotSupportedException($"Could not map file {creator.theFileName}. Error: {Marshal.GetLastWin32Error():X8}"); creator.dataLength = fileSize; creator.osType = OSType.Windows; } @@ -130,7 +129,7 @@ public static void Mmap(MemoryMappedFileStreamCreator creator, bool mapAsImage) int fd = open(creator.theFileName, O_RDONLY); try { if (fd < 0) - throw new IOException(string.Format("Could not open file {0} for reading. Error: {1}", creator.theFileName, fd)); + throw new IOException($"Could not open file {creator.theFileName} for reading. Error: {fd}"); long size; IntPtr data; @@ -138,20 +137,20 @@ public static void Mmap(MemoryMappedFileStreamCreator creator, bool mapAsImage) if (IntPtr.Size == 4) { size = lseek32(fd, 0, SEEK_END); if (size == -1) - throw new MemoryMappedIONotSupportedException(string.Format("Could not get length of {0} (lseek failed): {1}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new MemoryMappedIONotSupportedException($"Could not get length of {creator.theFileName} (lseek failed): {Marshal.GetLastWin32Error()}"); data = mmap32(IntPtr.Zero, (IntPtr)size, PROT_READ, MAP_PRIVATE, fd, 0); if (data == new IntPtr(-1) || data == IntPtr.Zero) - throw new MemoryMappedIONotSupportedException(string.Format("Could not map file {0}. Error: {1}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new MemoryMappedIONotSupportedException($"Could not map file {creator.theFileName}. Error: {Marshal.GetLastWin32Error()}"); } else { size = lseek64(fd, 0, SEEK_END); if (size == -1) - throw new MemoryMappedIONotSupportedException(string.Format("Could not get length of {0} (lseek failed): {1}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new MemoryMappedIONotSupportedException($"Could not get length of {creator.theFileName} (lseek failed): {Marshal.GetLastWin32Error()}"); data = mmap64(IntPtr.Zero, (IntPtr)size, PROT_READ, MAP_PRIVATE, fd, 0); if (data == new IntPtr(-1) || data == IntPtr.Zero) - throw new MemoryMappedIONotSupportedException(string.Format("Could not map file {0}. Error: {1}", creator.theFileName, Marshal.GetLastWin32Error())); + throw new MemoryMappedIONotSupportedException($"Could not map file {creator.theFileName}. Error: {Marshal.GetLastWin32Error()}"); } creator.data = data; @@ -229,7 +228,7 @@ internal static MemoryMappedFileStreamCreator CreateUnix(string fileName, bool m return creator; } catch (MemoryMappedIONotSupportedException ex) { - Debug.WriteLine(string.Format("mmap'd IO didn't work: {0}", ex.Message)); + Debug.WriteLine($"mmap'd IO didn't work: {ex.Message}"); } catch (EntryPointNotFoundException) { } @@ -262,9 +261,7 @@ protected override void Dispose(bool disposing) { /// /// true if memory mapped I/O is enabled /// - public bool IsMemoryMappedIO { - get { return dataAry == null; } - } + public bool IsMemoryMappedIO => dataAry == null; /// /// Call this to disable memory mapped I/O. This must only be called if no other code is @@ -281,7 +278,7 @@ public void UnsafeDisableMemoryMappedIO() { dataLength = newAry.Length; dataAry = newAry; gcHandle = GCHandle.Alloc(dataAry, GCHandleType.Pinned); - this.data = gcHandle.AddrOfPinnedObject(); + data = gcHandle.AddrOfPinnedObject(); } GCHandle gcHandle; byte[] dataAry; diff --git a/src/IO/MemoryStreamCreator.cs b/src/IO/MemoryStreamCreator.cs index 0fd2750eb..3d40f4f56 100644 --- a/src/IO/MemoryStreamCreator.cs +++ b/src/IO/MemoryStreamCreator.cs @@ -20,14 +20,12 @@ sealed class MemoryStreamCreator : IImageStreamCreator { /// The file name /// public string FileName { - get { return theFileName; } - set { theFileName = value; } + get => theFileName; + set => theFileName = value; } /// - public long Length { - get { return dataLength; } - } + public long Length => dataLength; /// /// Constructor @@ -46,14 +44,14 @@ public MemoryStreamCreator(byte[] data) /// If one of the args is invalid public MemoryStreamCreator(byte[] data, int offset, int length) { if (offset < 0) - throw new ArgumentOutOfRangeException("offset"); + throw new ArgumentOutOfRangeException(nameof(offset)); if (length < 0 || offset + length < offset) - throw new ArgumentOutOfRangeException("length"); + throw new ArgumentOutOfRangeException(nameof(length)); if (offset + length > data.Length) - throw new ArgumentOutOfRangeException("length"); + throw new ArgumentOutOfRangeException(nameof(length)); this.data = data; - this.dataOffset = offset; - this.dataLength = length; + dataOffset = offset; + dataLength = length; } /// @@ -67,9 +65,7 @@ public IImageStream Create(FileOffset offset, long length) { } /// - public IImageStream CreateFull() { - return new MemoryImageStream(0, data, dataOffset, dataLength); - } + public IImageStream CreateFull() => new MemoryImageStream(0, data, dataOffset, dataLength); /// public void Dispose() { diff --git a/src/IO/UnmanagedMemoryImageStream.cs b/src/IO/UnmanagedMemoryImageStream.cs index 4b62cd901..8c2000c60 100644 --- a/src/IO/UnmanagedMemoryImageStream.cs +++ b/src/IO/UnmanagedMemoryImageStream.cs @@ -27,9 +27,9 @@ sealed unsafe class UnmanagedMemoryImageStream : IImageStream { /// Length of data public unsafe UnmanagedMemoryImageStream(UnmanagedMemoryStreamCreator owner, FileOffset fileOffset, long baseAddr, long length) { this.fileOffset = fileOffset; - this.startAddr = baseAddr; - this.endAddr = baseAddr + length; - this.currentAddr = this.startAddr; + startAddr = baseAddr; + endAddr = baseAddr + length; + currentAddr = startAddr; this.owner = owner; } @@ -38,30 +38,22 @@ public unsafe UnmanagedMemoryImageStream(UnmanagedMemoryStreamCreator owner, Fil /// /// A instance internal UnmanagedMemoryImageStream(UnmanagedMemoryStreamCreator creator) - : this(creator, 0, 0, creator.Length) { - this.ownOwner = true; - } + : this(creator, 0, 0, creator.Length) => ownOwner = true; /// - public FileOffset FileOffset { - get { return fileOffset; } - } + public FileOffset FileOffset => fileOffset; /// /// Gets the start address of the memory this instance uses /// - internal unsafe IntPtr StartAddress { - get { return new IntPtr((byte*)owner.UnsafeUseAddress + startAddr); } - } + internal unsafe IntPtr StartAddress => new IntPtr((byte*)owner.UnsafeUseAddress + startAddr); /// - public unsafe long Length { - get { return endAddr - startAddr; } - } + public unsafe long Length => endAddr - startAddr; /// public unsafe long Position { - get { return currentAddr - startAddr; } + get => currentAddr - startAddr; set { if (IntPtr.Size == 4 && (ulong)value > int.MaxValue) value = int.MaxValue; diff --git a/src/IO/UnmanagedMemoryStreamCreator.cs b/src/IO/UnmanagedMemoryStreamCreator.cs index e0edee2a2..7175f39e9 100644 --- a/src/IO/UnmanagedMemoryStreamCreator.cs +++ b/src/IO/UnmanagedMemoryStreamCreator.cs @@ -31,24 +31,22 @@ class UnmanagedMemoryStreamCreator : IImageStreamCreator { /// The file name /// public string FileName { - get { return theFileName; } - set { theFileName = value; } + get => theFileName; + set => theFileName = value; } /// /// Size of the data /// public long Length { - get { return dataLength; } - set { dataLength = value; } + get => dataLength; + set => dataLength = value; } /// /// Returns the base address of the data /// - public IntPtr Address { - get { return data; } - } + public IntPtr Address => data; public IntPtr UnsafeUseAddress { get { @@ -80,7 +78,7 @@ public UnmanagedMemoryStreamCreator(IntPtr data) /// If one of the args is invalid public UnmanagedMemoryStreamCreator(IntPtr data, long dataLength) { if (dataLength < 0) - throw new ArgumentOutOfRangeException("dataLength"); + throw new ArgumentOutOfRangeException(nameof(dataLength)); this.data = data; this.dataLength = dataLength; } @@ -96,9 +94,7 @@ public unsafe IImageStream Create(FileOffset offset, long length) { } /// - public IImageStream CreateFull() { - return new UnmanagedMemoryImageStream(this, 0, 0, dataLength); - } + public IImageStream CreateFull() => new UnmanagedMemoryImageStream(this, 0, 0, dataLength); /// public void Dispose() { diff --git a/src/PE/IPEImage.cs b/src/PE/IPEImage.cs index 74dcbbc23..c3f3e5171 100644 --- a/src/PE/IPEImage.cs +++ b/src/PE/IPEImage.cs @@ -118,9 +118,7 @@ public static partial class PEExtensions { /// RVA /// A new stream /// If the arg is invalid - public static IImageStream CreateStream(this IPEImage self, RVA rva) { - return self.CreateStream(self.ToFileOffset(rva)); - } + public static IImageStream CreateStream(this IPEImage self, RVA rva) => self.CreateStream(self.ToFileOffset(rva)); /// /// Creates a stream to access part of the PE image from @@ -131,9 +129,7 @@ public static IImageStream CreateStream(this IPEImage self, RVA rva) { /// Length of data /// A new stream /// If any arg is invalid - public static IImageStream CreateStream(this IPEImage self, RVA rva, long length) { - return self.CreateStream(self.ToFileOffset(rva), length); - } + public static IImageStream CreateStream(this IPEImage self, RVA rva, long length) => self.CreateStream(self.ToFileOffset(rva), length); /// /// Reads all bytes from the PE image. This may fail if the PE image has been loaded @@ -154,9 +150,7 @@ public static byte[] GetImageAsByteArray(this IPEImage self) { /// Name /// Language ID /// The or null if none found - public static ResourceData FindWin32ResourceData(this IPEImage self, ResourceName type, ResourceName name, ResourceName langId) { - var w32Resources = self.Win32Resources; - return w32Resources == null ? null : w32Resources.Find(type, name, langId); - } + public static ResourceData FindWin32ResourceData(this IPEImage self, ResourceName type, ResourceName name, ResourceName langId) => + self.Win32Resources?.Find(type, name, langId); } } diff --git a/src/PE/ImageDataDirectory.cs b/src/PE/ImageDataDirectory.cs index 27c0f6f12..b7dd3dc8c 100644 --- a/src/PE/ImageDataDirectory.cs +++ b/src/PE/ImageDataDirectory.cs @@ -16,16 +16,12 @@ public sealed class ImageDataDirectory : FileSection { /// /// Returns the IMAGE_DATA_DIRECTORY.VirtualAddress field /// - public RVA VirtualAddress { - get { return virtualAddress; } - } + public RVA VirtualAddress => virtualAddress; /// /// Returns the IMAGE_DATA_DIRECTORY.Size field /// - public uint Size { - get { return dataSize; } - } + public uint Size => dataSize; /// /// Default constructor @@ -41,8 +37,8 @@ public ImageDataDirectory() { /// Thrown if verification fails public ImageDataDirectory(IImageStream reader, bool verify) { SetStartOffset(reader); - this.virtualAddress = (RVA)reader.ReadUInt32(); - this.dataSize = reader.ReadUInt32(); + virtualAddress = (RVA)reader.ReadUInt32(); + dataSize = reader.ReadUInt32(); SetEndoffset(reader); } } diff --git a/src/PE/ImageDebugDirectory.cs b/src/PE/ImageDebugDirectory.cs index 4a8eda053..3810867a8 100644 --- a/src/PE/ImageDebugDirectory.cs +++ b/src/PE/ImageDebugDirectory.cs @@ -22,58 +22,42 @@ public sealed class ImageDebugDirectory : FileSection { /// /// Gets the characteristics (reserved) /// - public uint Characteristics { - get { return characteristics; } - } + public uint Characteristics => characteristics; /// /// Gets the timestamp /// - public uint TimeDateStamp { - get { return timeDateStamp; } - } + public uint TimeDateStamp => timeDateStamp; /// /// Gets the major version /// - public ushort MajorVersion { - get { return majorVersion; } - } + public ushort MajorVersion => majorVersion; /// /// Gets the minor version /// - public ushort MinorVersion { - get { return minorVersion; } - } + public ushort MinorVersion => minorVersion; /// /// Gets the type /// - public ImageDebugType Type { - get { return type; } - } + public ImageDebugType Type => type; /// /// Gets the size of data /// - public uint SizeOfData { - get { return sizeOfData; } - } + public uint SizeOfData => sizeOfData; /// /// RVA of the data /// - public RVA AddressOfRawData { - get { return (RVA)addressOfRawData; } - } + public RVA AddressOfRawData => (RVA)addressOfRawData; /// /// File offset of the data /// - public FileOffset PointerToRawData { - get { return (FileOffset)pointerToRawData; } - } + public FileOffset PointerToRawData => (FileOffset)pointerToRawData; /// /// Constructor diff --git a/src/PE/ImageDosHeader.cs b/src/PE/ImageDosHeader.cs index 467275fd7..c94444aab 100644 --- a/src/PE/ImageDosHeader.cs +++ b/src/PE/ImageDosHeader.cs @@ -13,9 +13,7 @@ public sealed class ImageDosHeader : FileSection { /// /// File offset of the NT headers /// - public uint NTHeadersOffset { - get { return ntHeadersOffset; } - } + public uint NTHeadersOffset => ntHeadersOffset; /// /// Constructor @@ -29,7 +27,7 @@ public ImageDosHeader(IImageStream reader, bool verify) { if (verify && sig != 0x5A4D) throw new BadImageFormatException("Invalid DOS signature"); reader.Position = (long)startOffset + 0x3C; - this.ntHeadersOffset = reader.ReadUInt32(); + ntHeadersOffset = reader.ReadUInt32(); SetEndoffset(reader); } } diff --git a/src/PE/ImageFileHeader.cs b/src/PE/ImageFileHeader.cs index e3cc14e81..146617836 100644 --- a/src/PE/ImageFileHeader.cs +++ b/src/PE/ImageFileHeader.cs @@ -19,51 +19,37 @@ public sealed class ImageFileHeader : FileSection { /// /// Returns the IMAGE_FILE_HEADER.Machine field /// - public Machine Machine { - get { return machine; } - } + public Machine Machine => machine; /// /// Returns the IMAGE_FILE_HEADER.NumberOfSections field /// - public int NumberOfSections { - get { return numberOfSections; } - } + public int NumberOfSections => numberOfSections; /// /// Returns the IMAGE_FILE_HEADER.TimeDateStamp field /// - public uint TimeDateStamp { - get { return timeDateStamp; } - } + public uint TimeDateStamp => timeDateStamp; /// /// Returns the IMAGE_FILE_HEADER.PointerToSymbolTable field /// - public uint PointerToSymbolTable { - get { return pointerToSymbolTable; } - } + public uint PointerToSymbolTable => pointerToSymbolTable; /// /// Returns the IMAGE_FILE_HEADER.NumberOfSymbols field /// - public uint NumberOfSymbols { - get { return numberOfSymbols; } - } + public uint NumberOfSymbols => numberOfSymbols; /// /// Returns the IMAGE_FILE_HEADER.SizeOfOptionalHeader field /// - public uint SizeOfOptionalHeader { - get { return sizeOfOptionalHeader; } - } + public uint SizeOfOptionalHeader => sizeOfOptionalHeader; /// /// Returns the IMAGE_FILE_HEADER.Characteristics field /// - public Characteristics Characteristics { - get { return characteristics; } - } + public Characteristics Characteristics => characteristics; /// /// Constructor @@ -73,15 +59,15 @@ public Characteristics Characteristics { /// Thrown if verification fails public ImageFileHeader(IImageStream reader, bool verify) { SetStartOffset(reader); - this.machine = (Machine)reader.ReadUInt16(); - this.numberOfSections = reader.ReadUInt16(); - this.timeDateStamp = reader.ReadUInt32(); - this.pointerToSymbolTable = reader.ReadUInt32(); - this.numberOfSymbols = reader.ReadUInt32(); - this.sizeOfOptionalHeader = reader.ReadUInt16(); - this.characteristics = (Characteristics)reader.ReadUInt16(); + machine = (Machine)reader.ReadUInt16(); + numberOfSections = reader.ReadUInt16(); + timeDateStamp = reader.ReadUInt32(); + pointerToSymbolTable = reader.ReadUInt32(); + numberOfSymbols = reader.ReadUInt32(); + sizeOfOptionalHeader = reader.ReadUInt16(); + characteristics = (Characteristics)reader.ReadUInt16(); SetEndoffset(reader); - if (verify && this.sizeOfOptionalHeader == 0) + if (verify && sizeOfOptionalHeader == 0) throw new BadImageFormatException("Invalid SizeOfOptionalHeader"); } } diff --git a/src/PE/ImageNTHeaders.cs b/src/PE/ImageNTHeaders.cs index 9e1b941ee..63dfd721e 100644 --- a/src/PE/ImageNTHeaders.cs +++ b/src/PE/ImageNTHeaders.cs @@ -15,23 +15,17 @@ public sealed class ImageNTHeaders : FileSection { /// /// Returns the IMAGE_NT_HEADERS.Signature field /// - public uint Signature { - get { return signature; } - } + public uint Signature => signature; /// /// Returns the IMAGE_NT_HEADERS.FileHeader field /// - public ImageFileHeader FileHeader { - get { return imageFileHeader; } - } + public ImageFileHeader FileHeader => imageFileHeader; /// /// Returns the IMAGE_NT_HEADERS.OptionalHeader field /// - public IImageOptionalHeader OptionalHeader { - get { return imageOptionalHeader; } - } + public IImageOptionalHeader OptionalHeader => imageOptionalHeader; /// /// Constructor @@ -41,11 +35,11 @@ public IImageOptionalHeader OptionalHeader { /// Thrown if verification fails public ImageNTHeaders(IImageStream reader, bool verify) { SetStartOffset(reader); - this.signature = reader.ReadUInt32(); - if (verify && this.signature != 0x4550) + signature = reader.ReadUInt32(); + if (verify && signature != 0x4550) throw new BadImageFormatException("Invalid NT headers signature"); - this.imageFileHeader = new ImageFileHeader(reader, verify); - this.imageOptionalHeader = CreateImageOptionalHeader(reader, verify); + imageFileHeader = new ImageFileHeader(reader, verify); + imageOptionalHeader = CreateImageOptionalHeader(reader, verify); SetEndoffset(reader); } diff --git a/src/PE/ImageOptionalHeader32.cs b/src/PE/ImageOptionalHeader32.cs index 6ea7ecb0c..bcb2aabe0 100644 --- a/src/PE/ImageOptionalHeader32.cs +++ b/src/PE/ImageOptionalHeader32.cs @@ -43,219 +43,157 @@ public sealed class ImageOptionalHeader32 : FileSection, IImageOptionalHeader { /// /// Returns the IMAGE_OPTIONAL_HEADER.Magic field /// - public ushort Magic { - get { return magic; } - } + public ushort Magic => magic; /// /// Returns the IMAGE_OPTIONAL_HEADER.MajorLinkerVersion field /// - public byte MajorLinkerVersion { - get { return majorLinkerVersion; } - } + public byte MajorLinkerVersion => majorLinkerVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.MinorLinkerVersion field /// - public byte MinorLinkerVersion { - get { return minorLinkerVersion; } - } + public byte MinorLinkerVersion => minorLinkerVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfCode field /// - public uint SizeOfCode { - get { return sizeOfCode; } - } + public uint SizeOfCode => sizeOfCode; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfInitializedData field /// - public uint SizeOfInitializedData { - get { return sizeOfInitializedData; } - } + public uint SizeOfInitializedData => sizeOfInitializedData; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfUninitializedData field /// - public uint SizeOfUninitializedData { - get { return sizeOfUninitializedData; } - } + public uint SizeOfUninitializedData => sizeOfUninitializedData; /// /// Returns the IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint field /// - public RVA AddressOfEntryPoint { - get { return addressOfEntryPoint; } - } + public RVA AddressOfEntryPoint => addressOfEntryPoint; /// /// Returns the IMAGE_OPTIONAL_HEADER.BaseOfCode field /// - public RVA BaseOfCode { - get { return baseOfCode; } - } + public RVA BaseOfCode => baseOfCode; /// /// Returns the IMAGE_OPTIONAL_HEADER.BaseOfData field /// - public RVA BaseOfData { - get { return baseOfData; } - } + public RVA BaseOfData => baseOfData; /// /// Returns the IMAGE_OPTIONAL_HEADER.ImageBase field /// - public ulong ImageBase { - get { return imageBase; } - } + public ulong ImageBase => imageBase; /// /// Returns the IMAGE_OPTIONAL_HEADER.SectionAlignment field /// - public uint SectionAlignment { - get { return sectionAlignment; } - } + public uint SectionAlignment => sectionAlignment; /// /// Returns the IMAGE_OPTIONAL_HEADER.FileAlignment field /// - public uint FileAlignment { - get { return fileAlignment; } - } + public uint FileAlignment => fileAlignment; /// /// Returns the IMAGE_OPTIONAL_HEADER.MajorOperatingSystemVersion field /// - public ushort MajorOperatingSystemVersion { - get { return majorOperatingSystemVersion; } - } + public ushort MajorOperatingSystemVersion => majorOperatingSystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.MinorOperatingSystemVersion field /// - public ushort MinorOperatingSystemVersion { - get { return minorOperatingSystemVersion; } - } + public ushort MinorOperatingSystemVersion => minorOperatingSystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.MajorImageVersion field /// - public ushort MajorImageVersion { - get { return majorImageVersion; } - } + public ushort MajorImageVersion => majorImageVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.MinorImageVersion field /// - public ushort MinorImageVersion { - get { return minorImageVersion; } - } + public ushort MinorImageVersion => minorImageVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.MajorSubsystemVersion field /// - public ushort MajorSubsystemVersion { - get { return majorSubsystemVersion; } - } + public ushort MajorSubsystemVersion => majorSubsystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.MinorSubsystemVersion field /// - public ushort MinorSubsystemVersion { - get { return minorSubsystemVersion; } - } + public ushort MinorSubsystemVersion => minorSubsystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER.Win32VersionValue field /// - public uint Win32VersionValue { - get { return win32VersionValue; } - } + public uint Win32VersionValue => win32VersionValue; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfImage field /// - public uint SizeOfImage { - get { return sizeOfImage; } - } + public uint SizeOfImage => sizeOfImage; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeaders field /// - public uint SizeOfHeaders { - get { return sizeOfHeaders; } - } + public uint SizeOfHeaders => sizeOfHeaders; /// /// Returns the IMAGE_OPTIONAL_HEADER.CheckSum field /// - public uint CheckSum { - get { return checkSum; } - } + public uint CheckSum => checkSum; /// /// Returns the IMAGE_OPTIONAL_HEADER.Subsystem field /// - public Subsystem Subsystem { - get { return subsystem; } - } + public Subsystem Subsystem => subsystem; /// /// Returns the IMAGE_OPTIONAL_HEADER.DllCharacteristics field /// - public DllCharacteristics DllCharacteristics { - get { return dllCharacteristics; } - } + public DllCharacteristics DllCharacteristics => dllCharacteristics; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfStackReserve field /// - public ulong SizeOfStackReserve { - get { return sizeOfStackReserve; } - } + public ulong SizeOfStackReserve => sizeOfStackReserve; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfStackCommit field /// - public ulong SizeOfStackCommit { - get { return sizeOfStackCommit; } - } + public ulong SizeOfStackCommit => sizeOfStackCommit; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeapReserve field /// - public ulong SizeOfHeapReserve { - get { return sizeOfHeapReserve; } - } + public ulong SizeOfHeapReserve => sizeOfHeapReserve; /// /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeapCommit field /// - public ulong SizeOfHeapCommit { - get { return sizeOfHeapCommit; } - } + public ulong SizeOfHeapCommit => sizeOfHeapCommit; /// /// Returns the IMAGE_OPTIONAL_HEADER.LoaderFlags field /// - public uint LoaderFlags { - get { return loaderFlags; } - } + public uint LoaderFlags => loaderFlags; /// /// Returns the IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes field /// - public uint NumberOfRvaAndSizes { - get { return numberOfRvaAndSizes; } - } + public uint NumberOfRvaAndSizes => numberOfRvaAndSizes; /// /// Returns the IMAGE_OPTIONAL_HEADER.DataDirectories field /// - public ImageDataDirectory[] DataDirectories { - get { return dataDirectories; } - } + public ImageDataDirectory[] DataDirectories => dataDirectories; /// /// Constructor @@ -270,36 +208,36 @@ public ImageOptionalHeader32(IImageStream reader, uint totalSize, bool verify) { if (verify && reader.Position + totalSize > reader.Length) throw new BadImageFormatException("Invalid optional header size"); SetStartOffset(reader); - this.magic = reader.ReadUInt16(); - this.majorLinkerVersion = reader.ReadByte(); - this.minorLinkerVersion = reader.ReadByte(); - this.sizeOfCode = reader.ReadUInt32(); - this.sizeOfInitializedData = reader.ReadUInt32(); - this.sizeOfUninitializedData = reader.ReadUInt32(); - this.addressOfEntryPoint = (RVA)reader.ReadUInt32(); - this.baseOfCode = (RVA)reader.ReadUInt32(); - this.baseOfData = (RVA)reader.ReadUInt32(); - this.imageBase = reader.ReadUInt32(); - this.sectionAlignment = reader.ReadUInt32(); - this.fileAlignment = reader.ReadUInt32(); - this.majorOperatingSystemVersion = reader.ReadUInt16(); - this.minorOperatingSystemVersion = reader.ReadUInt16(); - this.majorImageVersion = reader.ReadUInt16(); - this.minorImageVersion = reader.ReadUInt16(); - this.majorSubsystemVersion = reader.ReadUInt16(); - this.minorSubsystemVersion = reader.ReadUInt16(); - this.win32VersionValue = reader.ReadUInt32(); - this.sizeOfImage = reader.ReadUInt32(); - this.sizeOfHeaders = reader.ReadUInt32(); - this.checkSum = reader.ReadUInt32(); - this.subsystem = (Subsystem)reader.ReadUInt16(); - this.dllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); - this.sizeOfStackReserve = reader.ReadUInt32(); - this.sizeOfStackCommit = reader.ReadUInt32(); - this.sizeOfHeapReserve = reader.ReadUInt32(); - this.sizeOfHeapCommit = reader.ReadUInt32(); - this.loaderFlags = reader.ReadUInt32(); - this.numberOfRvaAndSizes = reader.ReadUInt32(); + magic = reader.ReadUInt16(); + majorLinkerVersion = reader.ReadByte(); + minorLinkerVersion = reader.ReadByte(); + sizeOfCode = reader.ReadUInt32(); + sizeOfInitializedData = reader.ReadUInt32(); + sizeOfUninitializedData = reader.ReadUInt32(); + addressOfEntryPoint = (RVA)reader.ReadUInt32(); + baseOfCode = (RVA)reader.ReadUInt32(); + baseOfData = (RVA)reader.ReadUInt32(); + imageBase = reader.ReadUInt32(); + sectionAlignment = reader.ReadUInt32(); + fileAlignment = reader.ReadUInt32(); + majorOperatingSystemVersion = reader.ReadUInt16(); + minorOperatingSystemVersion = reader.ReadUInt16(); + majorImageVersion = reader.ReadUInt16(); + minorImageVersion = reader.ReadUInt16(); + majorSubsystemVersion = reader.ReadUInt16(); + minorSubsystemVersion = reader.ReadUInt16(); + win32VersionValue = reader.ReadUInt32(); + sizeOfImage = reader.ReadUInt32(); + sizeOfHeaders = reader.ReadUInt32(); + checkSum = reader.ReadUInt32(); + subsystem = (Subsystem)reader.ReadUInt16(); + dllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); + sizeOfStackReserve = reader.ReadUInt32(); + sizeOfStackCommit = reader.ReadUInt32(); + sizeOfHeapReserve = reader.ReadUInt32(); + sizeOfHeapCommit = reader.ReadUInt32(); + loaderFlags = reader.ReadUInt32(); + numberOfRvaAndSizes = reader.ReadUInt32(); for (int i = 0; i < dataDirectories.Length; i++) { uint len = (uint)(reader.Position - startOffset); if (len + 8 <= totalSize) diff --git a/src/PE/ImageOptionalHeader64.cs b/src/PE/ImageOptionalHeader64.cs index b49c32d5b..4d9298f78 100644 --- a/src/PE/ImageOptionalHeader64.cs +++ b/src/PE/ImageOptionalHeader64.cs @@ -42,219 +42,157 @@ public sealed class ImageOptionalHeader64 : FileSection, IImageOptionalHeader { /// /// Returns the IMAGE_OPTIONAL_HEADER64.Magic field /// - public ushort Magic { - get { return magic; } - } + public ushort Magic => magic; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MajorLinkerVersion field /// - public byte MajorLinkerVersion { - get { return majorLinkerVersion; } - } + public byte MajorLinkerVersion => majorLinkerVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MinorLinkerVersion field /// - public byte MinorLinkerVersion { - get { return minorLinkerVersion; } - } + public byte MinorLinkerVersion => minorLinkerVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfCode field /// - public uint SizeOfCode { - get { return sizeOfCode; } - } + public uint SizeOfCode => sizeOfCode; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfInitializedData field /// - public uint SizeOfInitializedData { - get { return sizeOfInitializedData; } - } + public uint SizeOfInitializedData => sizeOfInitializedData; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfUninitializedData field /// - public uint SizeOfUninitializedData { - get { return sizeOfUninitializedData; } - } + public uint SizeOfUninitializedData => sizeOfUninitializedData; /// /// Returns the IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint field /// - public RVA AddressOfEntryPoint { - get { return addressOfEntryPoint; } - } + public RVA AddressOfEntryPoint => addressOfEntryPoint; /// /// Returns the IMAGE_OPTIONAL_HEADER64.BaseOfCode field /// - public RVA BaseOfCode { - get { return baseOfCode; } - } + public RVA BaseOfCode => baseOfCode; /// /// Returns 0 since BaseOfData is not present in IMAGE_OPTIONAL_HEADER64 /// - public RVA BaseOfData { - get { return 0; } - } + public RVA BaseOfData => 0; /// /// Returns the IMAGE_OPTIONAL_HEADER64.ImageBase field /// - public ulong ImageBase { - get { return imageBase; } - } + public ulong ImageBase => imageBase; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SectionAlignment field /// - public uint SectionAlignment { - get { return sectionAlignment; } - } + public uint SectionAlignment => sectionAlignment; /// /// Returns the IMAGE_OPTIONAL_HEADER64.FileAlignment field /// - public uint FileAlignment { - get { return fileAlignment; } - } + public uint FileAlignment => fileAlignment; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MajorOperatingSystemVersion field /// - public ushort MajorOperatingSystemVersion { - get { return majorOperatingSystemVersion; } - } + public ushort MajorOperatingSystemVersion => majorOperatingSystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MinorOperatingSystemVersion field /// - public ushort MinorOperatingSystemVersion { - get { return minorOperatingSystemVersion; } - } + public ushort MinorOperatingSystemVersion => minorOperatingSystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MajorImageVersion field /// - public ushort MajorImageVersion { - get { return majorImageVersion; } - } + public ushort MajorImageVersion => majorImageVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MinorImageVersion field /// - public ushort MinorImageVersion { - get { return minorImageVersion; } - } + public ushort MinorImageVersion => minorImageVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MajorSubsystemVersion field /// - public ushort MajorSubsystemVersion { - get { return majorSubsystemVersion; } - } + public ushort MajorSubsystemVersion => majorSubsystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.MinorSubsystemVersion field /// - public ushort MinorSubsystemVersion { - get { return minorSubsystemVersion; } - } + public ushort MinorSubsystemVersion => minorSubsystemVersion; /// /// Returns the IMAGE_OPTIONAL_HEADER64.Win32VersionValue field /// - public uint Win32VersionValue { - get { return win32VersionValue; } - } + public uint Win32VersionValue => win32VersionValue; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfImage field /// - public uint SizeOfImage { - get { return sizeOfImage; } - } + public uint SizeOfImage => sizeOfImage; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfHeaders field /// - public uint SizeOfHeaders { - get { return sizeOfHeaders; } - } + public uint SizeOfHeaders => sizeOfHeaders; /// /// Returns the IMAGE_OPTIONAL_HEADER64.CheckSum field /// - public uint CheckSum { - get { return checkSum; } - } + public uint CheckSum => checkSum; /// /// Returns the IMAGE_OPTIONAL_HEADER64.Subsystem field /// - public Subsystem Subsystem { - get { return subsystem; } - } + public Subsystem Subsystem => subsystem; /// /// Returns the IMAGE_OPTIONAL_HEADER64.DllCharacteristics field /// - public DllCharacteristics DllCharacteristics { - get { return dllCharacteristics; } - } + public DllCharacteristics DllCharacteristics => dllCharacteristics; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfStackReserve field /// - public ulong SizeOfStackReserve { - get { return sizeOfStackReserve; } - } + public ulong SizeOfStackReserve => sizeOfStackReserve; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfStackCommit field /// - public ulong SizeOfStackCommit { - get { return sizeOfStackCommit; } - } + public ulong SizeOfStackCommit => sizeOfStackCommit; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfHeapReserve field /// - public ulong SizeOfHeapReserve { - get { return sizeOfHeapReserve; } - } + public ulong SizeOfHeapReserve => sizeOfHeapReserve; /// /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfHeapCommit field /// - public ulong SizeOfHeapCommit { - get { return sizeOfHeapCommit; } - } + public ulong SizeOfHeapCommit => sizeOfHeapCommit; /// /// Returns the IMAGE_OPTIONAL_HEADER64.LoaderFlags field /// - public uint LoaderFlags { - get { return loaderFlags; } - } + public uint LoaderFlags => loaderFlags; /// /// Returns the IMAGE_OPTIONAL_HEADER64.NumberOfRvaAndSizes field /// - public uint NumberOfRvaAndSizes { - get { return numberOfRvaAndSizes; } - } + public uint NumberOfRvaAndSizes => numberOfRvaAndSizes; /// /// Returns the IMAGE_OPTIONAL_HEADER64.DataDirectories field /// - public ImageDataDirectory[] DataDirectories { - get { return dataDirectories; } - } + public ImageDataDirectory[] DataDirectories => dataDirectories; /// /// Constructor @@ -269,35 +207,35 @@ public ImageOptionalHeader64(IImageStream reader, uint totalSize, bool verify) { if (verify && reader.Position + totalSize > reader.Length) throw new BadImageFormatException("Invalid optional header size"); SetStartOffset(reader); - this.magic = reader.ReadUInt16(); - this.majorLinkerVersion = reader.ReadByte(); - this.minorLinkerVersion = reader.ReadByte(); - this.sizeOfCode = reader.ReadUInt32(); - this.sizeOfInitializedData = reader.ReadUInt32(); - this.sizeOfUninitializedData = reader.ReadUInt32(); - this.addressOfEntryPoint = (RVA)reader.ReadUInt32(); - this.baseOfCode = (RVA)reader.ReadUInt32(); - this.imageBase = reader.ReadUInt64(); - this.sectionAlignment = reader.ReadUInt32(); - this.fileAlignment = reader.ReadUInt32(); - this.majorOperatingSystemVersion = reader.ReadUInt16(); - this.minorOperatingSystemVersion = reader.ReadUInt16(); - this.majorImageVersion = reader.ReadUInt16(); - this.minorImageVersion = reader.ReadUInt16(); - this.majorSubsystemVersion = reader.ReadUInt16(); - this.minorSubsystemVersion = reader.ReadUInt16(); - this.win32VersionValue = reader.ReadUInt32(); - this.sizeOfImage = reader.ReadUInt32(); - this.sizeOfHeaders = reader.ReadUInt32(); - this.checkSum = reader.ReadUInt32(); - this.subsystem = (Subsystem)reader.ReadUInt16(); - this.dllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); - this.sizeOfStackReserve = reader.ReadUInt64(); - this.sizeOfStackCommit = reader.ReadUInt64(); - this.sizeOfHeapReserve = reader.ReadUInt64(); - this.sizeOfHeapCommit = reader.ReadUInt64(); - this.loaderFlags = reader.ReadUInt32(); - this.numberOfRvaAndSizes = reader.ReadUInt32(); + magic = reader.ReadUInt16(); + majorLinkerVersion = reader.ReadByte(); + minorLinkerVersion = reader.ReadByte(); + sizeOfCode = reader.ReadUInt32(); + sizeOfInitializedData = reader.ReadUInt32(); + sizeOfUninitializedData = reader.ReadUInt32(); + addressOfEntryPoint = (RVA)reader.ReadUInt32(); + baseOfCode = (RVA)reader.ReadUInt32(); + imageBase = reader.ReadUInt64(); + sectionAlignment = reader.ReadUInt32(); + fileAlignment = reader.ReadUInt32(); + majorOperatingSystemVersion = reader.ReadUInt16(); + minorOperatingSystemVersion = reader.ReadUInt16(); + majorImageVersion = reader.ReadUInt16(); + minorImageVersion = reader.ReadUInt16(); + majorSubsystemVersion = reader.ReadUInt16(); + minorSubsystemVersion = reader.ReadUInt16(); + win32VersionValue = reader.ReadUInt32(); + sizeOfImage = reader.ReadUInt32(); + sizeOfHeaders = reader.ReadUInt32(); + checkSum = reader.ReadUInt32(); + subsystem = (Subsystem)reader.ReadUInt16(); + dllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); + sizeOfStackReserve = reader.ReadUInt64(); + sizeOfStackCommit = reader.ReadUInt64(); + sizeOfHeapReserve = reader.ReadUInt64(); + sizeOfHeapCommit = reader.ReadUInt64(); + loaderFlags = reader.ReadUInt32(); + numberOfRvaAndSizes = reader.ReadUInt32(); for (int i = 0; i < dataDirectories.Length; i++) { uint len = (uint)(reader.Position - startOffset); if (len + 8 <= totalSize) diff --git a/src/PE/ImageSectionHeader.cs b/src/PE/ImageSectionHeader.cs index f8da27e4a..c26a46d60 100644 --- a/src/PE/ImageSectionHeader.cs +++ b/src/PE/ImageSectionHeader.cs @@ -27,79 +27,57 @@ public sealed class ImageSectionHeader : FileSection { /// Returns the human readable section name, ignoring everything after /// the first nul byte /// - public string DisplayName { - get { return displayName; } - } + public string DisplayName => displayName; /// /// Returns the IMAGE_SECTION_HEADER.Name field /// - public byte[] Name { - get { return name; } - } + public byte[] Name => name; /// /// Returns the IMAGE_SECTION_HEADER.VirtualSize field /// - public uint VirtualSize { - get { return virtualSize; } - } + public uint VirtualSize => virtualSize; /// /// Returns the IMAGE_SECTION_HEADER.VirtualAddress field /// - public RVA VirtualAddress { - get { return virtualAddress; } - } + public RVA VirtualAddress => virtualAddress; /// /// Returns the IMAGE_SECTION_HEADER.SizeOfRawData field /// - public uint SizeOfRawData { - get { return sizeOfRawData; } - } + public uint SizeOfRawData => sizeOfRawData; /// /// Returns the IMAGE_SECTION_HEADER.PointerToRawData field /// - public uint PointerToRawData { - get { return pointerToRawData; } - } + public uint PointerToRawData => pointerToRawData; /// /// Returns the IMAGE_SECTION_HEADER.PointerToRelocations field /// - public uint PointerToRelocations { - get { return pointerToRelocations; } - } + public uint PointerToRelocations => pointerToRelocations; /// /// Returns the IMAGE_SECTION_HEADER.PointerToLinenumbers field /// - public uint PointerToLinenumbers { - get { return pointerToLinenumbers; } - } + public uint PointerToLinenumbers => pointerToLinenumbers; /// /// Returns the IMAGE_SECTION_HEADER.NumberOfRelocations field /// - public ushort NumberOfRelocations { - get { return numberOfRelocations; } - } + public ushort NumberOfRelocations => numberOfRelocations; /// /// Returns the IMAGE_SECTION_HEADER.NumberOfLinenumbers field /// - public ushort NumberOfLinenumbers { - get { return numberOfLinenumbers; } - } + public ushort NumberOfLinenumbers => numberOfLinenumbers; /// /// Returns the IMAGE_SECTION_HEADER.Characteristics field /// - public uint Characteristics { - get { return characteristics; } - } + public uint Characteristics => characteristics; /// /// Constructor @@ -109,16 +87,16 @@ public uint Characteristics { /// Thrown if verification fails public ImageSectionHeader(IImageStream reader, bool verify) { SetStartOffset(reader); - this.name = reader.ReadBytes(8); - this.virtualSize = reader.ReadUInt32(); - this.virtualAddress = (RVA)reader.ReadUInt32(); - this.sizeOfRawData = reader.ReadUInt32(); - this.pointerToRawData = reader.ReadUInt32(); - this.pointerToRelocations = reader.ReadUInt32(); - this.pointerToLinenumbers = reader.ReadUInt32(); - this.numberOfRelocations = reader.ReadUInt16(); - this.numberOfLinenumbers = reader.ReadUInt16(); - this.characteristics = reader.ReadUInt32(); + name = reader.ReadBytes(8); + virtualSize = reader.ReadUInt32(); + virtualAddress = (RVA)reader.ReadUInt32(); + sizeOfRawData = reader.ReadUInt32(); + pointerToRawData = reader.ReadUInt32(); + pointerToRelocations = reader.ReadUInt32(); + pointerToLinenumbers = reader.ReadUInt32(); + numberOfRelocations = reader.ReadUInt16(); + numberOfLinenumbers = reader.ReadUInt16(); + characteristics = reader.ReadUInt32(); SetEndoffset(reader); displayName = ToString(name); } diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index 78478e6d8..a616a3635 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -47,57 +47,37 @@ public sealed class PEImage : IPEImage { sealed class FilePEType : IPEType { /// - public RVA ToRVA(PEInfo peInfo, FileOffset offset) { - return peInfo.ToRVA(offset); - } + public RVA ToRVA(PEInfo peInfo, FileOffset offset) => peInfo.ToRVA(offset); /// - public FileOffset ToFileOffset(PEInfo peInfo, RVA rva) { - return peInfo.ToFileOffset(rva); - } + public FileOffset ToFileOffset(PEInfo peInfo, RVA rva) => peInfo.ToFileOffset(rva); } sealed class MemoryPEType : IPEType { /// - public RVA ToRVA(PEInfo peInfo, FileOffset offset) { - return (RVA)offset; - } + public RVA ToRVA(PEInfo peInfo, FileOffset offset) => (RVA)offset; /// - public FileOffset ToFileOffset(PEInfo peInfo, RVA rva) { - return (FileOffset)rva; - } + public FileOffset ToFileOffset(PEInfo peInfo, RVA rva) => (FileOffset)rva; } /// - public bool IsFileImageLayout { - get { return peType is FilePEType; } - } + public bool IsFileImageLayout => peType is FilePEType; /// - public bool MayHaveInvalidAddresses { - get { return !IsFileImageLayout; } - } + public bool MayHaveInvalidAddresses => !IsFileImageLayout; /// - public string FileName { - get { return imageStreamCreator.FileName; } - } + public string FileName => imageStreamCreator.FileName; /// - public ImageDosHeader ImageDosHeader { - get { return peInfo.ImageDosHeader; } - } + public ImageDosHeader ImageDosHeader => peInfo.ImageDosHeader; /// - public ImageNTHeaders ImageNTHeaders { - get { return peInfo.ImageNTHeaders; } - } + public ImageNTHeaders ImageNTHeaders => peInfo.ImageNTHeaders; /// - public IList ImageSectionHeaders { - get { return peInfo.ImageSectionHeaders; } - } + public IList ImageSectionHeaders => peInfo.ImageSectionHeaders; /// public IList ImageDebugDirectories { @@ -111,7 +91,7 @@ public IList ImageDebugDirectories { /// public Win32Resources Win32Resources { - get { return win32Resources.Value; } + get => win32Resources.Value; set { IDisposable origValue = null; if (win32Resources.IsValueInitialized) { @@ -135,9 +115,9 @@ public Win32Resources Win32Resources { public PEImage(IImageStreamCreator imageStreamCreator, ImageLayout imageLayout, bool verify) { try { this.imageStreamCreator = imageStreamCreator; - this.peType = ConvertImageLayout(imageLayout); + peType = ConvertImageLayout(imageLayout); ResetReader(); - this.peInfo = new PEInfo(imageStream, verify); + peInfo = new PEInfo(imageStream, verify); Initialize(); } catch { @@ -334,14 +314,10 @@ void ResetReader() { } /// - public RVA ToRVA(FileOffset offset) { - return peType.ToRVA(peInfo, offset); - } + public RVA ToRVA(FileOffset offset) => peType.ToRVA(peInfo, offset); /// - public FileOffset ToFileOffset(RVA rva) { - return peType.ToFileOffset(peInfo, rva); - } + public FileOffset ToFileOffset(RVA rva) => peType.ToFileOffset(peInfo, rva); /// public void Dispose() { @@ -362,25 +338,20 @@ public void Dispose() { /// public IImageStream CreateStream(FileOffset offset) { if ((long)offset > imageStreamCreator.Length) - throw new ArgumentOutOfRangeException("offset"); + throw new ArgumentOutOfRangeException(nameof(offset)); long length = imageStreamCreator.Length - (long)offset; return CreateStream(offset, length); } /// - public IImageStream CreateStream(FileOffset offset, long length) { - return imageStreamCreator.Create(offset, length); - } + public IImageStream CreateStream(FileOffset offset, long length) => imageStreamCreator.Create(offset, length); /// - public IImageStream CreateFullStream() { - return imageStreamCreator.CreateFull(); - } + public IImageStream CreateFullStream() => imageStreamCreator.CreateFull(); /// public void UnsafeDisableMemoryMappedIO() { - var creator = imageStreamCreator as MemoryMappedFileStreamCreator; - if (creator != null) + if (imageStreamCreator is MemoryMappedFileStreamCreator creator) creator.UnsafeDisableMemoryMappedIO(); } diff --git a/src/PE/PEInfo.cs b/src/PE/PEInfo.cs index c209f3f27..c618c55c6 100644 --- a/src/PE/PEInfo.cs +++ b/src/PE/PEInfo.cs @@ -15,23 +15,17 @@ sealed class PEInfo { /// /// Returns the DOS header /// - public ImageDosHeader ImageDosHeader { - get { return imageDosHeader; } - } + public ImageDosHeader ImageDosHeader => imageDosHeader; /// /// Returns the NT headers /// - public ImageNTHeaders ImageNTHeaders { - get { return imageNTHeaders; } - } + public ImageNTHeaders ImageNTHeaders => imageNTHeaders; /// /// Returns the section headers /// - public ImageSectionHeader[] ImageSectionHeaders { - get { return imageSectionHeaders; } - } + public ImageSectionHeader[] ImageSectionHeaders => imageSectionHeaders; /// /// Constructor @@ -41,17 +35,17 @@ public ImageSectionHeader[] ImageSectionHeaders { /// Thrown if verification fails public PEInfo(IImageStream reader, bool verify) { reader.Position = 0; - this.imageDosHeader = new ImageDosHeader(reader, verify); + imageDosHeader = new ImageDosHeader(reader, verify); - if (verify && this.imageDosHeader.NTHeadersOffset == 0) + if (verify && imageDosHeader.NTHeadersOffset == 0) throw new BadImageFormatException("Invalid NT headers offset"); - reader.Position = this.imageDosHeader.NTHeadersOffset; - this.imageNTHeaders = new ImageNTHeaders(reader, verify); + reader.Position = imageDosHeader.NTHeadersOffset; + imageNTHeaders = new ImageNTHeaders(reader, verify); - reader.Position = (long)this.imageNTHeaders.OptionalHeader.StartOffset + this.imageNTHeaders.FileHeader.SizeOfOptionalHeader; - this.imageSectionHeaders = new ImageSectionHeader[this.imageNTHeaders.FileHeader.NumberOfSections]; - for (int i = 0; i < this.imageSectionHeaders.Length; i++) - this.imageSectionHeaders[i] = new ImageSectionHeader(reader, verify); + reader.Position = (long)imageNTHeaders.OptionalHeader.StartOffset + imageNTHeaders.FileHeader.SizeOfOptionalHeader; + imageSectionHeaders = new ImageSectionHeader[imageNTHeaders.FileHeader.NumberOfSections]; + for (int i = 0; i < imageSectionHeaders.Length; i++) + imageSectionHeaders[i] = new ImageSectionHeader(reader, verify); } /// @@ -106,9 +100,7 @@ public FileOffset ToFileOffset(RVA rva) { return (FileOffset)rva; } - static ulong AlignUp(ulong val, uint alignment) { - return (val + alignment - 1) & ~(ulong)(alignment - 1); - } + static ulong AlignUp(ulong val, uint alignment) => (val + alignment - 1) & ~(ulong)(alignment - 1); /// /// Returns size of image rounded up to diff --git a/src/PE/RVA.cs b/src/PE/RVA.cs index 74179ef2a..3408e6943 100644 --- a/src/PE/RVA.cs +++ b/src/PE/RVA.cs @@ -13,17 +13,13 @@ partial class PEExtensions { /// /// this /// Alignment - public static RVA AlignUp(this RVA rva, uint alignment) { - return (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); - } + public static RVA AlignUp(this RVA rva, uint alignment) => (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); /// /// Align up /// /// this /// Alignment - public static RVA AlignUp(this RVA rva, int alignment) { - return (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); - } + public static RVA AlignUp(this RVA rva, int alignment) => (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); } } diff --git a/src/Threading/IThreadSafeList.cs b/src/Threading/IThreadSafeList.cs index 39c899650..6a3748c4c 100644 --- a/src/Threading/IThreadSafeList.cs +++ b/src/Threading/IThreadSafeList.cs @@ -230,13 +230,12 @@ public static partial class Extensions { /// Passed to /// Handler that should execute when the lock is held /// The value returns - public static TRetType ExecuteLocked(this ThreadSafe.IList tsList, TArgType arg, ExecuteLockedDelegate handler) { + public static TRetType ExecuteLocked(this ThreadSafe.IList tsList, TArgType arg, ExecuteLockedDelegate handler) => #if THREAD_SAFE - return tsList.ExecuteLocked(arg, handler); + tsList.ExecuteLocked(arg, handler); #else - return handler(tsList, arg); + handler(tsList, arg); #endif - } #if THREAD_SAFE /// @@ -248,7 +247,7 @@ public static TRetType ExecuteLocked(this ThreadSafe.ILis /// Start index /// End index. -1 means /// true if we should iterate in the reverse order - public static void Iterate(this ThreadSafe.IList tsList, int startIndex, int endIndex, bool reverseOrder, IterateDelegate handler) { + public static void Iterate(this ThreadSafe.IList tsList, int startIndex, int endIndex, bool reverseOrder, IterateDelegate handler) => tsList.ExecuteLocked(null, (tsList2, arg) => { if (reverseOrder) { int i = (endIndex < 0 ? tsList2.Count_NoLock : endIndex) - 1; @@ -266,7 +265,6 @@ public static void Iterate(this ThreadSafe.IList tsList, int startIndex, i } return null; }); - } /// /// Iterates over all elements in and calls @@ -274,9 +272,8 @@ public static void Iterate(this ThreadSafe.IList tsList, int startIndex, i /// Type to store in list /// A thread-safe list /// Called for each element - public static void Iterate(this ThreadSafe.IList tsList, IterateDelegate handler) { + public static void Iterate(this ThreadSafe.IList tsList, IterateDelegate handler) => tsList.Iterate(0, -1, false, handler); - } /// /// Iterates over all elements in and calls @@ -284,12 +281,11 @@ public static void Iterate(this ThreadSafe.IList tsList, IterateDelegateType to store in list /// A thread-safe list /// Called for each element - public static void IterateAll(this ThreadSafe.IList tsList, IterateAllDelegate handler) { + public static void IterateAll(this ThreadSafe.IList tsList, IterateAllDelegate handler) => tsList.Iterate(0, -1, false, (tsList2, index, value) => { handler(tsList2, index, value); return true; }); - } /// /// Iterates over all elements in in the reverse order and calls @@ -298,9 +294,8 @@ public static void IterateAll(this ThreadSafe.IList tsList, IterateAllDele /// Type to store in list /// A thread-safe list /// Called for each element - public static void IterateReverse(this ThreadSafe.IList tsList, IterateDelegate handler) { + public static void IterateReverse(this ThreadSafe.IList tsList, IterateDelegate handler) => tsList.Iterate(0, -1, true, handler); - } /// /// Iterates over all elements in in the reverse order and calls @@ -309,12 +304,11 @@ public static void IterateReverse(this ThreadSafe.IList tsList, IterateDel /// Type to store in list /// A thread-safe list /// Called for each element - public static void IterateAllReverse(this ThreadSafe.IList tsList, IterateAllDelegate handler) { + public static void IterateAllReverse(this ThreadSafe.IList tsList, IterateAllDelegate handler) => tsList.Iterate(0, -1, true, (tsList2, index, value) => { handler(tsList2, index, value); return true; }); - } #endif /// @@ -362,9 +356,8 @@ public static void Iterate(this IList list, int startIndex, int endIndex, /// Type to store in list /// A list /// Called for each element - public static void Iterate(this IList list, ListIterateDelegate handler) { + public static void Iterate(this IList list, ListIterateDelegate handler) => list.Iterate(0, -1, false, handler); - } /// /// Iterates over all elements in and calls @@ -374,12 +367,11 @@ public static void Iterate(this IList list, ListIterateDelegate handler /// Type to store in list /// A list /// Called for each element - public static void IterateAll(this IList list, ListIterateAllDelegate handler) { + public static void IterateAll(this IList list, ListIterateAllDelegate handler) => list.Iterate(0, -1, false, (list2, index, value) => { handler(list2, index, value); return true; }); - } /// /// Iterates over all elements in in the reverse order and calls @@ -389,9 +381,8 @@ public static void IterateAll(this IList list, ListIterateAllDelegate h /// Type to store in list /// A list /// Called for each element - public static void IterateReverse(this IList list, ListIterateDelegate handler) { + public static void IterateReverse(this IList list, ListIterateDelegate handler) => list.Iterate(0, -1, true, handler); - } /// /// Iterates over all elements in in the reverse order and calls @@ -401,12 +392,11 @@ public static void IterateReverse(this IList list, ListIterateDelegate /// Type to store in list /// A list /// Called for each element - public static void IterateAllReverse(this IList list, ListIterateAllDelegate handler) { + public static void IterateAllReverse(this IList list, ListIterateAllDelegate handler) => list.Iterate(0, -1, true, (list2, index, value) => { handler(list2, index, value); return true; }); - } /// /// Iterates over all elements in and calls @@ -442,12 +432,11 @@ public static void Iterate(this IEnumerable list, EnumerableIterateDelegat /// Type to store in list /// A list /// Called for each element - public static void IterateAll(this IEnumerable list, EnumerableIterateAllDelegate handler) { + public static void IterateAll(this IEnumerable list, EnumerableIterateAllDelegate handler) => list.Iterate((index, value) => { handler(index, value); return true; }); - } /// /// Reads an element from the list. If implements @@ -474,7 +463,7 @@ public static bool Get(this IList list, int index, out T value) { catch (ArgumentOutOfRangeException) { } #endif - value = default(T); + value = default; return false; } @@ -488,10 +477,8 @@ public static bool Get(this IList list, int index, out T value) { /// Default value if is invalid /// The value in the list or if /// was invalid - public static T Get(this IList list, int index, T defaultValue) { - T value; - return list.Get(index, out value) ? value : defaultValue; - } + public static T Get(this IList list, int index, T defaultValue) => + list.Get(index, out T value) ? value : defaultValue; /// /// Writes an element to the list. If implements @@ -528,18 +515,16 @@ public static bool Set(this IList list, int index, T value) { /// Type to store in list /// A thread-safe list /// Number of elements in the list - public static int Count_NoLock(this ThreadSafe.IList tsList) { - return tsList.Count_NoLock; - } + public static int Count_NoLock(this ThreadSafe.IList tsList) => + tsList.Count_NoLock; /// /// Calls /// /// Type to store in list /// A thread-safe list - public static bool IsReadOnly_NoLock(this ThreadSafe.IList tsList) { - return tsList.IsReadOnly_NoLock; - } + public static bool IsReadOnly_NoLock(this ThreadSafe.IList tsList) => + tsList.IsReadOnly_NoLock; #endif /// diff --git a/src/Threading/Lock.cs b/src/Threading/Lock.cs index 5fb1f1422..2d21c6b08 100644 --- a/src/Threading/Lock.cs +++ b/src/Threading/Lock.cs @@ -33,16 +33,14 @@ class Lock { /// Creates a new instance of this class /// /// - public static Lock Create() { - return new Lock(); - } + public static Lock Create() => new Lock(); /// /// Constructor /// Lock() { - this.lockObj = new object(); - this.recurseCount = 0; + lockObj = new object(); + recurseCount = 0; } /// diff --git a/src/Threading/ThreadSafeListWrapper.cs b/src/Threading/ThreadSafeListWrapper.cs index 8c6dae1e2..f872843e4 100644 --- a/src/Threading/ThreadSafeListWrapper.cs +++ b/src/Threading/ThreadSafeListWrapper.cs @@ -134,69 +134,43 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { } /// - public int Count_NoLock { - get { return list.Count; } - } + public int Count_NoLock => list.Count; /// - public bool IsReadOnly_NoLock { - get { return list.IsReadOnly; } - } + public bool IsReadOnly_NoLock => list.IsReadOnly; /// - public int IndexOf_NoLock(T item) { - return list.IndexOf(item); - } + public int IndexOf_NoLock(T item) => list.IndexOf(item); /// - public void Insert_NoLock(int index, T item) { - list.Insert(index, item); - } + public void Insert_NoLock(int index, T item) => list.Insert(index, item); /// - public void RemoveAt_NoLock(int index) { - list.RemoveAt(index); - } + public void RemoveAt_NoLock(int index) => list.RemoveAt(index); /// - public T Get_NoLock(int index) { - return list[index]; - } + public T Get_NoLock(int index) => list[index]; /// - public void Set_NoLock(int index, T value) { - list[index] = value; - } + public void Set_NoLock(int index, T value) => list[index] = value; /// - public void Add_NoLock(T item) { - list.Add(item); - } + public void Add_NoLock(T item) => list.Add(item); /// - public void Clear_NoLock() { - list.Clear(); - } + public void Clear_NoLock() => list.Clear(); /// - public bool Contains_NoLock(T item) { - return list.Contains(item); - } + public bool Contains_NoLock(T item) => list.Contains(item); /// - public void CopyTo_NoLock(T[] array, int arrayIndex) { - list.CopyTo(array, arrayIndex); - } + public void CopyTo_NoLock(T[] array, int arrayIndex) => list.CopyTo(array, arrayIndex); /// - public bool Remove_NoLock(T item) { - return list.Remove(item); - } + public bool Remove_NoLock(T item) => list.Remove(item); /// - public IEnumerator GetEnumerator_NoLock() { - return list.GetEnumerator(); - } + public IEnumerator GetEnumerator_NoLock() => list.GetEnumerator(); /// public TRetType ExecuteLocked(TArgType arg, ExecuteLockedDelegate handler) { diff --git a/src/Utils/LazyList.cs b/src/Utils/LazyList.cs index 360f43bb4..83516c4f9 100644 --- a/src/Utils/LazyList.cs +++ b/src/Utils/LazyList.cs @@ -93,9 +93,7 @@ class Element { /// /// true if it has been initialized, false otherwise /// - public virtual bool IsInitialized_NoLock { - get { return true; } - } + public virtual bool IsInitialized_NoLock => true; /// /// Default constructor @@ -107,31 +105,23 @@ protected Element() { /// Constructor that should be used when new elements are inserted into /// /// User data - public Element(TValue data) { - this.value = data; - } + public Element(TValue data) => value = data; /// /// Gets the value /// /// Index in the list - public virtual TValue GetValue_NoLock(int index) { - return value; - } + public virtual TValue GetValue_NoLock(int index) => value; /// /// Sets the value /// /// Index in the list /// New value - public virtual void SetValue_NoLock(int index, TValue value) { - this.value = value; - } + public virtual void SetValue_NoLock(int index, TValue value) => this.value = value; /// - public override string ToString() { - return value == null ? string.Empty : value.ToString(); - } + public override string ToString() => value?.ToString() ?? string.Empty; } /// @@ -143,9 +133,7 @@ sealed class LazyElement : Element { LazyList lazyList; /// - public override bool IsInitialized_NoLock { - get { return lazyList == null; } - } + public override bool IsInitialized_NoLock => lazyList == null; /// public override TValue GetValue_NoLock(int index) { @@ -198,21 +186,15 @@ public int Count { /// [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)] - public int Count_NoLock { - get { return list.Count; } - } + public int Count_NoLock => list.Count; /// [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)] - public bool IsReadOnly { - get { return false; } - } + public bool IsReadOnly => false; /// [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)] - public bool IsReadOnly_NoLock { - get { return false; } - } + public bool IsReadOnly_NoLock => false; /// public TValue this[int index] { @@ -237,9 +219,7 @@ public TValue this[int index] { } /// - public TValue Get_NoLock(int index) { - return list[index].GetValue_NoLock(index); - } + public TValue Get_NoLock(int index) => list[index].GetValue_NoLock(index); /// public void Set_NoLock(int index, TValue value) { @@ -264,7 +244,7 @@ public LazyList() /// List listener public LazyList(IListListener listener) { this.listener = listener; - this.list = new List(); + list = new List(); } /// @@ -288,14 +268,12 @@ public LazyList(int length, IListListener listener, object context, MFun this.listener = listener; this.context = context; this.readOriginalValue = readOriginalValue; - this.list = new List(length); + list = new List(length); for (int i = 0; i < length; i++) list.Add(new LazyElement(i, this)); } - TValue ReadOriginalValue_NoLock(LazyElement elem) { - return ReadOriginalValue_NoLock(list.IndexOf(elem), elem.origIndex); - } + TValue ReadOriginalValue_NoLock(LazyElement elem) => ReadOriginalValue_NoLock(list.IndexOf(elem), elem.origIndex); TValue ReadOriginalValue_NoLock(int index, uint origIndex) { var newValue = readOriginalValue(context, origIndex); @@ -410,14 +388,10 @@ public void Clear_NoLock() { } /// - public bool Contains(TValue item) { - return IndexOf(item) >= 0; - } + public bool Contains(TValue item) => IndexOf(item) >= 0; /// - public bool Contains_NoLock(TValue item) { - return IndexOf_NoLock(item) >= 0; - } + public bool Contains_NoLock(TValue item) => IndexOf_NoLock(item) >= 0; /// public void CopyTo(TValue[] array, int arrayIndex) { @@ -536,9 +510,7 @@ public List GetInitializedElements(bool clearList) { } /// - IEnumerator IEnumerable.GetEnumerator() { - return GetEnumerator(); - } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #if THREAD_SAFE /// diff --git a/src/Utils/SimpleLazyList.cs b/src/Utils/SimpleLazyList.cs index d40b3371a..af8606631 100644 --- a/src/Utils/SimpleLazyList.cs +++ b/src/Utils/SimpleLazyList.cs @@ -21,9 +21,7 @@ sealed class SimpleLazyList where T : class { /// /// Gets the length of this list /// - public uint Length { - get { return length; } - } + public uint Length => length; /// /// Access the list @@ -50,7 +48,7 @@ public T this[uint index] { public SimpleLazyList(uint length, MFunc readElementByRID) { this.length = length; this.readElementByRID = readElementByRID; - this.elements = new T[length]; + elements = new T[length]; } } @@ -70,9 +68,7 @@ sealed class SimpleLazyList2 where T : class, IContainsGenericParameter { /// /// Gets the length of this list /// - public uint Length { - get { return length; } - } + public uint Length => length; /// /// Access the list @@ -105,7 +101,7 @@ public uint Length { public SimpleLazyList2(uint length, MFunc readElementByRID) { this.length = length; this.readElementByRID = readElementByRID; - this.elements = new T[length]; + elements = new T[length]; } } } diff --git a/src/Utils/UserValue.cs b/src/Utils/UserValue.cs index ea590d88c..82c4cb46f 100644 --- a/src/Utils/UserValue.cs +++ b/src/Utils/UserValue.cs @@ -23,7 +23,7 @@ struct UserValue { /// Sets the lock that protects the data /// public Lock Lock { - set { theLock = value; } + set => theLock = value; } #endif @@ -31,7 +31,7 @@ public Lock Lock { /// Set a delegate instance that will return the original value /// public MFunc ReadOriginalValue { - set { readOriginalValue = value; } + set => readOriginalValue = value; } /// @@ -81,7 +81,7 @@ public bool IsValueInitialized { finally { if (theLock != null) theLock.ExitReadLock(); } } #else - get { return isValueInitialized; } + get => isValueInitialized; #endif } @@ -99,7 +99,7 @@ public bool IsUserValue { finally { if (theLock != null) theLock.ExitReadLock(); } } #else - get { return isUserValue; } + get => isUserValue; #endif } } diff --git a/src/W32Resources/ResourceData.cs b/src/W32Resources/ResourceData.cs index b58a449c3..9210fdc71 100644 --- a/src/W32Resources/ResourceData.cs +++ b/src/W32Resources/ResourceData.cs @@ -18,7 +18,7 @@ public sealed class ResourceData : ResourceDirectoryEntry, IDisposable { /// Gets/sets the data reader. This instance owns the reader. /// public IBinaryReader Data { - get { return reader; } + get => reader; set { var oldValue = Interlocked.Exchange(ref reader, value); if (oldValue != value && oldValue != null) @@ -30,16 +30,16 @@ public IBinaryReader Data { /// Gets/sets the code page /// public uint CodePage { - get { return codePage; } - set { codePage = value; } + get => codePage; + set => codePage = value; } /// /// Gets/sets the reserved field /// public uint Reserved { - get { return reserved; } - set { reserved = value; } + get => reserved; + set => reserved = value; } /// @@ -56,9 +56,7 @@ public ResourceData(ResourceName name) /// Raw data. This instance owns this reader. /// Name public ResourceData(ResourceName name, IBinaryReader reader) - : base(name) { - this.reader = reader; - } + : base(name) => this.reader = reader; /// /// Constructor @@ -77,9 +75,7 @@ public ResourceData(ResourceName name, IBinaryReader reader, uint codePage, uint /// /// Gets the data as a . It shares the file position with /// - public Stream ToDataStream() { - return Data.CreateStream(); - } + public Stream ToDataStream() => Data.CreateStream(); /// public void Dispose() { diff --git a/src/W32Resources/ResourceDirectory.cs b/src/W32Resources/ResourceDirectory.cs index 3160aad98..dbb49d106 100644 --- a/src/W32Resources/ResourceDirectory.cs +++ b/src/W32Resources/ResourceDirectory.cs @@ -36,47 +36,43 @@ public abstract class ResourceDirectory : ResourceDirectoryEntry, IDisposable { /// Gets/sets the characteristics /// public uint Characteristics { - get { return characteristics; } - set { characteristics = value; } + get => characteristics; + set => characteristics = value; } /// /// Gets/sets the time date stamp /// public uint TimeDateStamp { - get { return timeDateStamp; } - set { timeDateStamp = value; } + get => timeDateStamp; + set => timeDateStamp = value; } /// /// Gets/sets the major version number /// public ushort MajorVersion { - get { return majorVersion; } - set { majorVersion = value; } + get => majorVersion; + set => majorVersion = value; } /// /// Gets/sets the minor version number /// public ushort MinorVersion { - get { return minorVersion; } - set { minorVersion = value; } + get => minorVersion; + set => minorVersion = value; } /// /// Gets all directory entries /// - public ThreadSafe.IList Directories { - get { return directories; } - } + public ThreadSafe.IList Directories => directories; /// /// Gets all resource data /// - public ThreadSafe.IList Data { - get { return data; } - } + public ThreadSafe.IList Data => data; /// /// Constructor @@ -142,8 +138,8 @@ public class ResourceDirectoryUser : ResourceDirectory { /// Name public ResourceDirectoryUser(ResourceName name) : base(name) { - this.directories = new LazyList(); - this.data = new LazyList(); + directories = new LazyList(); + data = new LazyList(); } } @@ -173,7 +169,7 @@ public sealed class ResourceDirectoryPE : ResourceDirectory { /// List dirInfos; - struct EntryInfo { + readonly struct EntryInfo { public readonly ResourceName name; /// Offset of resource directory / data @@ -184,9 +180,7 @@ public EntryInfo(ResourceName name, uint offset) { this.offset = offset; } - public override string ToString() { - return string.Format("{0:X8} {1}", offset, name); - } + public override string ToString() => $"{offset:X8} {name}"; } /// @@ -302,7 +296,7 @@ ResourceData ReadResourceData(int i) { ResourceData data; if (reader.CanRead(16)) { - RVA rva = (RVA)reader.ReadUInt32(); + var rva = (RVA)reader.ReadUInt32(); uint size = reader.ReadUInt32(); uint codePage = reader.ReadUInt32(); uint reserved = reader.ReadUInt32(); diff --git a/src/W32Resources/ResourceDirectoryEntry.cs b/src/W32Resources/ResourceDirectoryEntry.cs index 659bc4d22..b407b01f2 100644 --- a/src/W32Resources/ResourceDirectoryEntry.cs +++ b/src/W32Resources/ResourceDirectoryEntry.cs @@ -11,21 +11,17 @@ public abstract class ResourceDirectoryEntry { /// Gets/sets the name /// public ResourceName Name { - get { return name; } - set { name = value; } + get => name; + set => name = value; } /// /// Constructor /// /// Name - protected ResourceDirectoryEntry(ResourceName name) { - this.name = name; - } + protected ResourceDirectoryEntry(ResourceName name) => this.name = name; /// - public override string ToString() { - return name.ToString(); - } + public override string ToString() => name.ToString(); } } diff --git a/src/W32Resources/ResourceName.cs b/src/W32Resources/ResourceName.cs index 420e0f001..e996d3b72 100644 --- a/src/W32Resources/ResourceName.cs +++ b/src/W32Resources/ResourceName.cs @@ -6,37 +6,29 @@ namespace dnlib.W32Resources { /// /// A Win32 resource name. It can be either an integer or a string. /// - public struct ResourceName : IComparable, IEquatable { + public readonly struct ResourceName : IComparable, IEquatable { readonly int id; readonly string name; /// /// true if is valid /// - public bool HasId { - get { return name == null; } - } + public bool HasId => name == null; /// /// true if is valid /// - public bool HasName { - get { return name != null; } - } + public bool HasName => name != null; /// /// The ID. It's only valid if is true /// - public int Id { - get { return id; } - } + public int Id => id; /// /// The name. It's only valid if is true /// - public string Name { - get { return name; } - } + public string Name => name; /// /// Constructor @@ -44,7 +36,7 @@ public string Name { /// ID public ResourceName(int id) { this.id = id; - this.name = null; + name = null; } /// @@ -52,49 +44,33 @@ public ResourceName(int id) { /// /// Name public ResourceName(string name) { - this.id = 0; + id = 0; this.name = name; } /// Converts input to a - public static implicit operator ResourceName(int id) { - return new ResourceName(id); - } + public static implicit operator ResourceName(int id) => new ResourceName(id); /// Converts input to a - public static implicit operator ResourceName(string name) { - return new ResourceName(name); - } + public static implicit operator ResourceName(string name) => new ResourceName(name); /// Overloaded operator - public static bool operator <(ResourceName left, ResourceName right) { - return left.CompareTo(right) < 0; - } + public static bool operator <(ResourceName left, ResourceName right) => left.CompareTo(right) < 0; /// Overloaded operator - public static bool operator <=(ResourceName left, ResourceName right) { - return left.CompareTo(right) <= 0; - } + public static bool operator <=(ResourceName left, ResourceName right) => left.CompareTo(right) <= 0; /// Overloaded operator - public static bool operator >(ResourceName left, ResourceName right) { - return left.CompareTo(right) > 0; - } + public static bool operator >(ResourceName left, ResourceName right) => left.CompareTo(right) > 0; /// Overloaded operator - public static bool operator >=(ResourceName left, ResourceName right) { - return left.CompareTo(right) >= 0; - } + public static bool operator >=(ResourceName left, ResourceName right) => left.CompareTo(right) >= 0; /// Overloaded operator - public static bool operator ==(ResourceName left, ResourceName right) { - return left.Equals(right); - } + public static bool operator ==(ResourceName left, ResourceName right) => left.Equals(right); /// Overloaded operator - public static bool operator !=(ResourceName left, ResourceName right) { - return !left.Equals(right); - } + public static bool operator !=(ResourceName left, ResourceName right) => !left.Equals(right); /// public int CompareTo(ResourceName other) { @@ -109,9 +85,7 @@ public int CompareTo(ResourceName other) { } /// - public bool Equals(ResourceName other) { - return CompareTo(other) == 0; - } + public bool Equals(ResourceName other) => CompareTo(other) == 0; /// public override bool Equals(object obj) { @@ -128,8 +102,6 @@ public override int GetHashCode() { } /// - public override string ToString() { - return HasId ? id.ToString() : name; - } + public override string ToString() => HasId ? id.ToString() : name; } } diff --git a/src/W32Resources/Win32Resources.cs b/src/W32Resources/Win32Resources.cs index efd679f6e..2d2d2efbd 100644 --- a/src/W32Resources/Win32Resources.cs +++ b/src/W32Resources/Win32Resources.cs @@ -81,7 +81,7 @@ public class Win32ResourcesUser : Win32Resources { /// public override ResourceDirectory Root { - get { return root; } + get => root; set { var oldValue = Interlocked.Exchange(ref root, value); if (oldValue != value && oldValue != null) @@ -120,7 +120,7 @@ public sealed class Win32ResourcesPE : Win32Resources { /// public override ResourceDirectory Root { - get { return root.Value; } + get => root.Value; set { IDisposable origValue = null; if (root.IsValueInitialized) { @@ -138,9 +138,7 @@ public override ResourceDirectory Root { /// /// Gets the resource reader /// - internal IBinaryReader ResourceReader { - get { return rsrcReader; } - } + internal IBinaryReader ResourceReader => rsrcReader; /// /// Constructor @@ -177,8 +175,8 @@ public Win32ResourcesPE(IPEImage peImage) /// the .rsrc section) or null if we should create one from the resource data /// directory in the optional header. This instance owns the reader. public Win32ResourcesPE(IPEImage peImage, IBinaryReader rsrcReader) { - this.rvaConverter = peImage; - this.dataReader = peImage.CreateFullStream(); + rvaConverter = peImage; + dataReader = peImage.CreateFullStream(); if (rsrcReader != null) this.rsrcReader = rsrcReader; else { From 1748c52f9355002087e309118a322b5df6e46102 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 5 Mar 2018 18:26:26 +0100 Subject: [PATCH 099/511] Target .NET Framework 3.5, Client Profile --- Examples/Examples.csproj | 6 +++++- Examples/app.config | 3 +++ src/ExtensionAttribute.cs | 9 --------- src/dnlib.csproj | 4 ++-- src/dnlib.netstandard.csproj | 1 - 5 files changed, 10 insertions(+), 13 deletions(-) create mode 100644 Examples/app.config delete mode 100644 src/ExtensionAttribute.cs diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 1773222b6..a826e8709 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -10,8 +10,9 @@ Properties dnlib.Examples dnlib.Examples - v2.0 + v3.5 512 + Client x86 @@ -48,6 +49,9 @@ dnlib + + + \ No newline at end of file diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a9749da59..8e094d5d1 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,14 +1,12 @@  - + + Debug AnyCPU - 8.0.30703 - 2.0 {FDFC1237-143F-4919-8318-4926901F4639} Library - Properties dnlib dnlib v3.5 @@ -429,11 +427,4 @@ - \ No newline at end of file From 5056c8016e105653ccf7a69c12b71f69a29cf895 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 16 Mar 2018 21:54:10 +0100 Subject: [PATCH 140/511] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75c52ad90..d1da48f20 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ v3.0 breaking changes - The reader is a struct called `DataReader` and it's not disposable - The reader has `Slice` methods to get another reader (replaces the older `Create` methods) - Since the reader is a struct, pass it by reference to methods if its position should be updated when the method returns - - `DataReader.Position` is now a `uint` and not a `long` so expressions that were `long` could now be `uint` and possibly underflow + - `DataReader.Position` is now a `uint` and not a `long` so expressions that were `long` could now be `uint` and possibly overflow/underflow - `reader.Position + 0xFFFFFFFF` - `reader.Position + someRandomValue` - `var pos = reader.Position;` <-- `pos` is a `uint` and not a `long` From 117c2b50b3177dc5da6cdb58bf0762fc4a495aeb Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 17 Mar 2018 12:05:24 +0100 Subject: [PATCH 141/511] Add a ProgressUpdated writer event --- README.md | 1 + src/DotNet/Writer/Metadata.cs | 99 +++++++++-- src/DotNet/Writer/MetadataEvent.cs | 125 ------------- src/DotNet/Writer/ModuleWriterBase.cs | 188 +++++++++----------- src/DotNet/Writer/ModuleWriterEvent.cs | 150 ---------------- src/DotNet/Writer/NormalMetadata.cs | 9 +- src/DotNet/Writer/PreserveTokensMetadata.cs | 11 +- 7 files changed, 179 insertions(+), 404 deletions(-) diff --git a/README.md b/README.md index d1da48f20..28592f4ce 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ v3.0 breaking changes - The `IRawRow` interface has been removed - The `Constant` table info (`TableInfo`) has an extra padding byte column - `ModuleWriterOptionsBase.Listener` is obsolete, use the new event `ModuleWriterOptionsBase.WriterEvent` instead +- Module writer events related to the current progress have been removed. Use the new event `ModuleWriterOptionsBase.ProgressUpdated` instead - `StrongNameKey`, `PublicKey`, `PublicKeyToken` are immutable classes - `RidList` is a struct - `IBinaryReader`, `IImageStream` have been removed and replaced with new classes diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 5ac776fe1..6656b48b5 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -278,7 +278,7 @@ public enum DebugMetadataKind { /// public sealed class MetadataWriterEventArgs : EventArgs { /// - /// Gets the metadata + /// Gets the metadata writer /// public Metadata Metadata { get; } @@ -298,6 +298,33 @@ public MetadataWriterEventArgs(Metadata metadata, MetadataEvent @event) { } } + /// + /// Metadata writer progress event args + /// + public sealed class MetadataProgressEventArgs : EventArgs { + /// + /// Gets the metadata writer + /// + public Metadata Metadata { get; } + + /// + /// Gets the progress, 0.0 - 1.0 + /// + public double Progress { get; } + + /// + /// Constructor + /// + /// Writer + /// Progress, 0.0 - 1.0 + public MetadataProgressEventArgs(Metadata metadata, double progress) { + if (progress < 0 || progress > 1) + throw new ArgumentOutOfRangeException(nameof(progress)); + Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); + Progress = progress; + } + } + /// /// .NET meta data /// @@ -365,6 +392,11 @@ public abstract class Metadata : IChunk, ISignatureWriterHelper, ITokenCreator, /// public event EventHandler MetadataEvent; + /// + /// Raised when the progress is updated + /// + public event EventHandler ProgressUpdated; + /// /// Gets/sets the logger /// @@ -1221,7 +1253,42 @@ public ByteArrayChunk GetInitialValueChunk(FieldDef fd) { /// Raises /// /// Event - protected void OnMetadataEvent(MetadataEvent evt) => MetadataEvent?.Invoke(this, new MetadataWriterEventArgs(this, evt)); + protected void OnMetadataEvent(MetadataEvent evt) { + RaiseProgress(evt, 0); + MetadataEvent?.Invoke(this, new MetadataWriterEventArgs(this, evt)); + } + + static readonly double[] eventToProgress = new double[(int)Writer.MetadataEvent.EndCreateTables - (int)Writer.MetadataEvent.BeginCreateTables + 1 + 1] { + 0, // BeginCreateTables + 0.00134240009466231,// AllocateTypeDefRids + 0.00257484711254305,// AllocateMemberDefRids + 0.0762721800615359, // MemberDefRidsAllocated + 0.196633787905108, // MemberDefsInitialized + 0.207788892253819, // BeforeSortTables + 0.270543867900699, // MostTablesSorted + 0.451478814851716, // MemberDefCustomAttributesWritten + 0.451478949929206, // BeginAddResources + 0.454664752528583, // EndAddResources + 0.454664887606073, // BeginWriteMethodBodies + 0.992591810143725, // EndWriteMethodBodies + 0.999984331011171, // OnAllTablesSorted + 1, // EndCreateTables + 1,// An extra one so we can get the next base progress without checking the index + }; + + /// + /// Raises the progress event + /// + /// Base event + /// Sub progress + protected void RaiseProgress(MetadataEvent evt, double subProgress) { + subProgress = Math.Min(1, Math.Max(0, subProgress)); + var baseProgress = eventToProgress[(int)evt]; + var nextProgress = eventToProgress[(int)evt + 1]; + var progress = baseProgress + (nextProgress - baseProgress) * subProgress; + progress = Math.Min(1, Math.Max(0, progress)); + ProgressUpdated?.Invoke(this, new MetadataProgressEventArgs(this, progress)); + } /// /// Creates the .NET metadata tables @@ -1337,13 +1404,14 @@ void InitializeTypeDefsAndMemberDefs() { int numTypes = allTypeDefs.Length; int typeNum = 0; int notifyNum = 0; - const int numNotifyEvents = 5; // InitializeTypeDefsAndMemberDefs0 - InitializeTypeDefsAndMemberDefs4 + const int numNotifyEvents = 5; int notifyAfter = numTypes / numNotifyEvents; foreach (var type in allTypeDefs) { if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { - OnMetadataEvent(Writer.MetadataEvent.InitializeTypeDefsAndMemberDefs0 + notifyNum++); - notifyAfter += numTypes / numNotifyEvents; + RaiseProgress(Writer.MetadataEvent.MemberDefRidsAllocated, (double)typeNum / numTypes); + notifyNum++; + notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); } if (type == null) { @@ -1426,8 +1494,6 @@ void InitializeTypeDefsAndMemberDefs() { AddMethodSemantics(prop); } } - while (notifyNum < numNotifyEvents) - OnMetadataEvent(Writer.MetadataEvent.InitializeTypeDefsAndMemberDefs0 + notifyNum++); } /// @@ -1438,14 +1504,15 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { int numTypes = allTypeDefs.Length; int typeNum = 0; int notifyNum = 0; - const int numNotifyEvents = 5; // WriteTypeDefAndMemberDefCustomAttributes0 - WriteTypeDefAndMemberDefCustomAttributes4 + const int numNotifyEvents = 5; int notifyAfter = numTypes / numNotifyEvents; uint rid; foreach (var type in allTypeDefs) { if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { - OnMetadataEvent(Writer.MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes0 + notifyNum++); - notifyAfter += numTypes / numNotifyEvents; + RaiseProgress(Writer.MetadataEvent.MostTablesSorted, (double)typeNum / numTypes); + notifyNum++; + notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); } if (type == null) @@ -1490,8 +1557,6 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { AddCustomDebugInformationList(Table.Property, rid, prop); } } - while (notifyNum < numNotifyEvents) - OnMetadataEvent(Writer.MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes0 + notifyNum++); } /// @@ -1667,7 +1732,8 @@ void WriteMethodBodies() { int numMethods = NumberOfMethods; int methodNum = 0; int notifyNum = 0; - const int numNotifyEvents = 10; // WriteMethodBodies0 - WriteMethodBodies9 + // Writing method bodies is the most expensive part and takes the longest + const int numNotifyEvents = 40; int notifyAfter = numMethods / numNotifyEvents; List methodScopeDebugInfos; @@ -1695,8 +1761,9 @@ void WriteMethodBodies() { continue; if (methodNum++ == notifyAfter && notifyNum < numNotifyEvents) { - OnMetadataEvent(Writer.MetadataEvent.WriteMethodBodies0 + notifyNum++); - notifyAfter += numMethods / numNotifyEvents; + RaiseProgress(Writer.MetadataEvent.BeginWriteMethodBodies, (double)methodNum / numMethods); + notifyNum++; + notifyAfter = (int)((double)numMethods / numNotifyEvents * (notifyNum + 1)); } uint localVarSigTok = 0; @@ -1779,8 +1846,6 @@ void WriteMethodBodies() { } if (serializerMethodContext != null) Free(ref serializerMethodContext); - while (notifyNum < numNotifyEvents) - OnMetadataEvent(Writer.MetadataEvent.WriteMethodBodies0 + notifyNum++); } static bool IsEmptyRootScope(CilBody cilBody, PdbScope scope) { diff --git a/src/DotNet/Writer/MetadataEvent.cs b/src/DotNet/Writer/MetadataEvent.cs index 62a256b6c..20b28dd78 100644 --- a/src/DotNet/Writer/MetadataEvent.cs +++ b/src/DotNet/Writer/MetadataEvent.cs @@ -20,62 +20,12 @@ public enum MetadataEvent { /// AllocateMemberDefRids, - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - AllocateMemberDefRids0, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - AllocateMemberDefRids1, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - AllocateMemberDefRids2, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - AllocateMemberDefRids3, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - AllocateMemberDefRids4, - /// /// The rids of types, fields, methods, events, properties and parameters are /// now known. /// MemberDefRidsAllocated, - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - InitializeTypeDefsAndMemberDefs0, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - InitializeTypeDefsAndMemberDefs1, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - InitializeTypeDefsAndMemberDefs2, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - InitializeTypeDefsAndMemberDefs3, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - InitializeTypeDefsAndMemberDefs4, - /// /// The tables and rows of all types, fields, methods, events, properties and parameters /// have been initialized. Method body RVAs are still not known, and no method has been @@ -94,31 +44,6 @@ public enum MetadataEvent { /// MostTablesSorted, - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteTypeDefAndMemberDefCustomAttributes0, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteTypeDefAndMemberDefCustomAttributes1, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteTypeDefAndMemberDefCustomAttributes2, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteTypeDefAndMemberDefCustomAttributes3, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteTypeDefAndMemberDefCustomAttributes4, - /// /// Custom attributes of all types, fields, methods, events, properties and parameters /// have now been written. @@ -140,56 +65,6 @@ public enum MetadataEvent { /// BeginWriteMethodBodies, - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies0, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies1, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies2, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies3, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies4, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies5, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies6, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies7, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies8, - - /// - /// Sent by the metadata writer so a UI can update its progress bar - /// - WriteMethodBodies9, - /// /// All method bodies have been written. Their RVAs are still not known. /// diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 63b1c2b53..364c3cdad 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -39,6 +39,33 @@ public ModuleWriterEventArgs(ModuleWriterBase writer, ModuleWriterEvent @event) } } + /// + /// Module writer progress event args + /// + public sealed class ModuleWriterProgressEventArgs : EventArgs { + /// + /// Gets the writer ( or ) + /// + public ModuleWriterBase Writer { get; } + + /// + /// Gets the progress, 0.0 - 1.0 + /// + public double Progress { get; } + + /// + /// Constructor + /// + /// Writer + /// Progress, 0.0 - 1.0 + public ModuleWriterProgressEventArgs(ModuleWriterBase writer, double progress) { + if (progress < 0 || progress > 1) + throw new ArgumentOutOfRangeException(nameof(progress)); + Writer = writer ?? throw new ArgumentNullException(nameof(writer)); + Progress = progress; + } + } + /// /// Common module writer options base class /// @@ -68,9 +95,14 @@ public IModuleWriterListener Listener { /// the file, eg. add extra metadata, encrypt methods, etc. /// public event EventHandler WriterEvent; - internal void RaiseEvent(object sender, ModuleWriterEventArgs e) => WriterEvent?.Invoke(sender, e); + /// + /// Raised when the progress is updated + /// + public event EventHandler ProgressUpdated; + internal void RaiseEvent(object sender, ModuleWriterProgressEventArgs e) => ProgressUpdated?.Invoke(sender, e); + /// /// Gets/sets the logger. If this is null, any errors result in a /// being thrown. To disable this behavior, either @@ -594,6 +626,7 @@ protected void CreateMetadataChunks(ModuleDef module) { metadata = Metadata.Create(module, constants, methodBodies, netResources, TheOptions.MetadataOptions, debugKind); metadata.Logger = TheOptions.MetadataLogger ?? this; metadata.MetadataEvent += Metadata_MetadataEvent; + metadata.ProgressUpdated += Metadata_ProgressUpdated; // StrongNamePublicKey is used if the user wants to override the assembly's // public key or when enhanced strong naming the assembly. @@ -901,50 +934,10 @@ void Metadata_MetadataEvent(object sender, MetadataWriterEventArgs e) { OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids); break; - case MetadataEvent.AllocateMemberDefRids0: - OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids0); - break; - - case MetadataEvent.AllocateMemberDefRids1: - OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids1); - break; - - case MetadataEvent.AllocateMemberDefRids2: - OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids2); - break; - - case MetadataEvent.AllocateMemberDefRids3: - OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids3); - break; - - case MetadataEvent.AllocateMemberDefRids4: - OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids4); - break; - case MetadataEvent.MemberDefRidsAllocated: OnWriterEvent(ModuleWriterEvent.MDMemberDefRidsAllocated); break; - case MetadataEvent.InitializeTypeDefsAndMemberDefs0: - OnWriterEvent(ModuleWriterEvent.MDInitializeTypeDefsAndMemberDefs0); - break; - - case MetadataEvent.InitializeTypeDefsAndMemberDefs1: - OnWriterEvent(ModuleWriterEvent.MDInitializeTypeDefsAndMemberDefs1); - break; - - case MetadataEvent.InitializeTypeDefsAndMemberDefs2: - OnWriterEvent(ModuleWriterEvent.MDInitializeTypeDefsAndMemberDefs2); - break; - - case MetadataEvent.InitializeTypeDefsAndMemberDefs3: - OnWriterEvent(ModuleWriterEvent.MDInitializeTypeDefsAndMemberDefs3); - break; - - case MetadataEvent.InitializeTypeDefsAndMemberDefs4: - OnWriterEvent(ModuleWriterEvent.MDInitializeTypeDefsAndMemberDefs4); - break; - case MetadataEvent.MemberDefsInitialized: OnWriterEvent(ModuleWriterEvent.MDMemberDefsInitialized); break; @@ -957,26 +950,6 @@ void Metadata_MetadataEvent(object sender, MetadataWriterEventArgs e) { OnWriterEvent(ModuleWriterEvent.MDMostTablesSorted); break; - case MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes0: - OnWriterEvent(ModuleWriterEvent.MDWriteTypeDefAndMemberDefCustomAttributes0); - break; - - case MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes1: - OnWriterEvent(ModuleWriterEvent.MDWriteTypeDefAndMemberDefCustomAttributes1); - break; - - case MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes2: - OnWriterEvent(ModuleWriterEvent.MDWriteTypeDefAndMemberDefCustomAttributes2); - break; - - case MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes3: - OnWriterEvent(ModuleWriterEvent.MDWriteTypeDefAndMemberDefCustomAttributes3); - break; - - case MetadataEvent.WriteTypeDefAndMemberDefCustomAttributes4: - OnWriterEvent(ModuleWriterEvent.MDWriteTypeDefAndMemberDefCustomAttributes4); - break; - case MetadataEvent.MemberDefCustomAttributesWritten: OnWriterEvent(ModuleWriterEvent.MDMemberDefCustomAttributesWritten); break; @@ -993,46 +966,6 @@ void Metadata_MetadataEvent(object sender, MetadataWriterEventArgs e) { OnWriterEvent(ModuleWriterEvent.MDBeginWriteMethodBodies); break; - case MetadataEvent.WriteMethodBodies0: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies0); - break; - - case MetadataEvent.WriteMethodBodies1: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies1); - break; - - case MetadataEvent.WriteMethodBodies2: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies2); - break; - - case MetadataEvent.WriteMethodBodies3: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies3); - break; - - case MetadataEvent.WriteMethodBodies4: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies4); - break; - - case MetadataEvent.WriteMethodBodies5: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies5); - break; - - case MetadataEvent.WriteMethodBodies6: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies6); - break; - - case MetadataEvent.WriteMethodBodies7: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies7); - break; - - case MetadataEvent.WriteMethodBodies8: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies8); - break; - - case MetadataEvent.WriteMethodBodies9: - OnWriterEvent(ModuleWriterEvent.MDWriteMethodBodies9); - break; - case MetadataEvent.EndWriteMethodBodies: OnWriterEvent(ModuleWriterEvent.MDEndWriteMethodBodies); break; @@ -1046,15 +979,66 @@ void Metadata_MetadataEvent(object sender, MetadataWriterEventArgs e) { break; default: + Debug.Fail($"Unknown MD event: {e.Event}"); break; } } + void Metadata_ProgressUpdated(object sender, MetadataProgressEventArgs e) => + RaiseProgress(ModuleWriterEvent.MDBeginCreateTables, ModuleWriterEvent.MDEndCreateTables + 1, e.Progress); + /// /// Raises a writer event /// /// Event - protected void OnWriterEvent(ModuleWriterEvent evt) => TheOptions.RaiseEvent(this, new ModuleWriterEventArgs(this, evt)); + protected void OnWriterEvent(ModuleWriterEvent evt) { + RaiseProgress(evt, 0); + TheOptions.RaiseEvent(this, new ModuleWriterEventArgs(this, evt)); + } + + static readonly double[] eventToProgress = new double[(int)ModuleWriterEvent.End - (int)ModuleWriterEvent.Begin + 1 + 1] { + 0,// Begin + 0.00128048488389907,// PESectionsCreated + 0.0524625293056615, // ChunksCreated + 0.0531036610555682, // ChunksAddedToSections + 0.0535679983835939, // MDBeginCreateTables + 0.0547784058004697, // MDAllocateTypeDefRids + 0.0558606342971218, // MDAllocateMemberDefRids + 0.120553993799033, // MDMemberDefRidsAllocated + 0.226210300699921, // MDMemberDefsInitialized + 0.236002648477671, // MDBeforeSortTables + 0.291089703426468, // MDMostTablesSorted + 0.449919748849947, // MDMemberDefCustomAttributesWritten + 0.449919985998736, // MDBeginAddResources + 0.452716444513587, // MDEndAddResources + 0.452716681662375, // MDBeginWriteMethodBodies + 0.924922132195272, // MDEndWriteMethodBodies + 0.931410404476231, // MDOnAllTablesSorted + 0.931425463424305, // MDEndCreateTables + 0.932072998191503, // BeginWritePdb + 0.932175327893773, // EndWritePdb + 0.932175446468167, // BeginCalculateRvasAndFileOffsets + 0.954646479929387, // EndCalculateRvasAndFileOffsets + 0.95492263969368, // BeginWriteChunks + 0.980563166714175, // EndWriteChunks + 0.980563403862964, // BeginStrongNameSign + 0.980563403862964, // EndStrongNameSign + 0.980563522437358, // BeginWritePEChecksum + 0.999975573674777, // EndWritePEChecksum + 1, // End + 1,// An extra one so we can get the next base progress without checking the index + }; + + void RaiseProgress(ModuleWriterEvent evt, double subProgress) => RaiseProgress(evt, evt + 1, subProgress); + + void RaiseProgress(ModuleWriterEvent evt, ModuleWriterEvent nextEvt, double subProgress) { + subProgress = Math.Min(1, Math.Max(0, subProgress)); + var baseProgress = eventToProgress[(int)evt]; + var nextProgress = eventToProgress[(int)nextEvt]; + var progress = baseProgress + (nextProgress - baseProgress) * subProgress; + progress = Math.Min(1, Math.Max(0, progress)); + TheOptions.RaiseEvent(this, new ModuleWriterProgressEventArgs(this, progress)); + } ILogger GetLogger() => TheOptions.Logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; diff --git a/src/DotNet/Writer/ModuleWriterEvent.cs b/src/DotNet/Writer/ModuleWriterEvent.cs index 9a39a24bf..59899fdef 100644 --- a/src/DotNet/Writer/ModuleWriterEvent.cs +++ b/src/DotNet/Writer/ModuleWriterEvent.cs @@ -43,36 +43,6 @@ public enum ModuleWriterEvent { /// MDAllocateMemberDefRids, - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDAllocateMemberDefRids0, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDAllocateMemberDefRids1, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDAllocateMemberDefRids2, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDAllocateMemberDefRids3, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDAllocateMemberDefRids4, - /// /// Original event: . /// The rids of types, fields, methods, events, properties and parameters are @@ -80,36 +50,6 @@ public enum ModuleWriterEvent { /// MDMemberDefRidsAllocated, - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDInitializeTypeDefsAndMemberDefs0, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDInitializeTypeDefsAndMemberDefs1, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDInitializeTypeDefsAndMemberDefs2, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDInitializeTypeDefsAndMemberDefs3, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDInitializeTypeDefsAndMemberDefs4, - /// /// Original event: . /// The tables and rows of all types, fields, methods, events, properties and parameters @@ -131,36 +71,6 @@ public enum ModuleWriterEvent { /// MDMostTablesSorted, - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteTypeDefAndMemberDefCustomAttributes0, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteTypeDefAndMemberDefCustomAttributes1, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteTypeDefAndMemberDefCustomAttributes2, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteTypeDefAndMemberDefCustomAttributes3, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteTypeDefAndMemberDefCustomAttributes4, - /// /// Original event: . /// Custom attributes of all types, fields, methods, events, properties and parameters @@ -186,66 +96,6 @@ public enum ModuleWriterEvent { /// MDBeginWriteMethodBodies, - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies0, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies1, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies2, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies3, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies4, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies5, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies6, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies7, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies8, - - /// - /// Original event: . - /// Sent by the metadata writer so a UI can update its progress bar - /// - MDWriteMethodBodies9, - /// /// Original event: . /// All method bodies have been written. Their RVAs are still not known. diff --git a/src/DotNet/Writer/NormalMetadata.cs b/src/DotNet/Writer/NormalMetadata.cs index 689bf8573..b714dc558 100644 --- a/src/DotNet/Writer/NormalMetadata.cs +++ b/src/DotNet/Writer/NormalMetadata.cs @@ -48,7 +48,7 @@ protected override void AllocateMemberDefRids() { int numTypes = allTypeDefs.Length; int typeNum = 0; int notifyNum = 0; - const int numNotifyEvents = 5; // AllocateMemberDefRids0 - AllocateMemberDefRids4 + const int numNotifyEvents = 5; int notifyAfter = numTypes / numNotifyEvents; uint fieldListRid = 1, methodListRid = 1; @@ -56,8 +56,9 @@ protected override void AllocateMemberDefRids() { uint paramListRid = 1; foreach (var type in allTypeDefs) { if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids0 + notifyNum++); - notifyAfter += numTypes / numNotifyEvents; + RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, (double)typeNum / numTypes); + notifyNum++; + notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); } if (type == null) @@ -120,8 +121,6 @@ protected override void AllocateMemberDefRids() { } } } - while (notifyNum < numNotifyEvents) - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids0 + notifyNum++); } /// diff --git a/src/DotNet/Writer/PreserveTokensMetadata.cs b/src/DotNet/Writer/PreserveTokensMetadata.cs index 6c0a15cfe..6d46c5f6b 100644 --- a/src/DotNet/Writer/PreserveTokensMetadata.cs +++ b/src/DotNet/Writer/PreserveTokensMetadata.cs @@ -525,7 +525,8 @@ void InitializeMethodSpecTableRows() { protected override void AllocateMemberDefRids() { FindMemberDefs(); - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids0); + const int numEvents = 5; + RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 0.0 / numEvents); for (int i = 1; i <= fieldDefInfos.TableSize; i++) { if ((uint)i != tablesHeap.FieldTable.Create(new RawFieldRow())) @@ -558,7 +559,7 @@ protected override void AllocateMemberDefRids() { SortEvents(); SortProperties(); - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids1); + RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 1.0 / numEvents); if (fieldDefInfos.NeedPtrTable) { for (int i = 0; i < fieldDefInfos.Count; i++) { @@ -604,14 +605,14 @@ protected override void AllocateMemberDefRids() { } } - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids2); + RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 2.0 / numEvents); InitializeMethodAndFieldList(); InitializeParamList(); InitializeEventMap(); InitializePropertyMap(); - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids3); + RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 3.0 / numEvents); // We must re-use deleted event/property rows after we've initialized // the event/prop map tables. @@ -620,7 +621,7 @@ protected override void AllocateMemberDefRids() { if (propertyDefInfos.NeedPtrTable) ReUseDeletedPropertyRows(); - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids4); + RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 4.0 / numEvents); InitializeTypeRefTableRows(); InitializeTypeSpecTableRows(); From d8b463c93dfc1e9fd20d9d76449c4bc65b1c0190 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 17 Mar 2018 12:05:35 +0100 Subject: [PATCH 142/511] Throw an IO exception --- src/IO/DataReader.cs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 478bbc916..750984ca1 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -104,7 +104,7 @@ void VerifyState() { void ThrowDataReaderException(string message) => throw new DataReaderException(message); void ThrowInvalidOperationException() => throw new InvalidOperationException(); void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName); - void ThrowArgumentOutOfRangeException(string paramName) => throw new ArgumentOutOfRangeException(paramName); + void ThrowInvalidArgument(string paramName) => throw new DataReaderException("Invalid argument value"); /// /// Resets the reader so it points to the start of the data @@ -119,7 +119,7 @@ void VerifyState() { /// public DataReader Slice(uint start, uint length) { if ((ulong)start + length > Length) - ThrowArgumentOutOfRangeException(nameof(length)); + ThrowInvalidArgument(nameof(length)); return new DataReader(stream, startOffset + start, length); } @@ -130,7 +130,7 @@ public DataReader Slice(uint start, uint length) { /// public DataReader Slice(uint start) { if (start > Length) - ThrowArgumentOutOfRangeException(nameof(start)); + ThrowInvalidArgument(nameof(start)); return Slice(start, Length - start); } @@ -142,9 +142,9 @@ public DataReader Slice(uint start) { /// public DataReader Slice(int start, int length) { if (start < 0) - ThrowArgumentOutOfRangeException(nameof(start)); + ThrowInvalidArgument(nameof(start)); if (length < 0) - ThrowArgumentOutOfRangeException(nameof(length)); + ThrowInvalidArgument(nameof(length)); return Slice((uint)start, (uint)length); } @@ -155,9 +155,9 @@ public DataReader Slice(int start, int length) { /// public DataReader Slice(int start) { if (start < 0) - ThrowArgumentOutOfRangeException(nameof(start)); + ThrowInvalidArgument(nameof(start)); if ((uint)start > Length) - ThrowArgumentOutOfRangeException(nameof(start)); + ThrowInvalidArgument(nameof(start)); return Slice((uint)start, Length - (uint)start); } @@ -417,7 +417,7 @@ public decimal ReadDecimal() { /// public string ReadUtf16String(int chars) { if (chars < 0) - ThrowArgumentOutOfRangeException(nameof(chars)); + ThrowInvalidArgument(nameof(chars)); if (chars == 0) return string.Empty; VerifyState(); @@ -440,7 +440,7 @@ public unsafe void ReadBytes(void* destination, int length) { if (destination == null) ThrowArgumentNullException(nameof(destination)); if (length < 0) - ThrowArgumentOutOfRangeException(nameof(length)); + ThrowInvalidArgument(nameof(length)); // This is also true if 'this' is the 'default' instance ('stream' is null) if (length == 0) return; @@ -463,9 +463,9 @@ public void ReadBytes(byte[] destination, int destinationIndex, int length) { if (destination == null) ThrowArgumentNullException(nameof(destination)); if (destinationIndex < 0) - ThrowArgumentOutOfRangeException(nameof(destinationIndex)); + ThrowInvalidArgument(nameof(destinationIndex)); if (length < 0) - ThrowArgumentOutOfRangeException(nameof(length)); + ThrowInvalidArgument(nameof(length)); // This is also true if 'this' is the 'default' instance ('stream' is null) if (length == 0) return; @@ -485,7 +485,7 @@ public void ReadBytes(byte[] destination, int destinationIndex, int length) { /// public byte[] ReadBytes(int length) { if (length < 0) - ThrowArgumentOutOfRangeException(nameof(length)); + ThrowInvalidArgument(nameof(length)); if (length == 0) return Array2.Empty(); var data = new byte[length]; @@ -756,13 +756,13 @@ public string TryReadZeroTerminatedString(Encoding encoding) { /// public string ReadString(int byteCount, Encoding encoding) { if (byteCount < 0) - ThrowArgumentOutOfRangeException(nameof(byteCount)); + ThrowInvalidArgument(nameof(byteCount)); if (encoding == null) ThrowArgumentNullException(nameof(encoding)); if (byteCount == 0) return string.Empty; if ((uint)byteCount > Length) - ThrowArgumentOutOfRangeException(nameof(byteCount)); + ThrowInvalidArgument(nameof(byteCount)); VerifyState(); var currentOffset = this.currentOffset; var value = stream.ReadString(currentOffset, byteCount, encoding); From d4608c94230ed8fbcab6e3bbb9abf6ecba0403ad Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 17 Mar 2018 12:05:49 +0100 Subject: [PATCH 143/511] Use a new DataWriter struct --- README.md | 1 + src/DotNet/Emit/Instruction.cs | 41 ++++--- src/DotNet/IAssemblyResolver.cs | 1 - src/DotNet/Utils.cs | 14 ++- src/DotNet/Writer/DataWriter.cs | 83 +++++++++++++ src/DotNet/Writer/MaxStackCalculator.cs | 77 +++++++----- src/DotNet/Writer/Metadata.cs | 17 ++- src/DotNet/Writer/MethodBodyWriter.cs | 53 +++++---- src/DotNet/Writer/MethodBodyWriterBase.cs | 135 ++++++++++++---------- src/IO/DataStreamFactory.cs | 1 + src/dnlib.csproj | 1 + 11 files changed, 284 insertions(+), 140 deletions(-) create mode 100644 src/DotNet/Writer/DataWriter.cs diff --git a/README.md b/README.md index 28592f4ce..1e6b5a085 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ v3.0 breaking changes - `var pos = reader.Position;` <-- `pos` is a `uint` and not a `long` - `DataReader.Position` only accepts valid values and will throw (an `IOException`) if you set it to an invalid position - `FileOffset` is `uint`, used to be `long` +- `MethodBodyWriterBase` uses `DataWriter` instead of `BinaryWriter` (all virtual methods) Examples -------- diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index cb843fe93..dcdb567b3 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -378,17 +378,17 @@ public void UpdateStack(ref int stack, bool methodHasReturnValue) { public void CalculateStackUsage(bool methodHasReturnValue, out int pushes, out int pops) { var opCode = OpCode; if (opCode.FlowControl == FlowControl.Call) - CalculateStackUsageCall(opCode, out pushes, out pops); + CalculateStackUsageCall(opCode.Code, out pushes, out pops); else CalculateStackUsageNonCall(opCode, methodHasReturnValue, out pushes, out pops); } - void CalculateStackUsageCall(OpCode opCode, out int pushes, out int pops) { + void CalculateStackUsageCall(Code code, out int pushes, out int pops) { pushes = 0; pops = 0; // It doesn't push or pop anything. The stack should be empty when JMP is executed. - if (opCode.Code == Code.Jmp) + if (code == Code.Jmp) return; MethodSig sig; @@ -400,28 +400,23 @@ void CalculateStackUsageCall(OpCode opCode, out int pushes, out int pops) { if (sig == null) return; bool implicitThis = sig.ImplicitThis; - if (!IsSystemVoid(sig.RetType) || (opCode.Code == Code.Newobj && sig.HasThis)) + if (!IsSystemVoid(sig.RetType) || (code == Code.Newobj && sig.HasThis)) pushes++; pops += sig.Params.Count; var paramsAfterSentinel = sig.ParamsAfterSentinel; if (paramsAfterSentinel != null) pops += paramsAfterSentinel.Count; - if (implicitThis && opCode.Code != Code.Newobj) + if (implicitThis && code != Code.Newobj) pops++; - if (opCode.Code == Code.Calli) + if (code == Code.Calli) pops++; } void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int pushes, out int pops) { - StackBehaviour stackBehavior; - - pushes = 0; - pops = 0; - - stackBehavior = opCode.StackBehaviourPush; - switch (stackBehavior) { + switch (opCode.StackBehaviourPush) { case StackBehaviour.Push0: + pushes = 0; break; case StackBehaviour.Push1: @@ -430,27 +425,28 @@ void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int push case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: - pushes++; + pushes = 1; break; case StackBehaviour.Push1_push1: - pushes += 2; + pushes = 2; break; case StackBehaviour.Varpush: // only call, calli, callvirt which are handled elsewhere default: + pushes = 0; break; } - stackBehavior = opCode.StackBehaviourPop; - switch (stackBehavior) { + switch (opCode.StackBehaviourPop) { case StackBehaviour.Pop0: + pops = 0; break; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: - pops++; + pops = 1; break; case StackBehaviour.Pop1_pop1: @@ -461,7 +457,7 @@ void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int push case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: - pops += 2; + pops = 2; break; case StackBehaviour.Popi_popi_popi: @@ -471,7 +467,7 @@ void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int push case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: case StackBehaviour.Popref_popi_pop1: - pops += 3; + pops = 3; break; case StackBehaviour.PopAll: @@ -480,10 +476,13 @@ void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int push case StackBehaviour.Varpop: // call, calli, callvirt, newobj (all handled elsewhere), and ret if (hasReturnValue) - pops++; + pops = 1; + else + pops = 0; break; default: + pops = 0; break; } } diff --git a/src/DotNet/IAssemblyResolver.cs b/src/DotNet/IAssemblyResolver.cs index fd584081a..8758ae452 100644 --- a/src/DotNet/IAssemblyResolver.cs +++ b/src/DotNet/IAssemblyResolver.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System; using System.Reflection; namespace dnlib.DotNet { diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index df60ecea0..72cb61ead 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -160,7 +160,19 @@ internal static int CompareTo(byte[] a, byte[] b) { /// First /// Second /// true if same, false otherwise - internal static bool Equals(byte[] a, byte[] b) => CompareTo(a, b) == 0; + internal static bool Equals(byte[] a, byte[] b) { + if (a == b) + return true; + if (a == null || b == null) + return false; + if (a.Length != b.Length) + return false; + for (int i = 0; i < a.Length; i++) { + if (a[i] != b[i]) + return false; + } + return true; + } /// /// Gets the hash code of a byte array diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs new file mode 100644 index 000000000..b290d599f --- /dev/null +++ b/src/DotNet/Writer/DataWriter.cs @@ -0,0 +1,83 @@ +// dnlib: See LICENSE.txt for more info + +using System.Diagnostics; + +namespace dnlib.DotNet.Writer { +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + /// + /// Writes data + /// + public unsafe struct DataWriter { + public int Position => position; + + readonly byte[] data; + int position; + + public DataWriter(byte[] data) { + this.data = data; + position = 0; + } + + public void Write(sbyte value) => data[position++] = (byte)value; + public void Write(byte value) => data[position++] = value; + + public void Write(short value) { + data[position++] = (byte)value; + data[position++] = (byte)(value >> 8); + } + + public void Write(ushort value) { + data[position++] = (byte)value; + data[position++] = (byte)(value >> 8); + } + + public void Write(int value) { + Debug.Assert(this.position + 4 <= data.Length); + var position = this.position; + fixed (byte* p = data) + *(int*)(p + position) = value; + this.position = position + 4; + } + + public void Write(uint value) { + Debug.Assert(this.position + 4 <= data.Length); + var position = this.position; + fixed (byte* p = data) + *(uint*)(p + position) = value; + this.position = position + 4; + } + + public void Write(long value) { + Debug.Assert(this.position + 8 <= data.Length); + var position = this.position; + fixed (byte* p = data) + *(long*)(p + position) = value; + this.position = position + 8; + } + + public void Write(ulong value) { + Debug.Assert(this.position + 8 <= data.Length); + var position = this.position; + fixed (byte* p = data) + *(ulong*)(p + position) = value; + this.position = position + 8; + } + + public void Write(float value) { + Debug.Assert(this.position + 4 <= data.Length); + var position = this.position; + fixed (byte* p = data) + *(float*)(p + position) = value; + this.position = position + 4; + } + + public void Write(double value) { + Debug.Assert(this.position + 8 <= data.Length); + var position = this.position; + fixed (byte* p = data) + *(double*)(p + position) = value; + this.position = position + 8; + } + } +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member +} diff --git a/src/DotNet/Writer/MaxStackCalculator.cs b/src/DotNet/Writer/MaxStackCalculator.cs index 60b4c1fab..5e3788bb6 100644 --- a/src/DotNet/Writer/MaxStackCalculator.cs +++ b/src/DotNet/Writer/MaxStackCalculator.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System; using System.Collections.Generic; using dnlib.DotNet.Emit; @@ -13,7 +12,8 @@ public struct MaxStackCalculator { IList instructions; IList exceptionHandlers; readonly Dictionary stackHeights; - int errors; + bool hasError; + int currentMaxStack; /// /// Gets max stack value @@ -42,40 +42,56 @@ public static bool GetMaxStack(IList instructions, IList(); - errors = 0; + hasError = false; + currentMaxStack = 0; } MaxStackCalculator(IList instructions, IList exceptionHandlers) { this.instructions = instructions; this.exceptionHandlers = exceptionHandlers; stackHeights = new Dictionary(); - errors = 0; + hasError = false; + currentMaxStack = 0; } internal void Reset(IList instructions, IList exceptionHandlers) { this.instructions = instructions; this.exceptionHandlers = exceptionHandlers; stackHeights.Clear(); - errors = 0; + hasError = false; + currentMaxStack = 0; } internal bool Calculate(out uint maxStack) { - foreach (var eh in exceptionHandlers) { + var exceptionHandlers = this.exceptionHandlers; + var stackHeights = this.stackHeights; + for (int i = 0; i < exceptionHandlers.Count; i++) { + var eh = exceptionHandlers[i]; if (eh == null) continue; - if (eh.TryStart != null) - stackHeights[eh.TryStart] = 0; - if (eh.FilterStart != null) - stackHeights[eh.FilterStart] = 1; - if (eh.HandlerStart != null) { + Instruction instr; + if ((instr = eh.TryStart) != null) + stackHeights[instr] = 0; + if ((instr = eh.FilterStart) != null) { + stackHeights[instr] = 1; + currentMaxStack = 1; + } + if ((instr = eh.HandlerStart) != null) { bool pushed = eh.HandlerType == ExceptionHandlerType.Catch || eh.HandlerType == ExceptionHandlerType.Filter; - stackHeights[eh.HandlerStart] = pushed ? 1 : 0; + if (pushed) { + stackHeights[instr] = 1; + currentMaxStack = 1; + } + else + stackHeights[instr] = 0; } } int stack = 0; bool resetStack = false; - foreach (var instr in instructions) { + var instructions = this.instructions; + for (int i = 0; i < instructions.Count; i++) { + var instr = instructions[i]; if (instr == null) continue; @@ -84,10 +100,11 @@ internal bool Calculate(out uint maxStack) { resetStack = false; } stack = WriteStack(instr, stack); - - if (instr.OpCode.Code == Code.Jmp) { + var opCode = instr.OpCode; + var code = opCode.Code; + if (code == Code.Jmp) { if (stack != 0) - errors++; + hasError = true; } else { instr.CalculateStackUsage(out int pushes, out int pops); @@ -96,33 +113,33 @@ internal bool Calculate(out uint maxStack) { else { stack -= pops; if (stack < 0) { - errors++; + hasError = true; stack = 0; } stack += pushes; } } if (stack < 0) { - errors++; + hasError = true; stack = 0; } - switch (instr.OpCode.FlowControl) { + switch (opCode.FlowControl) { case FlowControl.Branch: WriteStack(instr.Operand as Instruction, stack); resetStack = true; break; case FlowControl.Call: - if (instr.OpCode.Code == Code.Jmp) + if (code == Code.Jmp) resetStack = true; break; case FlowControl.Cond_Branch: - if (instr.OpCode.Code == Code.Switch) { + if (code == Code.Switch) { if (instr.Operand is IList targets) { - foreach (var target in targets) - WriteStack(target, stack); + for (int j = 0; j < targets.Count; j++) + WriteStack(targets[j], stack); } } else @@ -136,24 +153,24 @@ internal bool Calculate(out uint maxStack) { } } - stack = 0; - foreach (var v in stackHeights.Values) - stack = Math.Max(stack, v); - maxStack = (uint)stack; - return errors == 0; + maxStack = (uint)currentMaxStack; + return !hasError; } int WriteStack(Instruction instr, int stack) { if (instr == null) { - errors++; + hasError = true; return stack; } + var stackHeights = this.stackHeights; if (stackHeights.TryGetValue(instr, out int stack2)) { if (stack != stack2) - errors++; + hasError = true; return stack2; } stackHeights[instr] = stack; + if (stack > currentMaxStack) + currentMaxStack = stack; return stack; } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 6656b48b5..5fb57653e 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -1736,6 +1736,10 @@ void WriteMethodBodies() { const int numNotifyEvents = 40; int notifyAfter = numMethods / numNotifyEvents; + var debugMetadata = this.debugMetadata; + var methodBodies = this.methodBodies; + var methodToBody = this.methodToBody; + List methodScopeDebugInfos; List scopeStack; SerializerMethodContext serializerMethodContext; @@ -1756,7 +1760,9 @@ void WriteMethodBodies() { if (type == null) continue; - foreach (var method in type.Methods) { + var methods = type.Methods; + for (int i = 0; i < methods.Count; i++) { + var method = methods[i]; if (method == null) continue; @@ -1767,7 +1773,6 @@ void WriteMethodBodies() { } uint localVarSigTok = 0; - uint rid = GetRid(method); var cilBody = method.Body; if (cilBody != null) { @@ -1788,6 +1793,8 @@ void WriteMethodBodies() { } if (debugMetadata != null) { + uint rid = GetRid(method); + if (cilBody != null) { var pdbMethod = cilBody.PdbMethod; if (pdbMethod != null) { @@ -1811,9 +1818,10 @@ void WriteMethodBodies() { } } } + + // Always add CDIs even if it has no managed method body + AddCustomDebugInformationList(method, rid, localVarSigTok); } - // Always add CDIs even if it has no managed method body - AddCustomDebugInformationList(method, rid, localVarSigTok); } } if (debugMetadata != null) { @@ -2889,6 +2897,7 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { } void AddCustomDebugInformationList(MethodDef method, uint rid, uint localVarSigToken) { + Debug.Assert(debugMetadata != null); if (debugMetadata == null) return; var serializerMethodContext = AllocSerializerMethodContext(); diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 4e23d76bc..5c7c62b1f 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -1,9 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; -using System.IO; -using System.Text; using dnlib.DotNet.Emit; namespace dnlib.DotNet.Writer { @@ -144,12 +142,12 @@ void WriteFatHeader() { flags |= 0x10; code = new byte[12 + codeSize]; - var writer = new BinaryWriter(new MemoryStream(code), Encoding.UTF8); + var writer = new DataWriter(code); writer.Write(flags); writer.Write((ushort)maxStack); writer.Write(codeSize); writer.Write(localVarSigTok = helper.GetToken(GetLocals(), cilBody.LocalVarSigTok).Raw); - if (WriteInstructions(writer) != codeSize) + if (WriteInstructions(ref writer) != codeSize) Error("Didn't write all code bytes"); } @@ -163,29 +161,28 @@ IList GetLocals() { void WriteTinyHeader() { localVarSigTok = 0; code = new byte[1 + codeSize]; - var writer = new BinaryWriter(new MemoryStream(code), Encoding.UTF8); + var writer = new DataWriter(code); writer.Write((byte)((codeSize << 2) | 2)); - if (WriteInstructions(writer) != codeSize) + if (WriteInstructions(ref writer) != codeSize) Error("Didn't write all code bytes"); } void WriteExceptionHandlers() { - var outStream = new MemoryStream(); - var writer = new BinaryWriter(outStream, Encoding.UTF8); if (NeedFatExceptionClauses()) - WriteFatExceptionClauses(writer); + extraSections = WriteFatExceptionClauses(); else - WriteSmallExceptionClauses(writer); - extraSections = outStream.ToArray(); + extraSections = WriteSmallExceptionClauses(); } bool NeedFatExceptionClauses() { // Size must fit in a byte, and since one small exception record is 12 bytes // and header is 4 bytes: x*12+4 <= 255 ==> x <= 20 + var exceptionHandlers = this.exceptionHandlers; if (exceptionHandlers.Count > 20) return true; - foreach (var eh in exceptionHandlers) { + for (int i = 0; i < exceptionHandlers.Count; i++) { + var eh = exceptionHandlers[i]; if (!FitsInSmallExceptionClause(eh.TryStart, eh.TryEnd)) return true; if (!FitsInSmallExceptionClause(eh.HandlerStart, eh.HandlerEnd)) @@ -209,14 +206,17 @@ uint GetOffset2(Instruction instr) { return GetOffset(instr); } - void WriteFatExceptionClauses(BinaryWriter writer) { + byte[] WriteFatExceptionClauses() { const int maxExceptionHandlers = (0x00FFFFFF - 4) / 24; + var exceptionHandlers = this.exceptionHandlers; int numExceptionHandlers = exceptionHandlers.Count; if (numExceptionHandlers > maxExceptionHandlers) { Error("Too many exception handlers"); numExceptionHandlers = maxExceptionHandlers; } + var data = new byte[numExceptionHandlers * 24 + 4]; + var writer = new DataWriter(data); writer.Write((((uint)numExceptionHandlers * 24 + 4) << 8) | 0x41); for (int i = 0; i < numExceptionHandlers; i++) { var eh = exceptionHandlers[i]; @@ -245,16 +245,23 @@ void WriteFatExceptionClauses(BinaryWriter writer) { else writer.Write(0); } + + if (writer.Position != data.Length) + throw new InvalidOperationException(); + return data; } - void WriteSmallExceptionClauses(BinaryWriter writer) { + byte[] WriteSmallExceptionClauses() { const int maxExceptionHandlers = (0xFF - 4) / 12; + var exceptionHandlers = this.exceptionHandlers; int numExceptionHandlers = exceptionHandlers.Count; if (numExceptionHandlers > maxExceptionHandlers) { Error("Too many exception handlers"); numExceptionHandlers = maxExceptionHandlers; } + var data = new byte[numExceptionHandlers * 12 + 4]; + var writer = new DataWriter(data); writer.Write((((uint)numExceptionHandlers * 12 + 4) << 8) | 1); for (int i = 0; i < numExceptionHandlers; i++) { var eh = exceptionHandlers[i]; @@ -283,27 +290,31 @@ void WriteSmallExceptionClauses(BinaryWriter writer) { else writer.Write(0); } + + if (writer.Position != data.Length) + throw new InvalidOperationException(); + return data; } /// protected override void ErrorImpl(string message) => helper.Error(message); /// - protected override void WriteInlineField(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineField(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineMethod(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineMethod(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineSig(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineSig(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineString(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineString(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineTok(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineTok(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineType(BinaryWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineType(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); } } diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index 898cd3041..ce499ff54 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; -using System.IO; +using System.Collections.Generic; using dnlib.DotNet.Emit; namespace dnlib.DotNet.Writer { @@ -99,7 +98,9 @@ protected uint GetOffset(Instruction instr) { /// Size of code protected uint InitializeInstructionOffsets() { uint offset = 0; - foreach (var instr in instructions) { + var instructions = this.instructions; + for (int i = 0; i < instructions.Count; i++) { + var instr = instructions[i]; if (instr == null) continue; offsets[instr] = offset; @@ -120,14 +121,16 @@ protected uint InitializeInstructionOffsets() { /// /// The instruction writer /// Number of bytes written - protected uint WriteInstructions(BinaryWriter writer) { - firstInstructionOffset = (uint)writer.BaseStream.Position; - foreach (var instr in instructions) { + protected uint WriteInstructions(ref DataWriter writer) { + firstInstructionOffset = (uint)writer.Position; + var instructions = this.instructions; + for (int i = 0; i < instructions.Count; i++) { + var instr = instructions[i]; if (instr == null) continue; - WriteInstruction(writer, instr); + WriteInstruction(ref writer, instr); } - return ToInstructionOffset(writer); + return ToInstructionOffset(ref writer); } /// @@ -136,16 +139,16 @@ protected uint WriteInstructions(BinaryWriter writer) { /// /// The instruction writer /// Current offset, relative to the first written instruction - protected uint ToInstructionOffset(BinaryWriter writer) => (uint)writer.BaseStream.Position - firstInstructionOffset; + protected uint ToInstructionOffset(ref DataWriter writer) => (uint)writer.Position - firstInstructionOffset; /// /// Writes an instruction /// /// The instruction writer /// The instruction - protected virtual void WriteInstruction(BinaryWriter writer, Instruction instr) { - WriteOpCode(writer, instr); - WriteOperand(writer, instr); + protected virtual void WriteInstruction(ref DataWriter writer, Instruction instr) { + WriteOpCode(ref writer, instr); + WriteOperand(ref writer, instr); } /// @@ -153,7 +156,7 @@ protected virtual void WriteInstruction(BinaryWriter writer, Instruction instr) /// /// The instruction writer /// The instruction - protected virtual void WriteOpCode(BinaryWriter writer, Instruction instr) { + protected void WriteOpCode(ref DataWriter writer, Instruction instr) { var code = instr.OpCode.Code; if ((ushort)code <= 0xFF) writer.Write((byte)code); @@ -176,26 +179,26 @@ protected virtual void WriteOpCode(BinaryWriter writer, Instruction instr) { /// /// The instruction writer /// The instruction - protected virtual void WriteOperand(BinaryWriter writer, Instruction instr) { + protected void WriteOperand(ref DataWriter writer, Instruction instr) { switch (instr.OpCode.OperandType) { - case OperandType.InlineBrTarget: WriteInlineBrTarget(writer, instr); break; - case OperandType.InlineField: WriteInlineField(writer, instr); break; - case OperandType.InlineI: WriteInlineI(writer, instr); break; - case OperandType.InlineI8: WriteInlineI8(writer, instr); break; - case OperandType.InlineMethod: WriteInlineMethod(writer, instr); break; - case OperandType.InlineNone: WriteInlineNone(writer, instr); break; - case OperandType.InlinePhi: WriteInlinePhi(writer, instr); break; - case OperandType.InlineR: WriteInlineR(writer, instr); break; - case OperandType.InlineSig: WriteInlineSig(writer, instr); break; - case OperandType.InlineString: WriteInlineString(writer, instr); break; - case OperandType.InlineSwitch: WriteInlineSwitch(writer, instr); break; - case OperandType.InlineTok: WriteInlineTok(writer, instr); break; - case OperandType.InlineType: WriteInlineType(writer, instr); break; - case OperandType.InlineVar: WriteInlineVar(writer, instr); break; - case OperandType.ShortInlineBrTarget: WriteShortInlineBrTarget(writer, instr); break; - case OperandType.ShortInlineI: WriteShortInlineI(writer, instr); break; - case OperandType.ShortInlineR: WriteShortInlineR(writer, instr); break; - case OperandType.ShortInlineVar: WriteShortInlineVar(writer, instr); break; + case OperandType.InlineBrTarget: WriteInlineBrTarget(ref writer, instr); break; + case OperandType.InlineField: WriteInlineField(ref writer, instr); break; + case OperandType.InlineI: WriteInlineI(ref writer, instr); break; + case OperandType.InlineI8: WriteInlineI8(ref writer, instr); break; + case OperandType.InlineMethod: WriteInlineMethod(ref writer, instr); break; + case OperandType.InlineNone: WriteInlineNone(ref writer, instr); break; + case OperandType.InlinePhi: WriteInlinePhi(ref writer, instr); break; + case OperandType.InlineR: WriteInlineR(ref writer, instr); break; + case OperandType.InlineSig: WriteInlineSig(ref writer, instr); break; + case OperandType.InlineString: WriteInlineString(ref writer, instr); break; + case OperandType.InlineSwitch: WriteInlineSwitch(ref writer, instr); break; + case OperandType.InlineTok: WriteInlineTok(ref writer, instr); break; + case OperandType.InlineType: WriteInlineType(ref writer, instr); break; + case OperandType.InlineVar: WriteInlineVar(ref writer, instr); break; + case OperandType.ShortInlineBrTarget: WriteShortInlineBrTarget(ref writer, instr); break; + case OperandType.ShortInlineI: WriteShortInlineI(ref writer, instr); break; + case OperandType.ShortInlineR: WriteShortInlineR(ref writer, instr); break; + case OperandType.ShortInlineVar: WriteShortInlineVar(ref writer, instr); break; default: Error("Unknown operand type"); @@ -208,8 +211,8 @@ protected virtual void WriteOperand(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteInlineBrTarget(BinaryWriter writer, Instruction instr) { - uint displ = GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(writer) + 4); + protected virtual void WriteInlineBrTarget(ref DataWriter writer, Instruction instr) { + uint displ = GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 4); writer.Write(displ); } @@ -218,14 +221,14 @@ protected virtual void WriteInlineBrTarget(BinaryWriter writer, Instruction inst /// /// Instruction writer /// Instruction - protected abstract void WriteInlineField(BinaryWriter writer, Instruction instr); + protected abstract void WriteInlineField(ref DataWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineI(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlineI(ref DataWriter writer, Instruction instr) { if (instr.Operand is int) writer.Write((int)instr.Operand); else { @@ -239,7 +242,7 @@ protected virtual void WriteInlineI(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteInlineI8(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlineI8(ref DataWriter writer, Instruction instr) { if (instr.Operand is long) writer.Write((long)instr.Operand); else { @@ -253,14 +256,14 @@ protected virtual void WriteInlineI8(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected abstract void WriteInlineMethod(BinaryWriter writer, Instruction instr); + protected abstract void WriteInlineMethod(ref DataWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineNone(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlineNone(ref DataWriter writer, Instruction instr) { } /// @@ -268,7 +271,7 @@ protected virtual void WriteInlineNone(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteInlinePhi(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlinePhi(ref DataWriter writer, Instruction instr) { } /// @@ -276,7 +279,7 @@ protected virtual void WriteInlinePhi(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteInlineR(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlineR(ref DataWriter writer, Instruction instr) { if (instr.Operand is double) writer.Write((double)instr.Operand); else { @@ -290,31 +293,33 @@ protected virtual void WriteInlineR(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected abstract void WriteInlineSig(BinaryWriter writer, Instruction instr); + protected abstract void WriteInlineSig(ref DataWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected abstract void WriteInlineString(BinaryWriter writer, Instruction instr); + protected abstract void WriteInlineString(ref DataWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineSwitch(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlineSwitch(ref DataWriter writer, Instruction instr) { var targets = instr.Operand as IList; if (targets == null) { Error("switch operand is not a list of instructions"); writer.Write(0); } else { - uint offsetAfter = (uint)(ToInstructionOffset(writer) + 4 + targets.Count * 4); + uint offsetAfter = (uint)(ToInstructionOffset(ref writer) + 4 + targets.Count * 4); writer.Write(targets.Count); - foreach (var target in targets) + for (int i = 0; i < targets.Count; i++) { + var target = targets[i]; writer.Write(GetOffset(target) - offsetAfter); + } } } @@ -323,31 +328,34 @@ protected virtual void WriteInlineSwitch(BinaryWriter writer, Instruction instr) /// /// Instruction writer /// Instruction - protected abstract void WriteInlineTok(BinaryWriter writer, Instruction instr); + protected abstract void WriteInlineTok(ref DataWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected abstract void WriteInlineType(BinaryWriter writer, Instruction instr); + protected abstract void WriteInlineType(ref DataWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineVar(BinaryWriter writer, Instruction instr) { + protected virtual void WriteInlineVar(ref DataWriter writer, Instruction instr) { var variable = instr.Operand as IVariable; if (variable == null) { Error("Operand is not a local/arg"); writer.Write((ushort)0); } - else if (ushort.MinValue <= variable.Index && variable.Index <= ushort.MaxValue) - writer.Write((ushort)variable.Index); else { - Error("Local/arg index doesn't fit in a UInt16"); - writer.Write((ushort)0); + int index = variable.Index; + if (ushort.MinValue <= index && index <= ushort.MaxValue) + writer.Write((ushort)index); + else { + Error("Local/arg index doesn't fit in a UInt16"); + writer.Write((ushort)0); + } } } @@ -356,8 +364,8 @@ protected virtual void WriteInlineVar(BinaryWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineBrTarget(BinaryWriter writer, Instruction instr) { - int displ = (int)(GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(writer) + 1)); + protected virtual void WriteShortInlineBrTarget(ref DataWriter writer, Instruction instr) { + int displ = (int)(GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 1)); if (sbyte.MinValue <= displ && displ <= sbyte.MaxValue) writer.Write((sbyte)displ); else { @@ -371,7 +379,7 @@ protected virtual void WriteShortInlineBrTarget(BinaryWriter writer, Instruction /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineI(BinaryWriter writer, Instruction instr) { + protected virtual void WriteShortInlineI(ref DataWriter writer, Instruction instr) { if (instr.Operand is sbyte) writer.Write((sbyte)instr.Operand); else if (instr.Operand is byte) @@ -387,7 +395,7 @@ protected virtual void WriteShortInlineI(BinaryWriter writer, Instruction instr) /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineR(BinaryWriter writer, Instruction instr) { + protected virtual void WriteShortInlineR(ref DataWriter writer, Instruction instr) { if (instr.Operand is float) writer.Write((float)instr.Operand); else { @@ -401,17 +409,20 @@ protected virtual void WriteShortInlineR(BinaryWriter writer, Instruction instr) /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineVar(BinaryWriter writer, Instruction instr) { + protected virtual void WriteShortInlineVar(ref DataWriter writer, Instruction instr) { var variable = instr.Operand as IVariable; if (variable == null) { Error("Operand is not a local/arg"); writer.Write((byte)0); } - else if (byte.MinValue <= variable.Index && variable.Index <= byte.MaxValue) - writer.Write((byte)variable.Index); else { - Error("Local/arg index doesn't fit in a Byte. Use the longer ldloc/ldarg/stloc/starg instruction."); - writer.Write((byte)0); + int index = variable.Index; + if (byte.MinValue <= index && index <= byte.MaxValue) + writer.Write((byte)index); + else { + Error("Local/arg index doesn't fit in a Byte. Use the longer ldloc/ldarg/stloc/starg instruction."); + writer.Write((byte)0); + } } } } diff --git a/src/IO/DataStreamFactory.cs b/src/IO/DataStreamFactory.cs index fcf308d01..febe51000 100644 --- a/src/IO/DataStreamFactory.cs +++ b/src/IO/DataStreamFactory.cs @@ -10,6 +10,7 @@ public static unsafe class DataStreamFactory { static bool supportsUnalignedAccesses = CalculateSupportsUnalignedAccesses(); //TODO: ARM doesn't support unaligned accesses + //TODO: There are other places that use pointers that also need to be updated static bool CalculateSupportsUnalignedAccesses() => true; /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 8e094d5d1..ebc33a368 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -308,6 +308,7 @@ + From 69de265922c888f636c482649d2940181583cbdc Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 18 Mar 2018 13:02:23 +0100 Subject: [PATCH 144/511] Native module writer: reuse old MD and body locations when writing new data --- README.md | 1 + src/DotNet/Emit/MethodBody.cs | 6 + src/DotNet/Emit/MethodBodyReader.cs | 29 +++- src/DotNet/ModuleDefMD.cs | 4 +- src/DotNet/Writer/ByteArrayChunk.cs | 4 +- src/DotNet/Writer/ChunkList.cs | 1 + src/DotNet/Writer/ChunkListBase.cs | 2 + src/DotNet/Writer/DebugDirectory.cs | 27 +++- src/DotNet/Writer/HeapBase.cs | 2 + src/DotNet/Writer/IChunk.cs | 21 +++ src/DotNet/Writer/Metadata.cs | 56 +++++-- src/DotNet/Writer/MethodBody.cs | 19 ++- src/DotNet/Writer/MethodBodyChunks.cs | 52 +++++- src/DotNet/Writer/ModuleWriterBase.cs | 4 +- src/DotNet/Writer/NativeModuleWriter.cs | 191 ++++++++++++++++++++--- src/DotNet/Writer/NetResources.cs | 24 +-- src/DotNet/Writer/PEHeaders.cs | 2 +- src/DotNet/Writer/SectionSizes.cs | 4 +- src/DotNet/Writer/StrongNameSignature.cs | 4 +- src/DotNet/Writer/TablesHeap.cs | 2 + src/DotNet/Writer/Win32ResourcesChunk.cs | 60 +++++-- 21 files changed, 432 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index 1e6b5a085..bcadb53ca 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ v3.0 breaking changes - `DataReader.Position` only accepts valid values and will throw (an `IOException`) if you set it to an invalid position - `FileOffset` is `uint`, used to be `long` - `MethodBodyWriterBase` uses `DataWriter` instead of `BinaryWriter` (all virtual methods) +- The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` Examples -------- diff --git a/src/DotNet/Emit/MethodBody.cs b/src/DotNet/Emit/MethodBody.cs index acc79831d..4ef4e6be7 100644 --- a/src/DotNet/Emit/MethodBody.cs +++ b/src/DotNet/Emit/MethodBody.cs @@ -152,6 +152,12 @@ public PdbMethod PdbMethod { /// public bool HasPdbMethod => PdbMethod != null; + /// + /// Gets the total size of the body in the PE file, including header, IL bytes, and exception handlers. + /// This property returns 0 if the size is unknown. + /// + internal uint MetadataBodySize { get; set; } + /// /// Default constructor /// diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index 8391720b7..bd0d09709 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -45,6 +45,8 @@ public sealed class MethodBodyReader : MethodBodyReaderBase { ushort maxStack; uint codeSize; uint localVarSigTok; + uint startOfHeader; + uint totalBodySize; DataReader? exceptionsReader; readonly GenericParamContext gpContext; @@ -252,6 +254,7 @@ public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader codeR this.opResolver = opResolver; exceptionsReader = ehReader; this.gpContext = gpContext; + startOfHeader = uint.MaxValue; } /// @@ -279,7 +282,7 @@ public bool Read() { return false; SetLocals(ReadLocals()); ReadInstructions(); - ReadExceptionHandlers(); + ReadExceptionHandlers(out totalBodySize); return true; } catch (InvalidMethodException) { @@ -298,6 +301,7 @@ bool ReadHeader() { return true; hasReadHeader = true; + startOfHeader = reader.Position; byte b = reader.ReadByte(); switch (b & 7) { case 2: @@ -384,24 +388,36 @@ protected override MethodSig ReadInlineSig(Instruction instr) { /// /// Reads all exception handlers /// - void ReadExceptionHandlers() { - if ((flags & 8) == 0) + void ReadExceptionHandlers(out uint totalBodySize) { + if ((flags & 8) == 0) { + totalBodySize = startOfHeader == uint.MaxValue ? 0 : reader.Position - startOfHeader; return; + } + bool canSaveTotalBodySize; DataReader ehReader; - if (exceptionsReader != null) + if (exceptionsReader != null) { + canSaveTotalBodySize = false; ehReader = exceptionsReader.Value; + } else { + canSaveTotalBodySize = true; ehReader = reader; ehReader.Position = (ehReader.Position + 3) & ~3U; } // Only read the first one. Any others aren't used. byte b = ehReader.ReadByte(); - if ((b & 0x3F) != 1) - return; // Not exception handler clauses + if ((b & 0x3F) != 1) { + totalBodySize = startOfHeader == uint.MaxValue ? 0 : reader.Position - startOfHeader; + return; // Not exception handler clauses + } if ((b & 0x40) != 0) ReadFatExceptionHandlers(ref ehReader); else ReadSmallExceptionHandlers(ref ehReader); + if (canSaveTotalBodySize) + totalBodySize = startOfHeader == uint.MaxValue ? 0 : ehReader.Position - startOfHeader; + else + totalBodySize = 0; } static ushort GetNumberOfExceptionHandlers(uint num) { @@ -463,6 +479,7 @@ public CilBody CreateCilBody() { cilBody.HeaderSize = headerSize; cilBody.MaxStack = maxStack; cilBody.LocalVarSigTok = localVarSigTok; + cilBody.MetadataBodySize = totalBodySize; instructions = null; exceptionHandlers = null; locals = null; diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index c6e1704d9..9ec208fe8 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1752,7 +1752,7 @@ void InitializeMethodExportInfoProvider() => /// Filename /// Writer options public void NativeWrite(string filename, DNW.NativeModuleWriterOptions options) { - var writer = new DNW.NativeModuleWriter(this, options ?? new DNW.NativeModuleWriterOptions(this)); + var writer = new DNW.NativeModuleWriter(this, options ?? new DNW.NativeModuleWriterOptions(this, optimizeImageSize: true)); writer.Write(filename); } @@ -1768,7 +1768,7 @@ public void NativeWrite(string filename, DNW.NativeModuleWriterOptions options) /// Destination stream /// Writer options public void NativeWrite(Stream dest, DNW.NativeModuleWriterOptions options) { - var writer = new DNW.NativeModuleWriter(this, options ?? new DNW.NativeModuleWriterOptions(this)); + var writer = new DNW.NativeModuleWriter(this, options ?? new DNW.NativeModuleWriterOptions(this, optimizeImageSize: true)); writer.Write(dest); } diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 53afd7ab5..81d58dfb6 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.Writer { /// /// Stores a byte array /// - public sealed class ByteArrayChunk : IChunk { + public sealed class ByteArrayChunk : IReuseChunk { readonly byte[] array; FileOffset offset; RVA rva; @@ -35,6 +35,8 @@ public sealed class ByteArrayChunk : IChunk { /// but shouldn't be resized after has been called. public ByteArrayChunk(byte[] array) => this.array = array ?? Array2.Empty(); + bool IReuseChunk.CanReuse(uint origSize) => (uint)array.Length <= origSize; + /// public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; diff --git a/src/DotNet/Writer/ChunkList.cs b/src/DotNet/Writer/ChunkList.cs index c04df817f..47971ad4b 100644 --- a/src/DotNet/Writer/ChunkList.cs +++ b/src/DotNet/Writer/ChunkList.cs @@ -34,6 +34,7 @@ public void Add(T chunk, uint alignment) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); if (chunk != null) { + var chunks = this.chunks; for (int i = 0; i < chunks.Count; i++) { if (chunks[i].chunk == chunk) { uint alignment = chunks[i].alignment; diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index 4a9b566b6..1390bed89 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -20,6 +20,8 @@ public abstract class ChunkListBase : IChunk where T : IChunk { FileOffset offset; RVA rva; + internal bool IsEmpty => chunks.Count == 0; + /// /// Helper struct /// diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index 6197d0521..eff1b8492 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System; using System.Collections.Generic; using System.IO; using dnlib.DotNet.Pdb; @@ -31,15 +32,18 @@ public sealed class DebugDirectoryEntry { /// /// Debug directory chunk /// - public sealed class DebugDirectory : IChunk { + public sealed class DebugDirectory : IReuseChunk { /// Default debug directory alignment public const uint DEFAULT_DEBUGDIRECTORY_ALIGNMENT = 4; - const int HEADER_SIZE = 28; + internal const int HEADER_SIZE = 28; + + internal int Count => entries.Count; FileOffset offset; RVA rva; uint length; readonly List entries; + bool isReadonly; /// public FileOffset FileOffset => offset; @@ -65,22 +69,39 @@ public sealed class DebugDirectory : IChunk { /// Data /// public DebugDirectoryEntry Add(IChunk chunk) { + if (isReadonly) + throw new InvalidOperationException("Can't add a new DebugDirectory entry when the DebugDirectory is read-only!"); var entry = new DebugDirectoryEntry(chunk); entries.Add(entry); return entry; } + bool IReuseChunk.CanReuse(uint origSize) { + uint newLength = GetLength(entries, 0, 0); + if (newLength > origSize) + return false; + + isReadonly = true; + return true; + } + /// public void SetOffset(FileOffset offset, RVA rva) { + isReadonly = true; this.offset = offset; this.rva = rva; - length = HEADER_SIZE * (uint)entries.Count; + length = GetLength(entries, offset, rva); + } + + static uint GetLength(List entries, FileOffset offset, RVA rva) { + uint length = HEADER_SIZE * (uint)entries.Count; foreach (var entry in entries) { length = Utils.AlignUp(length, DEFAULT_DEBUGDIRECTORY_ALIGNMENT); entry.Chunk.SetOffset(offset + length, rva + length); length += entry.Chunk.GetFileLength(); } + return length; } /// diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index 99df18d24..7246214ac 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -42,6 +42,8 @@ public abstract class HeapBase : IHeap { public virtual void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; + + // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOFfset() for more info } /// diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index cf9329375..c7013a9b7 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -50,6 +50,18 @@ public interface IChunk { void WriteTo(BinaryWriter writer); } + /// + /// Implemented by s that can reuse the old data location in the original PE file + /// + interface IReuseChunk : IChunk { + /// + /// Returns true if this chunk fits in the old location + /// + /// Size of the original location + /// + bool CanReuse(uint origSize); + } + public static partial class Extensions { /// /// Writes all data to and verifies that all bytes were written @@ -84,5 +96,14 @@ internal static void WriteDataDirectory(this BinaryWriter writer, IChunk chunk) writer.Write(chunk.GetVirtualSize()); } } + + internal static void WriteDebugDirectory(this BinaryWriter writer, DebugDirectory chunk) { + if (chunk == null || chunk.GetVirtualSize() == 0) + writer.Write(0UL); + else { + writer.Write((uint)chunk.RVA); + writer.Write(chunk.Count * DebugDirectory.HEADER_SIZE); + } + } } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 5fb57653e..d299e117a 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -328,7 +328,7 @@ public MetadataProgressEventArgs(Metadata metadata, double progress) { /// /// .NET meta data /// - public abstract class Metadata : IChunk, ISignatureWriterHelper, ITokenCreator, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper { + public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenCreator, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper { uint length; FileOffset offset; RVA rva; @@ -1779,7 +1779,9 @@ void WriteMethodBodies() { if (!(cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0)) { writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); writer.Write(); - var mb = methodBodies.Add(new MethodBody(writer.Code, writer.ExtraSections, writer.LocalVarSigTok)); + var origRva = method.RVA; + uint origSize = cilBody.MetadataBodySize; + var mb = methodBodies.Add(new MethodBody(writer.Code, writer.ExtraSections, writer.LocalVarSigTok), origRva, origSize); methodToBody[method] = mb; localVarSigTok = writer.LocalVarSigTok; } @@ -3388,22 +3390,36 @@ protected virtual void EverythingInitialized() { const uint HEAP_ALIGNMENT = 4; + bool IReuseChunk.CanReuse(uint origSize) { + // The caller should've called SetOffset() so we know our final size + Debug.Assert(length != 0); + if (length == 0) + throw new InvalidOperationException(); + return length <= origSize; + } + /// public void SetOffset(FileOffset offset, RVA rva) { + // This method can be called twice by NativeModuleWriter. It needs to know the size + // of the final metadata. If it fits in the old location, the new MD will be written + // there (smaller file size). If the new MD doesn't fit in the old location, this + // method gets called a second time with the updated offset + rva. + bool initAll = this.offset == 0; this.offset = offset; this.rva = rva; - stringsHeap.AddOptimizedStrings(); - stringsHeap.SetReadOnly(); - blobHeap.SetReadOnly(); - guidHeap.SetReadOnly(); - tablesHeap.SetReadOnly(); - pdbHeap.SetReadOnly(); - tablesHeap.BigStrings = stringsHeap.IsBig; - tablesHeap.BigBlob = blobHeap.IsBig; - tablesHeap.BigGuid = guidHeap.IsBig; - - metadataHeader.Heaps = GetHeaps(); + if (initAll) { + stringsHeap.AddOptimizedStrings(); + stringsHeap.SetReadOnly(); + blobHeap.SetReadOnly(); + guidHeap.SetReadOnly(); + tablesHeap.SetReadOnly(); + pdbHeap.SetReadOnly(); + tablesHeap.BigStrings = stringsHeap.IsBig; + tablesHeap.BigBlob = blobHeap.IsBig; + tablesHeap.BigGuid = guidHeap.IsBig; + metadataHeader.Heaps = GetHeaps(); + } metadataHeader.SetOffset(offset, rva); uint len = metadataHeader.GetFileLength(); @@ -3418,12 +3434,18 @@ public void SetOffset(FileOffset offset, RVA rva) { offset += len; rva += len; } + Debug.Assert(initAll || length == rva - this.rva); + if (!(initAll || length == rva - this.rva)) + throw new InvalidOperationException(); length = rva - this.rva; - if (!isStandaloneDebugMetadata) { - UpdateMethodRvas(); - UpdateFieldRvas(); - } + if (!isStandaloneDebugMetadata && initAll) + UpdateMethodAndFieldRvas(); + } + + internal void UpdateMethodAndFieldRvas() { + UpdateMethodRvas(); + UpdateFieldRvas(); } IList GetHeaps() { diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 8b2b08db3..22b639083 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System.IO; +using System.Diagnostics; +using System.IO; using dnlib.IO; using dnlib.PE; @@ -88,7 +89,7 @@ public MethodBody(byte[] code, byte[] extraSections, uint localVarSigTok) { /// /// Gets the approximate size of the method body (code + exception handlers) /// - public int GetSizeOfMethodBody() { + public int GetApproximateSizeOfMethodBody() { int len = code.Length; if (extraSections != null) { len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); @@ -98,8 +99,22 @@ public int GetSizeOfMethodBody() { return len; } + internal bool CanReuse(RVA origRva, uint origSize) { + uint length; + if (HasExtraSections) { + var rva2 = origRva + (uint)code.Length; + rva2 = rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT); + rva2 += (uint)extraSections.Length; + length = (uint)rva2 - (uint)origRva; + } + else + length = (uint)code.Length; + return length <= origSize; + } + /// public void SetOffset(FileOffset offset, RVA rva) { + Debug.Assert(this.rva == 0); this.offset = offset; this.rva = rva; if (HasExtraSections) { diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index df273590c..d148e3e2c 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using dnlib.IO; using dnlib.PE; @@ -16,6 +17,7 @@ public sealed class MethodBodyChunks : IChunk { Dictionary fatMethodsDict; readonly List tinyMethods; readonly List fatMethods; + readonly List reusedMethods; readonly bool shareBodies; FileOffset offset; RVA rva; @@ -24,6 +26,15 @@ public sealed class MethodBodyChunks : IChunk { readonly bool alignFatBodies; uint savedBytes; + readonly struct ReusedMethodInfo { + public readonly MethodBody MethodBody; + public readonly RVA RVA; + public ReusedMethodInfo(MethodBody methodBody, RVA rva) { + MethodBody = methodBody; + RVA = rva; + } + } + /// public FileOffset FileOffset => offset; @@ -35,6 +46,10 @@ public sealed class MethodBodyChunks : IChunk { /// public uint SavedBytes => savedBytes; + internal bool CanReuseOldBodyLocation { get; set; } + internal bool ReusedAllMethodBodyLocations => tinyMethods.Count == 0 && fatMethods.Count == 0; + internal bool HasReusedMethods => reusedMethods.Count > 0; + /// /// Constructor /// @@ -48,6 +63,7 @@ public MethodBodyChunks(bool shareBodies) { } tinyMethods = new List(); fatMethods = new List(); + reusedMethods = new List(); } /// @@ -55,20 +71,46 @@ public MethodBodyChunks(bool shareBodies) { /// /// The method body /// The cached method body - public MethodBody Add(MethodBody methodBody) { + public MethodBody Add(MethodBody methodBody) => Add(methodBody, 0, 0); + + internal MethodBody Add(MethodBody methodBody, RVA origRva, uint origSize) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); if (shareBodies) { var dict = methodBody.IsFat ? fatMethodsDict : tinyMethodsDict; if (dict.TryGetValue(methodBody, out var cached)) { - savedBytes += (uint)methodBody.GetSizeOfMethodBody(); + savedBytes += (uint)methodBody.GetApproximateSizeOfMethodBody(); return cached; } dict[methodBody] = methodBody; } - var list = methodBody.IsFat ? fatMethods : tinyMethods; - list.Add(methodBody); - return methodBody; + bool reuseLoc = CanReuseOldBodyLocation && origRva != 0 && origSize != 0 && methodBody.CanReuse(origRva, origSize); + if (reuseLoc) { + reusedMethods.Add(new ReusedMethodInfo(methodBody, origRva)); + return methodBody; + } + else { + var list = methodBody.IsFat ? fatMethods : tinyMethods; + list.Add(methodBody); + return methodBody; + } + } + + internal void InitializeReusedMethodBodies(IPEImage peImage, uint fileOffsetDelta) { + foreach (var info in reusedMethods) { + var offset = peImage.ToFileOffset(info.RVA) + fileOffsetDelta; + info.MethodBody.SetOffset(offset, info.RVA); + } + } + + internal void WriteReusedMethodBodies(BinaryWriter writer, long destStreamBaseOffset) { + foreach (var info in reusedMethods) { + Debug.Assert(info.MethodBody.RVA == info.RVA); + if (info.MethodBody.RVA != info.RVA) + throw new InvalidOperationException(); + writer.BaseStream.Position = destStreamBaseOffset + (uint)info.MethodBody.FileOffset; + info.MethodBody.VerifyWriteTo(writer); + } } /// diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 364c3cdad..ba16baecb 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -412,13 +412,13 @@ public abstract class ModuleWriterBase : ILogger { /// Default alignment of all method bodies protected const uint DEFAULT_METHODBODIES_ALIGNMENT = 4; /// Default alignment of all .NET resources - protected const uint DEFAULT_NETRESOURCES_ALIGNMENT = 8; + protected const uint DEFAULT_NETRESOURCES_ALIGNMENT = 4; /// Default alignment of the .NET metadata protected const uint DEFAULT_METADATA_ALIGNMENT = 4; /// Default Win32 resources alignment protected internal const uint DEFAULT_WIN32_RESOURCES_ALIGNMENT = 8; /// Default strong name signature alignment - protected const uint DEFAULT_STRONGNAMESIG_ALIGNMENT = 16; + protected const uint DEFAULT_STRONGNAMESIG_ALIGNMENT = 4; /// Default COR20 header alignment protected const uint DEFAULT_COR20HEADER_ALIGNMENT = 4; diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 42c48ba15..e77bbd0a0 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -1,12 +1,13 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using dnlib.IO; using dnlib.PE; using dnlib.W32Resources; using dnlib.DotNet.MD; +using System.Diagnostics; namespace dnlib.DotNet.Writer { /// @@ -25,14 +26,30 @@ public sealed class NativeModuleWriterOptions : ModuleWriterOptionsBase { /// public bool KeepWin32Resources { get; set; } + internal bool OptimizeImageSize { get; } + /// /// Constructor /// /// Module - public NativeModuleWriterOptions(ModuleDefMD module) : base(module) { + /// true to optimize the image size so it's as small as possible. + /// Since the file can contain native methods and other native data, we re-use the + /// original file when writing the new file. If is true, + /// we'll try to re-use the old method body locations in the original file and + /// also try to fit the new metadata in the old metadata location. + public NativeModuleWriterOptions(ModuleDefMD module, bool optimizeImageSize) : base(module) { // C++ .NET mixed mode assemblies sometimes/often call Module.ResolveMethod(), // so method metadata tokens must be preserved. MetadataOptions.Flags |= MetadataFlags.PreserveAllMethodRids; + + if (optimizeImageSize) { + OptimizeImageSize = true; + + // Prevent the #Blob heap from getting bigger. Encoded TypeDefOrRef tokens are stored there (in + // typesigs and callingconvsigs) so we must preserve TypeDefOrRef tokens (or the #Blob heap could + // grow in size and new MD won't fit in old location) + MetadataOptions.Flags |= MetadataFlags.PreserveTypeRefRids | MetadataFlags.PreserveTypeDefRids | MetadataFlags.PreserveTypeSpecRids; + } } } @@ -54,12 +71,20 @@ public sealed class NativeModuleWriter : ModuleWriterBase { /// DataReaderChunk extraData; - /// The original PE headers - DataReaderChunk headerSection; - /// The original PE sections and their data List origSections; + readonly struct ReusedChunkInfo { + public IReuseChunk Chunk { get; } + public RVA RVA { get; } + public ReusedChunkInfo(IReuseChunk chunk, RVA rva) { + Chunk = chunk; + RVA = rva; + } + } + + List reusedChunks; + /// Original PE image readonly IPEImage peImage; @@ -128,7 +153,7 @@ public override string ToString() { /// Gets/sets the writer options. This is never null /// public NativeModuleWriterOptions Options { - get => options ?? (options = new NativeModuleWriterOptions(module)); + get => options ?? (options = new NativeModuleWriterOptions(module, optimizeImageSize: true)); set => options = value; } @@ -161,6 +186,7 @@ public NativeModuleWriter(ModuleDefMD module, NativeModuleWriterOptions options) this.module = module; this.options = options; peImage = module.Metadata.PEImage; + reusedChunks = new List(); } /// @@ -201,12 +227,12 @@ void Initialize() { void CreateSections() { CreatePESections(); CreateRawSections(); - CreateHeaderSection(); CreateExtraData(); } void CreateChunks() { CreateMetadataChunks(module); + methodBodies.CanReuseOldBodyLocation = Options.OptimizeImageSize; CreateDebugDirectory(); @@ -259,7 +285,7 @@ void CreateRawSections() { /// /// Creates the PE header "section" /// - void CreateHeaderSection() { + DataReaderChunk CreateHeaderSection(out IChunk extraHeaderData) { uint afterLastSectHeader = GetOffsetAfterLastSectionHeader() + (uint)sections.Count * 0x28; uint firstRawOffset = Math.Min(GetFirstRawDataFileOffset(), peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); uint headerLen = afterLastSectHeader; @@ -267,8 +293,19 @@ void CreateHeaderSection() { headerLen = firstRawOffset; headerLen = Utils.AlignUp(headerLen, peImage.ImageNTHeaders.OptionalHeader.FileAlignment); if (headerLen <= peImage.ImageNTHeaders.OptionalHeader.SectionAlignment) { - headerSection = new DataReaderChunk(peImage.CreateReader((FileOffset)0, headerLen)); - return; + uint origSizeOfHeaders = peImage.ImageNTHeaders.OptionalHeader.SizeOfHeaders; + uint extraLen; + if (headerLen <= origSizeOfHeaders) + extraLen = 0; + else { + extraLen = headerLen - origSizeOfHeaders; + headerLen = origSizeOfHeaders; + } + if (extraLen > 0) + extraHeaderData = new ByteArrayChunk(new byte[(int)extraLen]); + else + extraHeaderData = null; + return new DataReaderChunk(peImage.CreateReader((FileOffset)0, headerLen)); } //TODO: Support this too @@ -306,6 +343,21 @@ uint GetLastFileSectionOffset() { return (uint)peImage.ToFileOffset((RVA)(rva - 1)) + 1; } + void ReuseIfPossible(PESection section, IReuseChunk chunk, RVA origRva, uint origSize, uint requiredAlignment) { + if (origRva == 0 || origSize == 0) + return; + if (chunk == null) + return; + if (!chunk.CanReuse(origSize)) + return; + if (((uint)origRva & (requiredAlignment - 1)) != 0) + return; + + if (section.Remove(chunk) == null) + throw new InvalidOperationException(); + reusedChunks.Add(new ReusedChunkInfo(chunk, origRva)); + } + long WriteFile() { bool entryPointIsManagedOrNoEntryPoint = GetEntryPoint(out uint entryPointToken); @@ -315,8 +367,65 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.BeginCalculateRvasAndFileOffsets); + if (Options.OptimizeImageSize) { + // Check if we can reuse the old MD location for the new MD. + // If we can't reuse it, it could be due to several reasons: + // - TypeDefOrRef tokens weren't preserved resulting in a new #Blob heap that's bigger than the old #Blob heap + // - New MD was added or existing MD was modified (eg. types were renamed) by the user so it's + // now bigger and doesn't fit in the old location + // - The original location wasn't aligned properly + // - The new MD is bigger because the other MD writer was slightly better at optimizing the MD. + // This should be considered a bug. + var mdDataDir = module.Metadata.ImageCor20Header.Metadata; + metadata.SetOffset(peImage.ToFileOffset(mdDataDir.VirtualAddress), mdDataDir.VirtualAddress); + ReuseIfPossible(textSection, metadata, mdDataDir.VirtualAddress, mdDataDir.Size, DEFAULT_METADATA_ALIGNMENT); + + var resourceDataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[2]; + if (win32Resources != null && resourceDataDir.VirtualAddress != 0 && resourceDataDir.Size != 0) { + var win32ResourcesOffset = peImage.ToFileOffset(resourceDataDir.VirtualAddress); + if (win32Resources.CheckValidOffset(win32ResourcesOffset)) { + win32Resources.SetOffset(win32ResourcesOffset, resourceDataDir.VirtualAddress); + ReuseIfPossible(rsrcSection, win32Resources, resourceDataDir.VirtualAddress, resourceDataDir.Size, DEFAULT_WIN32_RESOURCES_ALIGNMENT); + } + } + + ReuseIfPossible(textSection, imageCor20Header, module.Metadata.PEImage.ImageNTHeaders.OptionalHeader.DataDirectories[14].VirtualAddress, module.Metadata.PEImage.ImageNTHeaders.OptionalHeader.DataDirectories[14].Size, DEFAULT_COR20HEADER_ALIGNMENT); + if ((module.Metadata.ImageCor20Header.Flags & ComImageFlags.StrongNameSigned) != 0) + ReuseIfPossible(textSection, strongNameSignature, module.Metadata.ImageCor20Header.StrongNameSignature.VirtualAddress, module.Metadata.ImageCor20Header.StrongNameSignature.Size, DEFAULT_STRONGNAMESIG_ALIGNMENT); + ReuseIfPossible(textSection, netResources, module.Metadata.ImageCor20Header.Resources.VirtualAddress, module.Metadata.ImageCor20Header.Resources.Size, DEFAULT_NETRESOURCES_ALIGNMENT); + if (methodBodies.ReusedAllMethodBodyLocations) + textSection.Remove(methodBodies); + + var debugDataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[6]; + if (debugDataDir.VirtualAddress != 0 && debugDataDir.Size != 0 && TryGetRealDebugDirectorySize(peImage, out uint realDebugDirSize)) + ReuseIfPossible(textSection, debugDirectory, debugDataDir.VirtualAddress, realDebugDirSize, DebugDirectory.DEFAULT_DEBUGDIRECTORY_ALIGNMENT); + } + + if (constants.IsEmpty) + textSection.Remove(constants); + if (netResources.IsEmpty) + textSection.Remove(netResources); + if (textSection.IsEmpty) + sections.Remove(textSection); + if (rsrcSection != null && rsrcSection.IsEmpty) { + sections.Remove(rsrcSection); + rsrcSection = null; + } + + var headerSection = CreateHeaderSection(out var extraHeaderData); var chunks = new List(); - chunks.Add(headerSection); + uint headerLen; + if (extraHeaderData != null) { + var list = new ChunkList(); + list.Add(headerSection, 1); + list.Add(extraHeaderData, 1); + chunks.Add(list); + headerLen = headerSection.GetVirtualSize() + extraHeaderData.GetVirtualSize(); + } + else { + chunks.Add(headerSection); + headerLen = headerSection.GetVirtualSize(); + } foreach (var origSection in origSections) chunks.Add(origSection.Chunk); foreach (var section in sections) @@ -324,6 +433,21 @@ long WriteFile() { if (extraData != null) chunks.Add(extraData); + if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { + uint newSizeOfHeaders = SectionSizes.GetSizeOfHeaders(peImage.ImageNTHeaders.OptionalHeader.FileAlignment, headerLen); + uint oldSizeOfHeaders = peImage.ImageNTHeaders.OptionalHeader.SizeOfHeaders; + if (newSizeOfHeaders < oldSizeOfHeaders) + throw new InvalidOperationException(); + uint fileOffsetDelta = newSizeOfHeaders - oldSizeOfHeaders; + methodBodies.InitializeReusedMethodBodies(peImage, fileOffsetDelta); + foreach (var info in reusedChunks) { + if (fileOffsetDelta == 0 && (info.Chunk == metadata || info.Chunk == win32Resources)) + continue; + var offset = peImage.ToFileOffset(info.RVA) + fileOffsetDelta; + info.Chunk.SetOffset(offset, info.RVA); + } + metadata.UpdateMethodAndFieldRvas(); + } CalculateRvasAndFileOffsets(chunks, 0, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); foreach (var section in origSections) { if (section.Chunk.RVA != section.PESection.VirtualAddress) @@ -335,7 +459,20 @@ long WriteFile() { var writer = new BinaryWriter(destStream); WriteChunks(writer, chunks, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment); long imageLength = writer.BaseStream.Position - destStreamBaseOffset; - UpdateHeaderFields(writer, entryPointIsManagedOrNoEntryPoint, entryPointToken); + if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { + var pos = writer.BaseStream.Position; + foreach (var info in reusedChunks) { + Debug.Assert(info.Chunk.RVA == info.RVA); + if (info.Chunk.RVA != info.RVA) + throw new InvalidOperationException(); + writer.BaseStream.Position = destStreamBaseOffset + (uint)info.Chunk.FileOffset; + info.Chunk.VerifyWriteTo(writer); + } + methodBodies.WriteReusedMethodBodies(writer, destStreamBaseOffset); + writer.BaseStream.Position = pos; + } + var sectionSizes = new SectionSizes(peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment, headerLen, GetSectionSizeInfos); + UpdateHeaderFields(writer, entryPointIsManagedOrNoEntryPoint, entryPointToken, ref sectionSizes); OnWriterEvent(ModuleWriterEvent.EndWriteChunks); OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); @@ -355,6 +492,26 @@ long WriteFile() { return imageLength; } + static bool TryGetRealDebugDirectorySize(IPEImage peImage, out uint realSize) { + realSize = 0; + if (peImage.ImageDebugDirectories.Count == 0) + return false; + var dirs = new List(peImage.ImageDebugDirectories); + dirs.Sort((a, b) => a.AddressOfRawData.CompareTo(b.AddressOfRawData)); + var debugDataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[6]; + if (dirs[0].AddressOfRawData != debugDataDir.VirtualAddress + debugDataDir.Size) + return false; + for (int i = 1; i < dirs.Count; i++) { + uint prevEnd = (uint)dirs[i - 1].AddressOfRawData + dirs[i - 1].SizeOfData; + uint prevEndAligned = (prevEnd + 3) & ~3U; + if (!(prevEnd <= (uint)dirs[i].AddressOfRawData && (uint)dirs[i].AddressOfRawData <= prevEndAligned)) + return false; + } + + realSize = dirs[dirs.Count - 1].AddressOfRawData + dirs[dirs.Count - 1].SizeOfData - debugDataDir.VirtualAddress; + return true; + } + /// /// true if image is 64-bit /// @@ -377,16 +534,13 @@ Characteristics GetCharacteristics() { /// Updates the PE header and COR20 header fields that need updating. All sections are /// also updated, and the new ones are added. /// - void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPoint, uint entryPointToken) { + void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPoint, uint entryPointToken, ref SectionSizes sectionSizes) { long fileHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.FileHeader.StartOffset; long optionalHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.StartOffset; long sectionsOffset = destStreamBaseOffset + (long)peImage.ImageSectionHeaders[0].StartOffset; long dataDirOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.EndOffset - 16 * 8; long cor20Offset = destStreamBaseOffset + (long)imageCor20Header.FileOffset; - uint fileAlignment = peImage.ImageNTHeaders.OptionalHeader.FileAlignment; - uint sectionAlignment = peImage.ImageNTHeaders.OptionalHeader.SectionAlignment; - // Update PE file header var peOptions = Options.PEHeadersOptions; writer.BaseStream.Position = fileHeaderOffset; @@ -399,7 +553,6 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo writer.Write((ushort)(peOptions.Characteristics ?? GetCharacteristics())); // Update optional header - var sectionSizes = new SectionSizes(fileAlignment, sectionAlignment, headerSection.GetVirtualSize(), GetSectionSizeInfos); writer.BaseStream.Position = optionalHeaderOffset; bool is32BitOptionalHeader = peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader32; if (is32BitOptionalHeader) { @@ -478,7 +631,7 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo // Write a new debug directory writer.BaseStream.Position = dataDirOffset + 6 * 8; - writer.WriteDataDirectory(debugDirectory); + writer.WriteDebugDirectory(debugDirectory); // Write a new Metadata data directory writer.BaseStream.Position = dataDirOffset + 14 * 8; @@ -492,7 +645,7 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo writer.BaseStream.Position += 0x10; } foreach (var section in sections) - section.WriteHeaderTo(writer, fileAlignment, sectionAlignment, (uint)section.RVA); + section.WriteHeaderTo(writer, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment, (uint)section.RVA); // Write the .NET header writer.BaseStream.Position = cor20Offset; diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index ecc772fa0..0e5f5934e 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using dnlib.IO; @@ -10,7 +10,7 @@ namespace dnlib.DotNet.Writer { /// /// .NET resources /// - public sealed class NetResources : IChunk { + public sealed class NetResources : IReuseChunk { readonly List resources = new List(); readonly uint alignment; uint length; @@ -18,6 +18,8 @@ public sealed class NetResources : IChunk { FileOffset offset; RVA rva; + internal bool IsEmpty => resources.Count == 0; + /// public FileOffset FileOffset => offset; @@ -28,7 +30,7 @@ public sealed class NetResources : IChunk { /// Gets offset of next resource. This offset is relative to the start of /// the .NET resources and is always aligned. /// - public uint NextOffset => length; + public uint NextOffset => Utils.AlignUp(length, alignment); /// /// Constructor @@ -44,22 +46,26 @@ public sealed class NetResources : IChunk { public DataReaderChunk Add(DataReader reader) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); - length = Utils.AlignUp(length + 4 + reader.Length, alignment); + length = NextOffset + 4 + reader.Length; var data = new DataReaderChunk(ref reader); resources.Add(data); return data; } + bool IReuseChunk.CanReuse(uint origSize) => length <= origSize; + /// public void SetOffset(FileOffset offset, RVA rva) { setOffsetCalled = true; this.offset = offset; this.rva = rva; foreach (var resource in resources) { + offset = offset.AlignUp(alignment); + rva = rva.AlignUp(alignment); resource.SetOffset(offset + 4, rva + 4); uint len = 4 + resource.GetFileLength(); - offset = (offset + len).AlignUp(alignment); - rva = (rva + len).AlignUp(alignment); + offset += len; + rva += len; } } @@ -73,12 +79,12 @@ public void SetOffset(FileOffset offset, RVA rva) { public void WriteTo(BinaryWriter writer) { var rva2 = rva; foreach (var resourceData in resources) { - writer.Write(resourceData.GetFileLength()); - resourceData.VerifyWriteTo(writer); - rva2 += 4 + resourceData.GetFileLength(); int padding = (int)rva2.AlignUp(alignment) - (int)rva2; writer.WriteZeros(padding); rva2 += (uint)padding; + writer.Write(resourceData.GetFileLength()); + resourceData.VerifyWriteTo(writer); + rva2 += 4 + resourceData.GetFileLength(); } } } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index f38d2c1ff..fecf0c950 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -430,7 +430,7 @@ public void WriteTo(BinaryWriter writer) { writer.WriteDataDirectory(null); // Exception table writer.WriteDataDirectory(null); // Certificate table writer.WriteDataDirectory(RelocDirectory); - writer.WriteDataDirectory(DebugDirectory); + writer.WriteDebugDirectory(DebugDirectory); writer.WriteDataDirectory(null); // Architecture-specific data writer.WriteDataDirectory(null); // Global pointer register RVA writer.WriteDataDirectory(null); // Thread local storage diff --git a/src/DotNet/Writer/SectionSizes.cs b/src/DotNet/Writer/SectionSizes.cs index 8a5aa6652..e5a8f9ffa 100644 --- a/src/DotNet/Writer/SectionSizes.cs +++ b/src/DotNet/Writer/SectionSizes.cs @@ -35,8 +35,10 @@ readonly struct SectionSizes { public readonly uint BaseOfData, BaseOfCode; public readonly uint SizeOfCode, SizeOfInitdData, SizeOfUninitdData; + public static uint GetSizeOfHeaders(uint fileAlignment, uint headerLen) => Utils.AlignUp(headerLen, fileAlignment); + public SectionSizes(uint fileAlignment, uint sectionAlignment, uint headerLen, Func> getSectionSizeInfos) { - SizeOfHeaders = Utils.AlignUp(headerLen, fileAlignment); + SizeOfHeaders = GetSizeOfHeaders(fileAlignment, headerLen); SizeOfImage = Utils.AlignUp(SizeOfHeaders, sectionAlignment); BaseOfData = 0; BaseOfCode = 0; diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index c26e93cc8..a3e3efe6d 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Writer { /// /// Strong name signature chunk /// - public sealed class StrongNameSignature : IChunk { + public sealed class StrongNameSignature : IReuseChunk { FileOffset offset; RVA rva; int size; @@ -25,6 +25,8 @@ public sealed class StrongNameSignature : IChunk { /// Size of strong name signature public StrongNameSignature(int size) => this.size = size; + bool IReuseChunk.CanReuse(uint origSize) => (uint)size <= origSize; + /// public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index f38153dd9..20081c294 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -306,6 +306,8 @@ public void SetReadOnly() { public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; + + // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOFfset() for more info } /// diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index cabcdf399..a63bb8807 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Text; using dnlib.IO; @@ -12,7 +13,7 @@ namespace dnlib.DotNet.Writer { /// /// Writes Win32 resources /// - public sealed class Win32ResourcesChunk : IChunk { + public sealed class Win32ResourcesChunk : IReuseChunk { readonly Win32Resources win32Resources; FileOffset offset; RVA rva; @@ -220,13 +221,53 @@ public RVA GetRVA(string name) { const uint RESOURCE_STRING_ALIGNMENT = 2; const uint RESOURCE_DATA_ALIGNMENT = 4; + bool IReuseChunk.CanReuse(uint origSize) { + Debug.Assert(rva != 0); + if (rva == 0) + throw new InvalidOperationException(); + return length <= origSize; + } + + internal bool CheckValidOffset(FileOffset offset) { + GetMaxAlignment(offset, out var error); + return error == null; + } + + static uint GetMaxAlignment(FileOffset offset, out string error) { + error = null; + uint maxAlignment = 1; + maxAlignment = Math.Max(maxAlignment, RESOURCE_DIR_ALIGNMENT); + maxAlignment = Math.Max(maxAlignment, RESOURCE_DATA_HEADER_ALIGNMENT); + maxAlignment = Math.Max(maxAlignment, RESOURCE_STRING_ALIGNMENT); + maxAlignment = Math.Max(maxAlignment, RESOURCE_DATA_ALIGNMENT); + if (((uint)offset & (maxAlignment - 1)) != 0) + error = $"Win32 resources section isn't {maxAlignment}-byte aligned"; + else if (maxAlignment > ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT) + error = "maxAlignment > DEFAULT_WIN32_RESOURCES_ALIGNMENT"; + return maxAlignment; + } + /// public void SetOffset(FileOffset offset, RVA rva) { + // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOFfset() for more info + bool initAll = this.offset == 0; this.offset = offset; this.rva = rva; if (win32Resources == null) return; + if (!initAll) { + // If it's called a second time, re-do everything + dirDict.Clear(); + dirList.Clear(); + dataHeaderDict.Clear(); + dataHeaderList.Clear(); + stringsDict.Clear(); + stringsList.Clear(); + dataDict.Clear(); + dataList.Clear(); + } + FindDirectoryEntries(); // Place everything in the following order: @@ -236,16 +277,9 @@ public void SetOffset(FileOffset offset, RVA rva) { // 4. All resource data. uint rsrcOffset = 0; - - uint maxAlignment = 1; - maxAlignment = Math.Max(maxAlignment, RESOURCE_DIR_ALIGNMENT); - maxAlignment = Math.Max(maxAlignment, RESOURCE_DATA_HEADER_ALIGNMENT); - maxAlignment = Math.Max(maxAlignment, RESOURCE_STRING_ALIGNMENT); - maxAlignment = Math.Max(maxAlignment, RESOURCE_DATA_ALIGNMENT); - if (((uint)offset & (maxAlignment - 1)) != 0) - throw new ModuleWriterException($"Win32 resources section isn't {maxAlignment}-byte aligned"); - if (maxAlignment > ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT) - throw new ModuleWriterException("maxAlignment > DEFAULT_WIN32_RESOURCES_ALIGNMENT"); + var maxAlignment = GetMaxAlignment(offset, out var error); + if (error != null) + throw new ModuleWriterException(error); foreach (var dir in dirList) { rsrcOffset = Utils.AlignUp(rsrcOffset, RESOURCE_DIR_ALIGNMENT); @@ -310,7 +344,7 @@ void FindDirectoryEntries(ResourceDirectory dir) { } /// - public uint GetFileLength() => Utils.AlignUp(length, ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT); + public uint GetFileLength() => length; /// public uint GetVirtualSize() => GetFileLength(); @@ -366,8 +400,6 @@ public void WriteTo(BinaryWriter writer) { offset += reader.BytesLeft; reader.CopyTo(writer, dataBuffer); } - - writer.WriteZeros((int)(Utils.AlignUp(length, ModuleWriterBase.DEFAULT_WIN32_RESOURCES_ALIGNMENT) - length)); } uint WriteTo(BinaryWriter writer, ResourceDirectory dir) { From d5b4751219c5af1031fd9a1ca50bf7b1d64aa2b3 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:35:49 +0100 Subject: [PATCH 145/511] Misc --- src/DotNet/Emit/MethodBodyReader.cs | 2 +- src/DotNet/Writer/ByteArrayChunk.cs | 2 +- src/DotNet/Writer/DebugDirectory.cs | 4 ++-- src/DotNet/Writer/HeapBase.cs | 2 +- src/DotNet/Writer/IChunk.cs | 5 +++-- src/DotNet/Writer/Metadata.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 2 +- src/DotNet/Writer/NativeModuleWriter.cs | 2 +- src/DotNet/Writer/NetResources.cs | 2 +- src/DotNet/Writer/StrongNameSignature.cs | 2 +- src/DotNet/Writer/TablesHeap.cs | 2 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 4 ++-- 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index bd0d09709..4198304ea 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -408,7 +408,7 @@ void ReadExceptionHandlers(out uint totalBodySize) { byte b = ehReader.ReadByte(); if ((b & 0x3F) != 1) { totalBodySize = startOfHeader == uint.MaxValue ? 0 : reader.Position - startOfHeader; - return; // Not exception handler clauses + return; // Not exception handler clauses } if ((b & 0x40) != 0) ReadFatExceptionHandlers(ref ehReader); diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 81d58dfb6..dae585502 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -35,7 +35,7 @@ public sealed class ByteArrayChunk : IReuseChunk { /// but shouldn't be resized after has been called. public ByteArrayChunk(byte[] array) => this.array = array ?? Array2.Empty(); - bool IReuseChunk.CanReuse(uint origSize) => (uint)array.Length <= origSize; + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) => (uint)array.Length <= origSize; /// public void SetOffset(FileOffset offset, RVA rva) { diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index eff1b8492..a4b4ac296 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -76,8 +76,8 @@ public DebugDirectoryEntry Add(IChunk chunk) { return entry; } - bool IReuseChunk.CanReuse(uint origSize) { - uint newLength = GetLength(entries, 0, 0); + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) { + uint newLength = GetLength(entries, (FileOffset)origRva, origRva); if (newLength > origSize) return false; diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index 7246214ac..be2f3e53a 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -43,7 +43,7 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; - // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOFfset() for more info + // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOffset() for more info } /// diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index c7013a9b7..3b8fb8440 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -57,9 +57,10 @@ interface IReuseChunk : IChunk { /// /// Returns true if this chunk fits in the old location /// + /// Original RVA of data /// Size of the original location /// - bool CanReuse(uint origSize); + bool CanReuse(RVA origRva, uint origSize); } public static partial class Extensions { @@ -102,7 +103,7 @@ internal static void WriteDebugDirectory(this BinaryWriter writer, DebugDirector writer.Write(0UL); else { writer.Write((uint)chunk.RVA); - writer.Write(chunk.Count * DebugDirectory.HEADER_SIZE); + writer.Write((uint)(chunk.Count * DebugDirectory.HEADER_SIZE)); } } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index d299e117a..476d512f1 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3390,7 +3390,7 @@ protected virtual void EverythingInitialized() { const uint HEAP_ALIGNMENT = 4; - bool IReuseChunk.CanReuse(uint origSize) { + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) { // The caller should've called SetOffset() so we know our final size Debug.Assert(length != 0); if (length == 0) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index ba16baecb..105172aa2 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -997,7 +997,7 @@ protected void OnWriterEvent(ModuleWriterEvent evt) { } static readonly double[] eventToProgress = new double[(int)ModuleWriterEvent.End - (int)ModuleWriterEvent.Begin + 1 + 1] { - 0,// Begin + 0, // Begin 0.00128048488389907,// PESectionsCreated 0.0524625293056615, // ChunksCreated 0.0531036610555682, // ChunksAddedToSections diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index e77bbd0a0..7c2c8439d 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -348,7 +348,7 @@ void ReuseIfPossible(PESection section, IReuseChunk chunk, RVA origRva, uint ori return; if (chunk == null) return; - if (!chunk.CanReuse(origSize)) + if (!chunk.CanReuse(origRva, origSize)) return; if (((uint)origRva & (requiredAlignment - 1)) != 0) return; diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index 0e5f5934e..4b5102344 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -52,7 +52,7 @@ public DataReaderChunk Add(DataReader reader) { return data; } - bool IReuseChunk.CanReuse(uint origSize) => length <= origSize; + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) => length <= origSize; /// public void SetOffset(FileOffset offset, RVA rva) { diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index a3e3efe6d..e484b761e 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -25,7 +25,7 @@ public sealed class StrongNameSignature : IReuseChunk { /// Size of strong name signature public StrongNameSignature(int size) => this.size = size; - bool IReuseChunk.CanReuse(uint origSize) => (uint)size <= origSize; + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) => (uint)size <= origSize; /// public void SetOffset(FileOffset offset, RVA rva) { diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 20081c294..31700a107 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -307,7 +307,7 @@ public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; - // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOFfset() for more info + // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOffset() for more info } /// diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index a63bb8807..d24515f09 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -221,7 +221,7 @@ public RVA GetRVA(string name) { const uint RESOURCE_STRING_ALIGNMENT = 2; const uint RESOURCE_DATA_ALIGNMENT = 4; - bool IReuseChunk.CanReuse(uint origSize) { + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) { Debug.Assert(rva != 0); if (rva == 0) throw new InvalidOperationException(); @@ -249,7 +249,7 @@ static uint GetMaxAlignment(FileOffset offset, out string error) { /// public void SetOffset(FileOffset offset, RVA rva) { - // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOFfset() for more info + // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOffset() for more info bool initAll = this.offset == 0; this.offset = offset; this.rva = rva; From df53cb5e30efc2469f18f92dc95e68ddad23e30e Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:35:59 +0100 Subject: [PATCH 146/511] Remove ReadUInt16() calls from CalculatePECheckSum() --- src/DotNet/Writer/NativeModuleWriter.cs | 2 +- src/DotNet/Writer/PEHeaders.cs | 2 +- src/PE/PEExtensions.cs | 41 +++++++++++++++++-------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 7c2c8439d..5a9447382 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -483,7 +483,7 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.BeginWritePEChecksum); if (Options.AddCheckSum) { destStream.Position = destStreamBaseOffset; - uint newCheckSum = new BinaryReader(destStream).CalculatePECheckSum(imageLength, checkSumOffset); + uint newCheckSum = destStream.CalculatePECheckSum(imageLength, checkSumOffset); writer.BaseStream.Position = checkSumOffset; writer.Write(newCheckSum); } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index fecf0c950..de9281681 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -461,7 +461,7 @@ public void WriteTo(BinaryWriter writer) { /// Length of PE file public void WriteCheckSum(BinaryWriter writer, long length) { writer.BaseStream.Position = startOffset; - uint checkSum = new BinaryReader(writer.BaseStream).CalculatePECheckSum(length, checkSumOffset); + uint checkSum = writer.BaseStream.CalculatePECheckSum(length, checkSumOffset); writer.BaseStream.Position = checkSumOffset; writer.Write(checkSum); } diff --git a/src/PE/PEExtensions.cs b/src/PE/PEExtensions.cs index 10cb179a5..db0de7d60 100644 --- a/src/PE/PEExtensions.cs +++ b/src/PE/PEExtensions.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System.IO; +using System; +using System.IO; namespace dnlib.PE { /// @@ -10,23 +11,39 @@ public static partial class PEExtensions { /// /// Calculates a PE checksum /// - /// Reader + /// PE image stream positioned at the MZ bytes /// Length of image /// Offset of checksum /// PE checksum - internal static uint CalculatePECheckSum(this BinaryReader reader, long length, long checkSumOffset) { + internal static uint CalculatePECheckSum(this Stream stream, long length, long checkSumOffset) { + if ((length & 1) != 0) + ThrowInvalidOperationException("Invalid PE length"); + var buffer = new byte[(int)Math.Min(length, 0x2000)]; uint checkSum = 0; - for (long i = 0; i < length; i += 2) { - if (i == checkSumOffset) { - reader.ReadUInt32(); - i += 2; - continue; - } - checkSum += reader.ReadUInt16(); - checkSum = (ushort)(checkSum + (checkSum >> 16)); - } + checkSum = CalculatePECheckSum(stream, checkSumOffset, checkSum, buffer); + stream.Position += 2; + checkSum = CalculatePECheckSum(stream, length - checkSumOffset - 2, checkSum, buffer); ulong cks = (ulong)checkSum + (ulong)length; return (uint)cks + (uint)(cks >> 32); } + + static uint CalculatePECheckSum(Stream stream, long length, uint checkSum, byte[] buffer) { + for (long offset = 0; offset < length;) { + int len = (int)Math.Min(length - offset, buffer.Length); + int count = stream.Read(buffer, 0, len); + if (count != len) + ThrowInvalidOperationException("Couldn't read all bytes"); + + for (int i = 0; i < count;) { + checkSum += buffer[i++] | ((uint)buffer[i++] << 8); + checkSum = (ushort)(checkSum + (checkSum >> 16)); + } + + offset += count; + } + return checkSum; + } + + static void ThrowInvalidOperationException(string message) => throw new InvalidOperationException(message); } } From 7b2acf00df4d8519fe07bfc950ebab863a2d065c Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:36:07 +0100 Subject: [PATCH 147/511] Rename --- README.md | 2 +- .../Writer/{DataWriter.cs => ArrayWriter.cs} | 4 +- src/DotNet/Writer/MethodBodyWriter.cs | 20 ++++---- src/DotNet/Writer/MethodBodyWriterBase.cs | 46 +++++++++---------- src/dnlib.csproj | 1 + 5 files changed, 37 insertions(+), 36 deletions(-) rename src/DotNet/Writer/{DataWriter.cs => ArrayWriter.cs} (96%) diff --git a/README.md b/README.md index bcadb53ca..0695140c1 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ v3.0 breaking changes - `var pos = reader.Position;` <-- `pos` is a `uint` and not a `long` - `DataReader.Position` only accepts valid values and will throw (an `IOException`) if you set it to an invalid position - `FileOffset` is `uint`, used to be `long` -- `MethodBodyWriterBase` uses `DataWriter` instead of `BinaryWriter` (all virtual methods) +- `MethodBodyWriterBase` uses `ArrayWriter` instead of `BinaryWriter` (all virtual methods) - The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` Examples diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/ArrayWriter.cs similarity index 96% rename from src/DotNet/Writer/DataWriter.cs rename to src/DotNet/Writer/ArrayWriter.cs index b290d599f..7e81acb02 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/ArrayWriter.cs @@ -7,13 +7,13 @@ namespace dnlib.DotNet.Writer { /// /// Writes data /// - public unsafe struct DataWriter { + public unsafe struct ArrayWriter { public int Position => position; readonly byte[] data; int position; - public DataWriter(byte[] data) { + public ArrayWriter(byte[] data) { this.data = data; position = 0; } diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 5c7c62b1f..4e39b1ed2 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -142,7 +142,7 @@ void WriteFatHeader() { flags |= 0x10; code = new byte[12 + codeSize]; - var writer = new DataWriter(code); + var writer = new ArrayWriter(code); writer.Write(flags); writer.Write((ushort)maxStack); writer.Write(codeSize); @@ -161,7 +161,7 @@ IList GetLocals() { void WriteTinyHeader() { localVarSigTok = 0; code = new byte[1 + codeSize]; - var writer = new DataWriter(code); + var writer = new ArrayWriter(code); writer.Write((byte)((codeSize << 2) | 2)); if (WriteInstructions(ref writer) != codeSize) Error("Didn't write all code bytes"); @@ -216,7 +216,7 @@ byte[] WriteFatExceptionClauses() { } var data = new byte[numExceptionHandlers * 24 + 4]; - var writer = new DataWriter(data); + var writer = new ArrayWriter(data); writer.Write((((uint)numExceptionHandlers * 24 + 4) << 8) | 0x41); for (int i = 0; i < numExceptionHandlers; i++) { var eh = exceptionHandlers[i]; @@ -261,7 +261,7 @@ byte[] WriteSmallExceptionClauses() { } var data = new byte[numExceptionHandlers * 12 + 4]; - var writer = new DataWriter(data); + var writer = new ArrayWriter(data); writer.Write((((uint)numExceptionHandlers * 12 + 4) << 8) | 1); for (int i = 0; i < numExceptionHandlers; i++) { var eh = exceptionHandlers[i]; @@ -300,21 +300,21 @@ byte[] WriteSmallExceptionClauses() { protected override void ErrorImpl(string message) => helper.Error(message); /// - protected override void WriteInlineField(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineField(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineMethod(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineMethod(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineSig(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineSig(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineString(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineString(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineTok(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineTok(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineType(ref DataWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineType(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); } } diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index ce499ff54..0adaeee23 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -121,7 +121,7 @@ protected uint InitializeInstructionOffsets() { /// /// The instruction writer /// Number of bytes written - protected uint WriteInstructions(ref DataWriter writer) { + protected uint WriteInstructions(ref ArrayWriter writer) { firstInstructionOffset = (uint)writer.Position; var instructions = this.instructions; for (int i = 0; i < instructions.Count; i++) { @@ -139,14 +139,14 @@ protected uint WriteInstructions(ref DataWriter writer) { /// /// The instruction writer /// Current offset, relative to the first written instruction - protected uint ToInstructionOffset(ref DataWriter writer) => (uint)writer.Position - firstInstructionOffset; + protected uint ToInstructionOffset(ref ArrayWriter writer) => (uint)writer.Position - firstInstructionOffset; /// /// Writes an instruction /// /// The instruction writer /// The instruction - protected virtual void WriteInstruction(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInstruction(ref ArrayWriter writer, Instruction instr) { WriteOpCode(ref writer, instr); WriteOperand(ref writer, instr); } @@ -156,7 +156,7 @@ protected virtual void WriteInstruction(ref DataWriter writer, Instruction instr /// /// The instruction writer /// The instruction - protected void WriteOpCode(ref DataWriter writer, Instruction instr) { + protected void WriteOpCode(ref ArrayWriter writer, Instruction instr) { var code = instr.OpCode.Code; if ((ushort)code <= 0xFF) writer.Write((byte)code); @@ -179,7 +179,7 @@ protected void WriteOpCode(ref DataWriter writer, Instruction instr) { /// /// The instruction writer /// The instruction - protected void WriteOperand(ref DataWriter writer, Instruction instr) { + protected void WriteOperand(ref ArrayWriter writer, Instruction instr) { switch (instr.OpCode.OperandType) { case OperandType.InlineBrTarget: WriteInlineBrTarget(ref writer, instr); break; case OperandType.InlineField: WriteInlineField(ref writer, instr); break; @@ -211,7 +211,7 @@ protected void WriteOperand(ref DataWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteInlineBrTarget(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineBrTarget(ref ArrayWriter writer, Instruction instr) { uint displ = GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 4); writer.Write(displ); } @@ -221,14 +221,14 @@ protected virtual void WriteInlineBrTarget(ref DataWriter writer, Instruction in /// /// Instruction writer /// Instruction - protected abstract void WriteInlineField(ref DataWriter writer, Instruction instr); + protected abstract void WriteInlineField(ref ArrayWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineI(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineI(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is int) writer.Write((int)instr.Operand); else { @@ -242,7 +242,7 @@ protected virtual void WriteInlineI(ref DataWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected virtual void WriteInlineI8(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineI8(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is long) writer.Write((long)instr.Operand); else { @@ -256,14 +256,14 @@ protected virtual void WriteInlineI8(ref DataWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected abstract void WriteInlineMethod(ref DataWriter writer, Instruction instr); + protected abstract void WriteInlineMethod(ref ArrayWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineNone(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineNone(ref ArrayWriter writer, Instruction instr) { } /// @@ -271,7 +271,7 @@ protected virtual void WriteInlineNone(ref DataWriter writer, Instruction instr) /// /// Instruction writer /// Instruction - protected virtual void WriteInlinePhi(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlinePhi(ref ArrayWriter writer, Instruction instr) { } /// @@ -279,7 +279,7 @@ protected virtual void WriteInlinePhi(ref DataWriter writer, Instruction instr) /// /// Instruction writer /// Instruction - protected virtual void WriteInlineR(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineR(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is double) writer.Write((double)instr.Operand); else { @@ -293,21 +293,21 @@ protected virtual void WriteInlineR(ref DataWriter writer, Instruction instr) { /// /// Instruction writer /// Instruction - protected abstract void WriteInlineSig(ref DataWriter writer, Instruction instr); + protected abstract void WriteInlineSig(ref ArrayWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected abstract void WriteInlineString(ref DataWriter writer, Instruction instr); + protected abstract void WriteInlineString(ref ArrayWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineSwitch(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineSwitch(ref ArrayWriter writer, Instruction instr) { var targets = instr.Operand as IList; if (targets == null) { Error("switch operand is not a list of instructions"); @@ -328,21 +328,21 @@ protected virtual void WriteInlineSwitch(ref DataWriter writer, Instruction inst /// /// Instruction writer /// Instruction - protected abstract void WriteInlineTok(ref DataWriter writer, Instruction instr); + protected abstract void WriteInlineTok(ref ArrayWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected abstract void WriteInlineType(ref DataWriter writer, Instruction instr); + protected abstract void WriteInlineType(ref ArrayWriter writer, Instruction instr); /// /// Writes an operand /// /// Instruction writer /// Instruction - protected virtual void WriteInlineVar(ref DataWriter writer, Instruction instr) { + protected virtual void WriteInlineVar(ref ArrayWriter writer, Instruction instr) { var variable = instr.Operand as IVariable; if (variable == null) { Error("Operand is not a local/arg"); @@ -364,7 +364,7 @@ protected virtual void WriteInlineVar(ref DataWriter writer, Instruction instr) /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineBrTarget(ref DataWriter writer, Instruction instr) { + protected virtual void WriteShortInlineBrTarget(ref ArrayWriter writer, Instruction instr) { int displ = (int)(GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 1)); if (sbyte.MinValue <= displ && displ <= sbyte.MaxValue) writer.Write((sbyte)displ); @@ -379,7 +379,7 @@ protected virtual void WriteShortInlineBrTarget(ref DataWriter writer, Instructi /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineI(ref DataWriter writer, Instruction instr) { + protected virtual void WriteShortInlineI(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is sbyte) writer.Write((sbyte)instr.Operand); else if (instr.Operand is byte) @@ -395,7 +395,7 @@ protected virtual void WriteShortInlineI(ref DataWriter writer, Instruction inst /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineR(ref DataWriter writer, Instruction instr) { + protected virtual void WriteShortInlineR(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is float) writer.Write((float)instr.Operand); else { @@ -409,7 +409,7 @@ protected virtual void WriteShortInlineR(ref DataWriter writer, Instruction inst /// /// Instruction writer /// Instruction - protected virtual void WriteShortInlineVar(ref DataWriter writer, Instruction instr) { + protected virtual void WriteShortInlineVar(ref ArrayWriter writer, Instruction instr) { var variable = instr.Operand as IVariable; if (variable == null) { Error("Operand is not a local/arg"); diff --git a/src/dnlib.csproj b/src/dnlib.csproj index ebc33a368..618864cb6 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -302,6 +302,7 @@ + From 92b4bbf3df3de06c17ddb8f68e60654fe808e987 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:36:16 +0100 Subject: [PATCH 148/511] Rename methods --- src/DotNet/Writer/ArrayWriter.cs | 20 ++++---- src/DotNet/Writer/MethodBodyWriter.cs | 58 +++++++++++------------ src/DotNet/Writer/MethodBodyWriterBase.cs | 58 +++++++++++------------ src/dnlib.csproj | 1 - 4 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/DotNet/Writer/ArrayWriter.cs b/src/DotNet/Writer/ArrayWriter.cs index 7e81acb02..60358e69a 100644 --- a/src/DotNet/Writer/ArrayWriter.cs +++ b/src/DotNet/Writer/ArrayWriter.cs @@ -18,20 +18,20 @@ public ArrayWriter(byte[] data) { position = 0; } - public void Write(sbyte value) => data[position++] = (byte)value; - public void Write(byte value) => data[position++] = value; + public void WriteSByte(sbyte value) => data[position++] = (byte)value; + public void WriteByte(byte value) => data[position++] = value; - public void Write(short value) { + public void WriteInt16(short value) { data[position++] = (byte)value; data[position++] = (byte)(value >> 8); } - public void Write(ushort value) { + public void WriteUInt16(ushort value) { data[position++] = (byte)value; data[position++] = (byte)(value >> 8); } - public void Write(int value) { + public void WriteInt32(int value) { Debug.Assert(this.position + 4 <= data.Length); var position = this.position; fixed (byte* p = data) @@ -39,7 +39,7 @@ public void Write(int value) { this.position = position + 4; } - public void Write(uint value) { + public void WriteUInt32(uint value) { Debug.Assert(this.position + 4 <= data.Length); var position = this.position; fixed (byte* p = data) @@ -47,7 +47,7 @@ public void Write(uint value) { this.position = position + 4; } - public void Write(long value) { + public void WriteInt64(long value) { Debug.Assert(this.position + 8 <= data.Length); var position = this.position; fixed (byte* p = data) @@ -55,7 +55,7 @@ public void Write(long value) { this.position = position + 8; } - public void Write(ulong value) { + public void WriteUInt64(ulong value) { Debug.Assert(this.position + 8 <= data.Length); var position = this.position; fixed (byte* p = data) @@ -63,7 +63,7 @@ public void Write(ulong value) { this.position = position + 8; } - public void Write(float value) { + public void WriteSingle(float value) { Debug.Assert(this.position + 4 <= data.Length); var position = this.position; fixed (byte* p = data) @@ -71,7 +71,7 @@ public void Write(float value) { this.position = position + 4; } - public void Write(double value) { + public void WriteDouble(double value) { Debug.Assert(this.position + 8 <= data.Length); var position = this.position; fixed (byte* p = data) diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 4e39b1ed2..c60dd7d1d 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -143,10 +143,10 @@ void WriteFatHeader() { code = new byte[12 + codeSize]; var writer = new ArrayWriter(code); - writer.Write(flags); - writer.Write((ushort)maxStack); - writer.Write(codeSize); - writer.Write(localVarSigTok = helper.GetToken(GetLocals(), cilBody.LocalVarSigTok).Raw); + writer.WriteUInt16(flags); + writer.WriteUInt16((ushort)maxStack); + writer.WriteUInt32(codeSize); + writer.WriteUInt32(localVarSigTok = helper.GetToken(GetLocals(), cilBody.LocalVarSigTok).Raw); if (WriteInstructions(ref writer) != codeSize) Error("Didn't write all code bytes"); } @@ -162,7 +162,7 @@ void WriteTinyHeader() { localVarSigTok = 0; code = new byte[1 + codeSize]; var writer = new ArrayWriter(code); - writer.Write((byte)((codeSize << 2) | 2)); + writer.WriteByte((byte)((codeSize << 2) | 2)); if (WriteInstructions(ref writer) != codeSize) Error("Didn't write all code bytes"); } @@ -217,33 +217,33 @@ byte[] WriteFatExceptionClauses() { var data = new byte[numExceptionHandlers * 24 + 4]; var writer = new ArrayWriter(data); - writer.Write((((uint)numExceptionHandlers * 24 + 4) << 8) | 0x41); + writer.WriteUInt32((((uint)numExceptionHandlers * 24 + 4) << 8) | 0x41); for (int i = 0; i < numExceptionHandlers; i++) { var eh = exceptionHandlers[i]; uint offs1, offs2; - writer.Write((uint)eh.HandlerType); + writer.WriteUInt32((uint)eh.HandlerType); offs1 = GetOffset2(eh.TryStart); offs2 = GetOffset2(eh.TryEnd); if (offs2 <= offs1) Error("Exception handler: TryEnd <= TryStart"); - writer.Write(offs1); - writer.Write(offs2 - offs1); + writer.WriteUInt32(offs1); + writer.WriteUInt32(offs2 - offs1); offs1 = GetOffset2(eh.HandlerStart); offs2 = GetOffset2(eh.HandlerEnd); if (offs2 <= offs1) Error("Exception handler: HandlerEnd <= HandlerStart"); - writer.Write(offs1); - writer.Write(offs2 - offs1); + writer.WriteUInt32(offs1); + writer.WriteUInt32(offs2 - offs1); if (eh.HandlerType == ExceptionHandlerType.Catch) - writer.Write(helper.GetToken(eh.CatchType).Raw); + writer.WriteUInt32(helper.GetToken(eh.CatchType).Raw); else if (eh.HandlerType == ExceptionHandlerType.Filter) - writer.Write(GetOffset2(eh.FilterStart)); + writer.WriteUInt32(GetOffset2(eh.FilterStart)); else - writer.Write(0); + writer.WriteInt32(0); } if (writer.Position != data.Length) @@ -262,33 +262,33 @@ byte[] WriteSmallExceptionClauses() { var data = new byte[numExceptionHandlers * 12 + 4]; var writer = new ArrayWriter(data); - writer.Write((((uint)numExceptionHandlers * 12 + 4) << 8) | 1); + writer.WriteUInt32((((uint)numExceptionHandlers * 12 + 4) << 8) | 1); for (int i = 0; i < numExceptionHandlers; i++) { var eh = exceptionHandlers[i]; uint offs1, offs2; - writer.Write((ushort)eh.HandlerType); + writer.WriteUInt16((ushort)eh.HandlerType); offs1 = GetOffset2(eh.TryStart); offs2 = GetOffset2(eh.TryEnd); if (offs2 <= offs1) Error("Exception handler: TryEnd <= TryStart"); - writer.Write((ushort)offs1); - writer.Write((byte)(offs2 - offs1)); + writer.WriteUInt16((ushort)offs1); + writer.WriteByte((byte)(offs2 - offs1)); offs1 = GetOffset2(eh.HandlerStart); offs2 = GetOffset2(eh.HandlerEnd); if (offs2 <= offs1) Error("Exception handler: HandlerEnd <= HandlerStart"); - writer.Write((ushort)offs1); - writer.Write((byte)(offs2 - offs1)); + writer.WriteUInt16((ushort)offs1); + writer.WriteByte((byte)(offs2 - offs1)); if (eh.HandlerType == ExceptionHandlerType.Catch) - writer.Write(helper.GetToken(eh.CatchType).Raw); + writer.WriteUInt32(helper.GetToken(eh.CatchType).Raw); else if (eh.HandlerType == ExceptionHandlerType.Filter) - writer.Write(GetOffset2(eh.FilterStart)); + writer.WriteUInt32(GetOffset2(eh.FilterStart)); else - writer.Write(0); + writer.WriteInt32(0); } if (writer.Position != data.Length) @@ -300,21 +300,21 @@ byte[] WriteSmallExceptionClauses() { protected override void ErrorImpl(string message) => helper.Error(message); /// - protected override void WriteInlineField(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineField(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineMethod(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineMethod(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineSig(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineSig(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineString(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineString(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineTok(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineTok(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); /// - protected override void WriteInlineType(ref ArrayWriter writer, Instruction instr) => writer.Write(helper.GetToken(instr.Operand).Raw); + protected override void WriteInlineType(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); } } diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index 0adaeee23..73f421ebd 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -159,18 +159,18 @@ protected virtual void WriteInstruction(ref ArrayWriter writer, Instruction inst protected void WriteOpCode(ref ArrayWriter writer, Instruction instr) { var code = instr.OpCode.Code; if ((ushort)code <= 0xFF) - writer.Write((byte)code); + writer.WriteByte((byte)code); else if (((ushort)code >> 8) == 0xFE) { - writer.Write((byte)((ushort)code >> 8)); - writer.Write((byte)code); + writer.WriteByte((byte)((ushort)code >> 8)); + writer.WriteByte((byte)code); } else if (code == Code.UNKNOWN1) - writer.Write((byte)Code.Nop); + writer.WriteByte((byte)Code.Nop); else if (code == Code.UNKNOWN2) - writer.Write((ushort)(((ushort)Code.Nop << 8) | Code.Nop)); + writer.WriteUInt16((ushort)(((ushort)Code.Nop << 8) | Code.Nop)); else { Error("Unknown instruction"); - writer.Write((byte)Code.Nop); + writer.WriteByte((byte)Code.Nop); } } @@ -213,7 +213,7 @@ protected void WriteOperand(ref ArrayWriter writer, Instruction instr) { /// Instruction protected virtual void WriteInlineBrTarget(ref ArrayWriter writer, Instruction instr) { uint displ = GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 4); - writer.Write(displ); + writer.WriteUInt32(displ); } /// @@ -230,10 +230,10 @@ protected virtual void WriteInlineBrTarget(ref ArrayWriter writer, Instruction i /// Instruction protected virtual void WriteInlineI(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is int) - writer.Write((int)instr.Operand); + writer.WriteInt32((int)instr.Operand); else { Error("Operand is not an Int32"); - writer.Write(0); + writer.WriteInt32(0); } } @@ -244,10 +244,10 @@ protected virtual void WriteInlineI(ref ArrayWriter writer, Instruction instr) { /// Instruction protected virtual void WriteInlineI8(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is long) - writer.Write((long)instr.Operand); + writer.WriteInt64((long)instr.Operand); else { Error("Operand is not an Int64"); - writer.Write(0L); + writer.WriteInt64(0); } } @@ -281,10 +281,10 @@ protected virtual void WriteInlinePhi(ref ArrayWriter writer, Instruction instr) /// Instruction protected virtual void WriteInlineR(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is double) - writer.Write((double)instr.Operand); + writer.WriteDouble((double)instr.Operand); else { Error("Operand is not a Double"); - writer.Write(0D); + writer.WriteDouble(0); } } @@ -311,14 +311,14 @@ protected virtual void WriteInlineSwitch(ref ArrayWriter writer, Instruction ins var targets = instr.Operand as IList; if (targets == null) { Error("switch operand is not a list of instructions"); - writer.Write(0); + writer.WriteInt32(0); } else { uint offsetAfter = (uint)(ToInstructionOffset(ref writer) + 4 + targets.Count * 4); - writer.Write(targets.Count); + writer.WriteInt32(targets.Count); for (int i = 0; i < targets.Count; i++) { var target = targets[i]; - writer.Write(GetOffset(target) - offsetAfter); + writer.WriteUInt32(GetOffset(target) - offsetAfter); } } } @@ -346,15 +346,15 @@ protected virtual void WriteInlineVar(ref ArrayWriter writer, Instruction instr) var variable = instr.Operand as IVariable; if (variable == null) { Error("Operand is not a local/arg"); - writer.Write((ushort)0); + writer.WriteUInt16(0); } else { int index = variable.Index; if (ushort.MinValue <= index && index <= ushort.MaxValue) - writer.Write((ushort)index); + writer.WriteUInt16((ushort)index); else { Error("Local/arg index doesn't fit in a UInt16"); - writer.Write((ushort)0); + writer.WriteUInt16(0); } } } @@ -367,10 +367,10 @@ protected virtual void WriteInlineVar(ref ArrayWriter writer, Instruction instr) protected virtual void WriteShortInlineBrTarget(ref ArrayWriter writer, Instruction instr) { int displ = (int)(GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 1)); if (sbyte.MinValue <= displ && displ <= sbyte.MaxValue) - writer.Write((sbyte)displ); + writer.WriteSByte((sbyte)displ); else { Error("Target instruction is too far away for a short branch. Use the long branch or call CilBody.SimplifyBranches() and CilBody.OptimizeBranches()"); - writer.Write((byte)0); + writer.WriteByte(0); } } @@ -381,12 +381,12 @@ protected virtual void WriteShortInlineBrTarget(ref ArrayWriter writer, Instruct /// Instruction protected virtual void WriteShortInlineI(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is sbyte) - writer.Write((sbyte)instr.Operand); + writer.WriteSByte((sbyte)instr.Operand); else if (instr.Operand is byte) - writer.Write((byte)instr.Operand); + writer.WriteByte((byte)instr.Operand); else { Error("Operand is not a Byte or a SByte"); - writer.Write((byte)0); + writer.WriteByte(0); } } @@ -397,10 +397,10 @@ protected virtual void WriteShortInlineI(ref ArrayWriter writer, Instruction ins /// Instruction protected virtual void WriteShortInlineR(ref ArrayWriter writer, Instruction instr) { if (instr.Operand is float) - writer.Write((float)instr.Operand); + writer.WriteSingle((float)instr.Operand); else { Error("Operand is not a Single"); - writer.Write(0F); + writer.WriteSingle(0); } } @@ -413,15 +413,15 @@ protected virtual void WriteShortInlineVar(ref ArrayWriter writer, Instruction i var variable = instr.Operand as IVariable; if (variable == null) { Error("Operand is not a local/arg"); - writer.Write((byte)0); + writer.WriteByte(0); } else { int index = variable.Index; if (byte.MinValue <= index && index <= byte.MaxValue) - writer.Write((byte)index); + writer.WriteByte((byte)index); else { Error("Local/arg index doesn't fit in a Byte. Use the longer ldloc/ldarg/stloc/starg instruction."); - writer.Write((byte)0); + writer.WriteByte(0); } } } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 618864cb6..67638d85d 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -309,7 +309,6 @@ - From 71173eb8b9806bce5db7a3cca526b6dfc8c40ab1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:36:25 +0100 Subject: [PATCH 149/511] Use a new DataWriter --- README.md | 1 + src/DotNet/CpuArch.cs | 10 +- src/DotNet/MD/ColumnInfo.cs | 5 +- .../Pdb/Portable/ImportScopeBlobWriter.cs | 4 +- .../Portable/LocalConstantSigBlobWriter.cs | 10 +- .../PortablePdbCustomDebugInfoWriter.cs | 6 +- src/DotNet/Utils.cs | 70 ------- src/DotNet/Writer/BlobHeap.cs | 6 +- src/DotNet/Writer/ByteArrayChunk.cs | 2 +- src/DotNet/Writer/ChunkListBase.cs | 2 +- src/DotNet/Writer/CustomAttributeWriter.cs | 12 +- src/DotNet/Writer/DataReaderChunk.cs | 2 +- src/DotNet/Writer/DataWriter.cs | 173 ++++++++++++++++++ src/DotNet/Writer/DebugDirectory.cs | 4 +- src/DotNet/Writer/DeclSecurityWriter.cs | 73 ++++---- src/DotNet/Writer/Extensions.cs | 4 +- src/DotNet/Writer/GuidHeap.cs | 2 +- src/DotNet/Writer/HeapBase.cs | 4 +- src/DotNet/Writer/IChunk.cs | 12 +- src/DotNet/Writer/ImageCor20Header.cs | 2 +- src/DotNet/Writer/ImportAddressTable.cs | 2 +- src/DotNet/Writer/ImportDirectory.cs | 2 +- src/DotNet/Writer/MDTableWriter.cs | 106 +++++------ src/DotNet/Writer/ManagedExportsWriter.cs | 60 +++--- src/DotNet/Writer/MarshalBlobWriter.cs | 5 +- src/DotNet/Writer/Metadata.cs | 20 +- src/DotNet/Writer/MetadataHeader.cs | 2 +- src/DotNet/Writer/MethodBody.cs | 2 +- src/DotNet/Writer/MethodBodyChunks.cs | 6 +- src/DotNet/Writer/ModuleWriter.cs | 4 +- src/DotNet/Writer/ModuleWriterBase.cs | 10 +- src/DotNet/Writer/NativeModuleWriter.cs | 96 +++++----- src/DotNet/Writer/NetResources.cs | 2 +- src/DotNet/Writer/PEHeaders.cs | 18 +- src/DotNet/Writer/PESection.cs | 2 +- src/DotNet/Writer/PdbHeap.cs | 2 +- src/DotNet/Writer/RelocDirectory.cs | 2 +- src/DotNet/Writer/SignatureWriter.cs | 12 +- src/DotNet/Writer/StartupStub.cs | 2 +- src/DotNet/Writer/StringsHeap.cs | 2 +- src/DotNet/Writer/StrongNameSignature.cs | 2 +- src/DotNet/Writer/TablesHeap.cs | 2 +- src/DotNet/Writer/USHeap.cs | 8 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 6 +- src/DotNet/Writer/WriterUtils.cs | 8 +- src/IO/DataReader.cs | 24 +++ src/dnlib.csproj | 1 + 47 files changed, 466 insertions(+), 346 deletions(-) create mode 100644 src/DotNet/Writer/DataWriter.cs diff --git a/README.md b/README.md index 0695140c1..b243f3706 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ v3.0 breaking changes - `DataReader.Position` only accepts valid values and will throw (an `IOException`) if you set it to an invalid position - `FileOffset` is `uint`, used to be `long` - `MethodBodyWriterBase` uses `ArrayWriter` instead of `BinaryWriter` (all virtual methods) +- `ModuleWriter` and `NativeModuleWriter` use `DataWriter` instead of `BinaryWriter` - The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` Examples diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index ad53355c8..4e3e9702b 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -83,7 +83,7 @@ public bool TryGetExportedRvaFromStub(ref DataReader reader, IPEImage peImage, o /// Image base /// RVA of this stub /// RVA of a pointer-sized field that contains the absolute address of the managed function - public abstract void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva); + public abstract void WriteStub(StubType stubType, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva); } sealed class X86CpuArch : CpuArch { @@ -138,7 +138,7 @@ public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDire } } - public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + public override void WriteStub(StubType stubType, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { switch (stubType) { case StubType.Export: case StubType.EntryPoint: @@ -211,7 +211,7 @@ public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDire } } - public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + public override void WriteStub(StubType stubType, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { switch (stubType) { case StubType.Export: case StubType.EntryPoint: @@ -306,7 +306,7 @@ public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDire } } - public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + public override void WriteStub(StubType stubType, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { switch (stubType) { case StubType.Export: case StubType.EntryPoint: @@ -376,7 +376,7 @@ public override void WriteStubRelocs(StubType stubType, RelocDirectory relocDire } } - public override void WriteStub(StubType stubType, BinaryWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { + public override void WriteStub(StubType stubType, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { switch (stubType) { case StubType.Export: case StubType.EntryPoint: diff --git a/src/DotNet/MD/ColumnInfo.cs b/src/DotNet/MD/ColumnInfo.cs index 2295fdedb..1cab63dfc 100644 --- a/src/DotNet/MD/ColumnInfo.cs +++ b/src/DotNet/MD/ColumnInfo.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.IO; +using dnlib.DotNet.Writer; using dnlib.IO; namespace dnlib.DotNet.MD { @@ -100,7 +101,7 @@ internal uint Unsafe_Read24(ref DataReader reader) { /// /// The writer position on this column /// The column value - public void Write(BinaryWriter writer, uint value) { + public void Write(DataWriter writer, uint value) { switch (size) { case 1: writer.Write((byte)value); break; case 2: writer.Write((ushort)value); break; @@ -109,7 +110,7 @@ public void Write(BinaryWriter writer, uint value) { } } - internal void Write24(BinaryWriter writer, uint value) { + internal void Write24(DataWriter writer, uint value) { Debug.Assert(size == 2 || size == 4); if (size == 2) writer.Write((ushort)value); diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index 62331d5c8..76fe84953 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -18,7 +18,7 @@ readonly struct ImportScopeBlobWriter { this.blobHeap = blobHeap; } - public static void Write(IWriterError helper, Metadata systemMetadata, BinaryWriter writer, BlobHeap blobHeap, IList imports) { + public static void Write(IWriterError helper, Metadata systemMetadata, DataWriter writer, BlobHeap blobHeap, IList imports) { var blobWriter = new ImportScopeBlobWriter(helper, systemMetadata, blobHeap); blobWriter.Write(writer, imports); } @@ -32,7 +32,7 @@ uint WriteUTF8(string s) { return blobHeap.Add(bytes); } - void Write(BinaryWriter writer, IList imports) { + void Write(DataWriter writer, IList imports) { foreach (var import in imports) { if (!ImportDefinitionKindUtils.ToImportDefinitionKind(import.Kind, out uint rawKind)) { helper.Error("Unknown import definition kind: " + import.Kind.ToString()); diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index 97889c088..8c3366e4b 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -15,12 +15,12 @@ readonly struct LocalConstantSigBlobWriter { this.systemMetadata = systemMetadata; } - public static void Write(IWriterError helper, Metadata systemMetadata, BinaryWriter writer, TypeSig type, object value) { + public static void Write(IWriterError helper, Metadata systemMetadata, DataWriter writer, TypeSig type, object value) { var sigWriter = new LocalConstantSigBlobWriter(helper, systemMetadata); sigWriter.Write(writer, type, value); } - void Write(BinaryWriter writer, TypeSig type, object value) { + void Write(DataWriter writer, TypeSig type, object value) { for (; ; type = type.Next) { if (type == null) return; @@ -94,7 +94,7 @@ void Write(BinaryWriter writer, TypeSig type, object value) { case ElementType.U4: case ElementType.I8: case ElementType.U8: - writer.BaseStream.Position--; + writer.Position--; writer.Write((byte)underlyingType.GetElementType()); WritePrimitiveValue(writer, underlyingType.GetElementType(), value); WriteTypeDefOrRef(writer, tdr); @@ -204,7 +204,7 @@ static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String return false; } - void WritePrimitiveValue(BinaryWriter writer, ElementType et, object value) { + void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { switch (et) { case ElementType.Boolean: if (value is bool) @@ -301,7 +301,7 @@ void WritePrimitiveValue(BinaryWriter writer, ElementType et, object value) { } } - void WriteTypeDefOrRef(BinaryWriter writer, ITypeDefOrRef tdr) { + void WriteTypeDefOrRef(DataWriter writer, ITypeDefOrRef tdr) { if (!MD.CodedToken.TypeDefOrRef.Encode(systemMetadata.GetToken(tdr), out uint codedToken)) { helper.Error("Couldn't encode a TypeDefOrRef"); return; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 7295edf84..3b0624d6b 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -14,14 +14,14 @@ readonly struct PortablePdbCustomDebugInfoWriter { readonly SerializerMethodContext methodContext; readonly Metadata systemMetadata; readonly MemoryStream outStream; - readonly BinaryWriter writer; + readonly DataWriter writer; - public static byte[] Write(IPortablePdbCustomDebugInfoWriterHelper helper, SerializerMethodContext methodContext, Metadata systemMetadata, PdbCustomDebugInfo cdi, BinaryWriterContext context) { + public static byte[] Write(IPortablePdbCustomDebugInfoWriterHelper helper, SerializerMethodContext methodContext, Metadata systemMetadata, PdbCustomDebugInfo cdi, DataWriterContext context) { var writer = new PortablePdbCustomDebugInfoWriter(helper, methodContext, systemMetadata, context); return writer.Write(cdi); } - PortablePdbCustomDebugInfoWriter(IPortablePdbCustomDebugInfoWriterHelper helper, SerializerMethodContext methodContext, Metadata systemMetadata, BinaryWriterContext context) { + PortablePdbCustomDebugInfoWriter(IPortablePdbCustomDebugInfoWriterHelper helper, SerializerMethodContext methodContext, Metadata systemMetadata, DataWriterContext context) { this.helper = helper; this.methodContext = methodContext; this.systemMetadata = systemMetadata; diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index 72cb61ead..d58124975 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -317,75 +317,5 @@ static string GetCanonicalLocale(string locale) { /// Value /// Alignment public static int AlignUp(int v, uint alignment) => (int)AlignUp((uint)v, alignment); - - /// - /// Gets length of compressed integer - /// - /// Integer - /// Size of compressed integer in bytes (1, 2 or 4 bytes) - /// can't be compressed (too big) - public static int GetCompressedUInt32Length(uint value) { - if (value <= 0x7F) - return 1; - if (value <= 0x3FFF) - return 2; - if (value <= 0x1FFFFFFF) - return 4; - throw new ArgumentOutOfRangeException("UInt32 value can't be compressed"); - } - - /// - /// Writes a compressed - /// - /// Writer - /// Value - /// can't be compressed (too big) - public static void WriteCompressedUInt32(this BinaryWriter writer, uint value) { - if (value <= 0x7F) - writer.Write((byte)value); - else if (value <= 0x3FFF) { - writer.Write((byte)((value >> 8) | 0x80)); - writer.Write((byte)value); - } - else if (value <= 0x1FFFFFFF) { - writer.Write((byte)((value >> 24) | 0xC0)); - writer.Write((byte)(value >> 16)); - writer.Write((byte)(value >> 8)); - writer.Write((byte)value); - } - else - throw new ArgumentOutOfRangeException("UInt32 value can't be compressed"); - } - - /// - /// Writes a compressed - /// - /// Writer - /// Value - /// can't be compressed (too big/small) - public static void WriteCompressedInt32(this BinaryWriter writer, int value) { - // This is almost identical to compressing a UInt32, except that we first - // recode value so the sign bit is in bit 0. Then we compress it the same - // way a UInt32 is compressed. - uint sign = (uint)value >> 31; - if (-0x40 <= value && value <= 0x3F) { - uint v = (uint)((value & 0x3F) << 1) | sign; - writer.Write((byte)v); - } - else if (-0x2000 <= value && value <= 0x1FFF) { - uint v = ((uint)(value & 0x1FFF) << 1) | sign; - writer.Write((byte)((v >> 8) | 0x80)); - writer.Write((byte)v); - } - else if (-0x10000000 <= value && value <= 0x0FFFFFFF) { - uint v = ((uint)(value & 0x0FFFFFFF) << 1) | sign; - writer.Write((byte)((v >> 24) | 0xC0)); - writer.Write((byte)(v >> 16)); - writer.Write((byte)(v >> 8)); - writer.Write((byte)v); - } - else - throw new ArgumentOutOfRangeException("Int32 value can't be compressed"); - } } } diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index 10b8a5c6a..545578e80 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -98,7 +98,7 @@ uint AddToCache(byte[] data) { public override uint GetRawLength() => nextOffset; /// - protected override void WriteToImpl(BinaryWriter writer) { + protected override void WriteToImpl(DataWriter writer) { if (originalData != null) writer.Write(originalData); else @@ -121,7 +121,7 @@ protected override void WriteToImpl(BinaryWriter writer) { } /// - public int GetRawDataSize(byte[] data) => Utils.GetCompressedUInt32Length((uint)data.Length) + data.Length; + public int GetRawDataSize(byte[] data) => DataWriter.GetCompressedUInt32Length((uint)data.Length) + data.Length; /// public void SetRawData(uint offset, byte[] rawData) { @@ -133,7 +133,7 @@ public void SetRawData(uint offset, byte[] rawData) { /// public IEnumerable> GetAllRawData() { var memStream = new MemoryStream(); - var writer = new BinaryWriter(memStream); + var writer = new DataWriter(memStream); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var data in cached) { memStream.Position = 0; diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index dae585502..414c58e36 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -50,7 +50,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) => writer.Write(array); + public void WriteTo(DataWriter writer) => writer.Write(array); /// public override int GetHashCode() => Utils.GetHashCode(array); diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index 1390bed89..583b1cd02 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -104,7 +104,7 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => virtualSize; /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { var offset2 = offset; foreach (var elem in chunks) { if (elem.chunk.GetVirtualSize() == 0) diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index b7881dbcb..a424e607c 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -18,7 +18,7 @@ public struct CustomAttributeWriter : IDisposable { readonly ICustomAttributeWriterHelper helper; RecursionCounter recursionCounter; readonly MemoryStream outStream; - readonly BinaryWriter writer; + readonly DataWriter writer; readonly bool disposeStream; GenericArguments genericArguments; @@ -35,7 +35,7 @@ public static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute } } - internal static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute ca, BinaryWriterContext context) { + internal static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute ca, DataWriterContext context) { using (var writer = new CustomAttributeWriter(helper, context)) { writer.Write(ca); return writer.GetResult(); @@ -55,7 +55,7 @@ internal static byte[] Write(ICustomAttributeWriterHelper helper, IList namedArgs, BinaryWriterContext context) { + internal static byte[] Write(ICustomAttributeWriterHelper helper, IList namedArgs, DataWriterContext context) { using (var writer = new CustomAttributeWriter(helper, context)) { writer.Write(namedArgs); return writer.GetResult(); @@ -66,12 +66,12 @@ internal static byte[] Write(ICustomAttributeWriterHelper helper, IList virtualSize; /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { data.Position = 0; data.CopyTo(writer); } diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs new file mode 100644 index 000000000..a646941bc --- /dev/null +++ b/src/DotNet/Writer/DataWriter.cs @@ -0,0 +1,173 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; + +namespace dnlib.DotNet.Writer { +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + /// + /// Writes data + /// + public sealed class DataWriter { + readonly Stream stream; + readonly byte[] buffer; + const int BUFFER_LEN = 8; + + internal Stream InternalStream => stream; + + public long Position { + get => stream.Position; + set => stream.Position = value; + } + + public DataWriter(Stream stream) { + this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); + buffer = new byte[BUFFER_LEN]; + } + + static void ThrowArgumentOutOfRangeException(string message) => throw new ArgumentOutOfRangeException(message); + + public void Write(bool value) => stream.WriteByte(value ? (byte)1 : (byte)0); + public void Write(sbyte value) => stream.WriteByte((byte)value); + public void Write(byte value) => stream.WriteByte(value); + + public void Write(short value) { + var buffer = this.buffer; + buffer[0] = (byte)value; + buffer[1] = (byte)(value >> 8); + stream.Write(buffer, 0, 2); + } + + public void Write(ushort value) { + var buffer = this.buffer; + buffer[0] = (byte)value; + buffer[1] = (byte)(value >> 8); + stream.Write(buffer, 0, 2); + } + + public void Write(int value) { + var buffer = this.buffer; + buffer[0] = (byte)value; + buffer[1] = (byte)(value >> 8); + buffer[2] = (byte)(value >> 16); + buffer[3] = (byte)(value >> 24); + stream.Write(buffer, 0, 4); + } + + public void Write(uint value) { + var buffer = this.buffer; + buffer[0] = (byte)value; + buffer[1] = (byte)(value >> 8); + buffer[2] = (byte)(value >> 16); + buffer[3] = (byte)(value >> 24); + stream.Write(buffer, 0, 4); + } + + public void Write(long value) { + var buffer = this.buffer; + buffer[0] = (byte)value; + buffer[1] = (byte)(value >> 8); + buffer[2] = (byte)(value >> 16); + buffer[3] = (byte)(value >> 24); + buffer[4] = (byte)(value >> 32); + buffer[5] = (byte)(value >> 40); + buffer[6] = (byte)(value >> 48); + buffer[7] = (byte)(value >> 56); + stream.Write(buffer, 0, 8); + } + + public void Write(ulong value) { + var buffer = this.buffer; + buffer[0] = (byte)value; + buffer[1] = (byte)(value >> 8); + buffer[2] = (byte)(value >> 16); + buffer[3] = (byte)(value >> 24); + buffer[4] = (byte)(value >> 32); + buffer[5] = (byte)(value >> 40); + buffer[6] = (byte)(value >> 48); + buffer[7] = (byte)(value >> 56); + stream.Write(buffer, 0, 8); + } + + public unsafe void Write(float value) { + uint tmp = *(uint*)&value; + var buffer = this.buffer; + buffer[0] = (byte)tmp; + buffer[1] = (byte)(tmp >> 8); + buffer[2] = (byte)(tmp >> 16); + buffer[3] = (byte)(tmp >> 24); + stream.Write(buffer, 0, 4); + } + + public unsafe void Write(double value) { + ulong tmp = *(ulong*)&value; + var buffer = this.buffer; + buffer[0] = (byte)tmp; + buffer[1] = (byte)(tmp >> 8); + buffer[2] = (byte)(tmp >> 16); + buffer[3] = (byte)(tmp >> 24); + buffer[4] = (byte)(tmp >> 32); + buffer[5] = (byte)(tmp >> 40); + buffer[6] = (byte)(tmp >> 48); + buffer[7] = (byte)(tmp >> 56); + stream.Write(buffer, 0, 8); + } + + public void Write(byte[] source) => stream.Write(source, 0, source.Length); + public void Write(byte[] source, int index, int length) => stream.Write(source, index, length); + + public void WriteCompressedUInt32(uint value) { + if (value <= 0x7F) + stream.WriteByte((byte)value); + else if (value <= 0x3FFF) { + stream.WriteByte((byte)((value >> 8) | 0x80)); + stream.WriteByte((byte)value); + } + else if (value <= 0x1FFFFFFF) { + stream.WriteByte((byte)((value >> 24) | 0xC0)); + stream.WriteByte((byte)(value >> 16)); + stream.WriteByte((byte)(value >> 8)); + stream.WriteByte((byte)value); + } + else + ThrowArgumentOutOfRangeException("UInt32 value can't be compressed"); + } + + public void WriteCompressedInt32(int value) { + // This is almost identical to compressing a UInt32, except that we first + // recode value so the sign bit is in bit 0. Then we compress it the same + // way a UInt32 is compressed. + uint sign = (uint)value >> 31; + if (-0x40 <= value && value <= 0x3F) { + uint v = (uint)((value & 0x3F) << 1) | sign; + stream.WriteByte((byte)v); + } + else if (-0x2000 <= value && value <= 0x1FFF) { + uint v = ((uint)(value & 0x1FFF) << 1) | sign; + stream.WriteByte((byte)((v >> 8) | 0x80)); + stream.WriteByte((byte)v); + } + else if (-0x10000000 <= value && value <= 0x0FFFFFFF) { + uint v = ((uint)(value & 0x0FFFFFFF) << 1) | sign; + stream.WriteByte((byte)((v >> 24) | 0xC0)); + stream.WriteByte((byte)(v >> 16)); + stream.WriteByte((byte)(v >> 8)); + stream.WriteByte((byte)v); + } + else + ThrowArgumentOutOfRangeException("Int32 value can't be compressed"); + } + + public static int GetCompressedUInt32Length(uint value) { + if (value <= 0x7F) + return 1; + if (value <= 0x3FFF) + return 2; + if (value <= 0x1FFFFFFF) + return 4; + ThrowArgumentOutOfRangeException("UInt32 value can't be compressed"); + return 0; + } + } +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member +} diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index a4b4ac296..e87c5d1f4 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -111,7 +111,7 @@ static uint GetLength(List entries, FileOffset offset, RVA public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { uint offset = 0; foreach (var entry in entries) { writer.Write(entry.DebugDirectory.Characteristics); @@ -132,7 +132,7 @@ public void WriteTo(BinaryWriter writer) { } } - static void WriteAlign(BinaryWriter writer, ref uint offs) { + static void WriteAlign(DataWriter writer, ref uint offs) { uint align = Utils.AlignUp(offs, DEFAULT_DEBUGDIRECTORY_ALIGNMENT) - offs; offs += align; writer.WriteZeros((int)align); diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index c5a573f92..76ab14c63 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -12,7 +12,7 @@ namespace dnlib.DotNet.Writer { public readonly struct DeclSecurityWriter : ICustomAttributeWriterHelper { readonly ModuleDef module; readonly IWriterError helper; - readonly BinaryWriterContext context; + readonly DataWriterContext context; /// /// Creates a DeclSecurity blob from @@ -24,10 +24,10 @@ namespace dnlib.DotNet.Writer { public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper) => new DeclSecurityWriter(module, helper, null).Write(secAttrs); - internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, BinaryWriterContext context) => + internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, DataWriterContext context) => new DeclSecurityWriter(module, helper, context).Write(secAttrs); - DeclSecurityWriter(ModuleDef module, IWriterError helper, BinaryWriterContext context) { + DeclSecurityWriter(ModuleDef module, IWriterError helper, DataWriterContext context) { this.module = module; this.helper = helper; this.context = context; @@ -46,46 +46,45 @@ byte[] Write(IList secAttrs) { byte[] WriteFormat1(string xml) => Encoding.Unicode.GetBytes(xml); byte[] WriteFormat2(IList secAttrs) { - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) { - writer.Write((byte)'.'); - WriteCompressedUInt32(writer, (uint)secAttrs.Count); + var stream = new MemoryStream(); + var writer = new DataWriter(stream); + writer.Write((byte)'.'); + WriteCompressedUInt32(writer, (uint)secAttrs.Count); - foreach (var sa in secAttrs) { - if (sa == null) { - helper.Error("SecurityAttribute is null"); - Write(writer, UTF8String.Empty); - WriteCompressedUInt32(writer, 1); - WriteCompressedUInt32(writer, 0); - continue; - } - var attrType = sa.AttributeType; - string fqn; - if (attrType == null) { - helper.Error("SecurityAttribute attribute type is null"); - fqn = string.Empty; - } - else - fqn = attrType.AssemblyQualifiedName; - Write(writer, fqn); - - var namedArgsBlob = context == null ? - CustomAttributeWriter.Write(this, sa.NamedArguments) : - CustomAttributeWriter.Write(this, sa.NamedArguments, context); - if (namedArgsBlob.Length > 0x1FFFFFFF) { - helper.Error("Named arguments blob size doesn't fit in 29 bits"); - namedArgsBlob = Array2.Empty(); - } - WriteCompressedUInt32(writer, (uint)namedArgsBlob.Length); - writer.Write(namedArgsBlob); + foreach (var sa in secAttrs) { + if (sa == null) { + helper.Error("SecurityAttribute is null"); + Write(writer, UTF8String.Empty); + WriteCompressedUInt32(writer, 1); + WriteCompressedUInt32(writer, 0); + continue; + } + var attrType = sa.AttributeType; + string fqn; + if (attrType == null) { + helper.Error("SecurityAttribute attribute type is null"); + fqn = string.Empty; } + else + fqn = attrType.AssemblyQualifiedName; + Write(writer, fqn); - return stream.ToArray(); + var namedArgsBlob = context == null ? + CustomAttributeWriter.Write(this, sa.NamedArguments) : + CustomAttributeWriter.Write(this, sa.NamedArguments, context); + if (namedArgsBlob.Length > 0x1FFFFFFF) { + helper.Error("Named arguments blob size doesn't fit in 29 bits"); + namedArgsBlob = Array2.Empty(); + } + WriteCompressedUInt32(writer, (uint)namedArgsBlob.Length); + writer.Write(namedArgsBlob); } + + return stream.ToArray(); } - uint WriteCompressedUInt32(BinaryWriter writer, uint value) => writer.WriteCompressedUInt32(helper, value); - void Write(BinaryWriter writer, UTF8String s) => writer.Write(helper, s); + uint WriteCompressedUInt32(DataWriter writer, uint value) => writer.WriteCompressedUInt32(helper, value); + void Write(DataWriter writer, UTF8String s) => writer.Write(helper, s); void IWriterError.Error(string message) => helper.Error(message); bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); } diff --git a/src/DotNet/Writer/Extensions.cs b/src/DotNet/Writer/Extensions.cs index 71a92c83d..642240968 100644 --- a/src/DotNet/Writer/Extensions.cs +++ b/src/DotNet/Writer/Extensions.cs @@ -1,7 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; - namespace dnlib.DotNet.Writer { /// /// Extension methods @@ -12,7 +10,7 @@ public static partial class Extensions { /// /// this /// Number of zeros - public static void WriteZeros(this BinaryWriter writer, int count) { + public static void WriteZeros(this DataWriter writer, int count) { if (count <= 0x20) { for (int i = 0; i < count; i++) writer.Write((byte)0); diff --git a/src/DotNet/Writer/GuidHeap.cs b/src/DotNet/Writer/GuidHeap.cs index 759b2e8a4..862c8e312 100644 --- a/src/DotNet/Writer/GuidHeap.cs +++ b/src/DotNet/Writer/GuidHeap.cs @@ -38,7 +38,7 @@ public uint Add(Guid? guid) { public override uint GetRawLength() => (uint)guids.Count * 16; /// - protected override void WriteToImpl(BinaryWriter writer) { + protected override void WriteToImpl(DataWriter writer) { uint offset = 0; foreach (var kv in guids) { if (userRawData == null || !userRawData.TryGetValue(offset, out var rawData)) diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index be2f3e53a..1e8c3ce18 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -59,7 +59,7 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { public abstract uint GetRawLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { WriteToImpl(writer); writer.WriteZeros((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength())); } @@ -68,7 +68,7 @@ public void WriteTo(BinaryWriter writer) { /// Writes all data to at its current location. /// /// Destination - protected abstract void WriteToImpl(BinaryWriter writer); + protected abstract void WriteToImpl(DataWriter writer); /// public override string ToString() => Name; diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index 3b8fb8440..bae2182d2 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -47,7 +47,7 @@ public interface IChunk { /// chunk's file position. /// /// Destination - void WriteTo(BinaryWriter writer); + void WriteTo(DataWriter writer); } /// @@ -70,16 +70,16 @@ public static partial class Extensions { /// this /// Destination /// Not all bytes were written - public static void VerifyWriteTo(this IChunk chunk, BinaryWriter writer) { + public static void VerifyWriteTo(this IChunk chunk, DataWriter writer) { #if DEBUG // PERF: Calling the BaseStream property is pretty expensive so only do it in DEBUG builds - long pos = writer.BaseStream.Position; + long pos = writer.Position; #endif // Uncomment this to add some debug info, useful when comparing old vs new version //System.Diagnostics.Debug.WriteLine($" RVA 0x{(uint)chunk.RVA:X8} OFFS 0x{(uint)chunk.FileOffset:X8} VSIZE 0x{chunk.GetVirtualSize():X8} {chunk.GetType().FullName}"); chunk.WriteTo(writer); #if DEBUG - if (writer.BaseStream.Position - pos != chunk.GetFileLength()) + if (writer.Position - pos != chunk.GetFileLength()) throw new IOException("Did not write all bytes"); #endif } @@ -89,7 +89,7 @@ public static void VerifyWriteTo(this IChunk chunk, BinaryWriter writer) { /// /// Writer /// The data - internal static void WriteDataDirectory(this BinaryWriter writer, IChunk chunk) { + internal static void WriteDataDirectory(this DataWriter writer, IChunk chunk) { if (chunk == null || chunk.GetVirtualSize() == 0) writer.Write(0UL); else { @@ -98,7 +98,7 @@ internal static void WriteDataDirectory(this BinaryWriter writer, IChunk chunk) } } - internal static void WriteDebugDirectory(this BinaryWriter writer, DebugDirectory chunk) { + internal static void WriteDebugDirectory(this DataWriter writer, DebugDirectory chunk) { if (chunk == null || chunk.GetVirtualSize() == 0) writer.Write(0UL); else { diff --git a/src/DotNet/Writer/ImageCor20Header.cs b/src/DotNet/Writer/ImageCor20Header.cs index e672439c4..11e2d6dbc 100644 --- a/src/DotNet/Writer/ImageCor20Header.cs +++ b/src/DotNet/Writer/ImageCor20Header.cs @@ -115,7 +115,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { writer.Write(0x48); // cb writer.Write(options.MajorRuntimeVersion ?? Cor20HeaderOptions.DEFAULT_MAJOR_RT_VER); writer.Write(options.MinorRuntimeVersion ?? Cor20HeaderOptions.DEFAULT_MINOR_RT_VER); diff --git a/src/DotNet/Writer/ImportAddressTable.cs b/src/DotNet/Writer/ImportAddressTable.cs index df35332c1..11bee424d 100644 --- a/src/DotNet/Writer/ImportAddressTable.cs +++ b/src/DotNet/Writer/ImportAddressTable.cs @@ -49,7 +49,7 @@ public uint GetFileLength() { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { if (!Enable) return; if (is64bit) { diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index e2bf2b162..55a8e18ca 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -88,7 +88,7 @@ public uint GetFileLength() { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { if (!Enable) return; writer.Write((uint)importLookupTableRVA); diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index 1bdf9ae2c..5f7b96573 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -14,7 +14,7 @@ public static class MDTableWriter { /// Writer /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -37,7 +37,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -57,7 +57,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -82,7 +82,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -97,7 +97,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -116,7 +116,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -131,7 +131,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns3 = columns[3]; var columns4 = columns[4]; @@ -154,7 +154,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -169,7 +169,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; var stringsHeap = metadata.StringsHeap; @@ -187,7 +187,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -204,7 +204,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -224,7 +224,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; var columns3 = columns[3]; @@ -243,7 +243,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -262,7 +262,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -279,7 +279,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -297,7 +297,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; for (int i = 0; i < table.Rows; i++) { @@ -314,7 +314,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; for (int i = 0; i < table.Rows; i++) { @@ -330,7 +330,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -345,7 +345,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -362,7 +362,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -377,7 +377,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -396,7 +396,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -413,7 +413,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -428,7 +428,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -447,7 +447,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -465,7 +465,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -484,7 +484,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var stringsHeap = metadata.StringsHeap; @@ -500,7 +500,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; for (int i = 0; i < table.Rows; i++) { @@ -515,7 +515,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -536,7 +536,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; for (int i = 0; i < table.Rows; i++) { @@ -552,7 +552,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; writer.Write(row.Token); @@ -566,7 +566,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; writer.Write(row.Token); @@ -579,7 +579,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns6 = columns[6]; var columns7 = columns[7]; @@ -605,7 +605,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; writer.Write(row.Processor); @@ -618,7 +618,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; writer.Write(row.OSPlatformId); @@ -633,7 +633,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns5 = columns[5]; var columns6 = columns[6]; @@ -660,7 +660,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; for (int i = 0; i < table.Rows; i++) { @@ -676,7 +676,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns3 = columns[3]; for (int i = 0; i < table.Rows; i++) { @@ -694,7 +694,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; @@ -713,7 +713,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; var columns3 = columns[3]; @@ -735,7 +735,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; var columns3 = columns[3]; @@ -755,7 +755,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -772,7 +772,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; var columns3 = columns[3]; @@ -805,7 +805,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -822,7 +822,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -839,7 +839,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -860,7 +860,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -877,7 +877,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -900,7 +900,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns2 = columns[2]; var stringsHeap = metadata.StringsHeap; @@ -918,7 +918,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -936,7 +936,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -953,7 +953,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; @@ -970,7 +970,7 @@ public static void Write(this BinaryWriter writer, Metadata metadata, MDTableWriter /// Metadata /// Table - public static void Write(this BinaryWriter writer, Metadata metadata, MDTable table) { + public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { var columns = table.TableInfo.Columns; var columns0 = columns[0]; var columns1 = columns[1]; diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index c9c636f35..2844c2cd8 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -44,7 +44,7 @@ sealed class ExportDir : IChunk { void IChunk.SetOffset(FileOffset offset, RVA rva) => throw new NotSupportedException(); public uint GetFileLength() => owner.ExportDirSize; public uint GetVirtualSize() => GetFileLength(); - void IChunk.WriteTo(BinaryWriter writer) => throw new NotSupportedException(); + void IChunk.WriteTo(DataWriter writer) => throw new NotSupportedException(); } sealed class VtableFixupsChunk : IChunk { @@ -61,7 +61,7 @@ public void SetOffset(FileOffset offset, RVA rva) { } public uint GetFileLength() => length; public uint GetVirtualSize() => GetFileLength(); - public void WriteTo(BinaryWriter writer) => owner.WriteVtableFixups(writer); + public void WriteTo(DataWriter writer) => owner.WriteVtableFixups(writer); } sealed class StubsChunk : IChunk { @@ -78,7 +78,7 @@ public void SetOffset(FileOffset offset, RVA rva) { } public uint GetFileLength() => length; public uint GetVirtualSize() => GetFileLength(); - public void WriteTo(BinaryWriter writer) => owner.WriteStubs(writer); + public void WriteTo(DataWriter writer) => owner.WriteStubs(writer); } sealed class SdataChunk : IChunk { @@ -95,7 +95,7 @@ public void SetOffset(FileOffset offset, RVA rva) { } public uint GetFileLength() => length; public uint GetVirtualSize() => GetFileLength(); - public void WriteTo(BinaryWriter writer) => owner.WriteSdata(writer); + public void WriteTo(DataWriter writer) => owner.WriteSdata(writer); } public ManagedExportsWriter(string moduleName, Machine machine, RelocDirectory relocDirectory, Metadata metadata, PEHeaders peHeaders, Action logError) { @@ -291,7 +291,7 @@ static byte[] GetNameASCIIZ(string name) { return bytes; } - public void Write(BinaryWriter writer) { + public void Write(DataWriter writer) { foreach (var name in names) writer.Write(name); } @@ -318,14 +318,14 @@ struct SdataBytesInfo { /// PE timestamp void WriteSdataBlob(uint timestamp) { var stream = new MemoryStream(); - var writer = new BinaryWriter(stream); + var writer = new DataWriter(stream); // Write all vtables (referenced from the .text section) - Debug.Assert((writer.BaseStream.Position & 7) == 0); + Debug.Assert((writer.Position & 7) == 0); foreach (var vtbl in vtables) { - vtbl.SdataChunkOffset = (uint)writer.BaseStream.Position; + vtbl.SdataChunkOffset = (uint)writer.Position; foreach (var info in vtbl.Methods) { - info.ManagedVtblOffset = (uint)writer.BaseStream.Position; + info.ManagedVtblOffset = (uint)writer.Position; writer.Write(0x06000000 + metadata.GetRid(info.Method)); if ((vtbl.Flags & VTableFlags.Bit64) != 0) writer.Write(0U); @@ -389,34 +389,34 @@ void WriteSdataBlob(uint timestamp) { } // Write IMAGE_EXPORT_DIRECTORY - Debug.Assert((writer.BaseStream.Position & 3) == 0); - exportDirOffset = (uint)writer.BaseStream.Position; + Debug.Assert((writer.Position & 3) == 0); + exportDirOffset = (uint)writer.Position; writer.Write(0U); // Characteristics writer.Write(timestamp); writer.Write(0U); // MajorVersion, MinorVersion - sdataBytesInfo.exportDirModuleNameStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.exportDirModuleNameStreamOffset = (uint)writer.Position; writer.Write(0U); // Name writer.Write(ordinalBase); // Base writer.Write((uint)funcSize); // NumberOfFunctions writer.Write(sdataBytesInfo.MethodNameOffsets.Length); // NumberOfNames - sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset = (uint)writer.Position; writer.Write(0U); // AddressOfFunctions writer.Write(0U); // AddressOfNames writer.Write(0U); // AddressOfNameOrdinals - sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.Position; WriteZeroes(writer, funcSize * 4); - sdataBytesInfo.addressOfNamesStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.addressOfNamesStreamOffset = (uint)writer.Position; WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 4); - sdataBytesInfo.addressOfNameOrdinalsStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.addressOfNameOrdinalsStreamOffset = (uint)writer.Position; WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 2); - sdataBytesInfo.namesBlobStreamOffset = (uint)writer.BaseStream.Position; + sdataBytesInfo.namesBlobStreamOffset = (uint)writer.Position; namesBlob.Write(writer); sdataBytesInfo.Data = stream.ToArray(); } - void WriteSdata(BinaryWriter writer) { + void WriteSdata(DataWriter writer) { if (sdataBytesInfo.Data == null) return; PatchSdataBytesBlob(); @@ -427,12 +427,12 @@ void PatchSdataBytesBlob() { uint rva = (uint)sdataChunk.RVA; uint namesBaseOffset = rva + sdataBytesInfo.namesBlobStreamOffset; - var writer = new BinaryWriter(new MemoryStream(sdataBytesInfo.Data)); + var writer = new DataWriter(new MemoryStream(sdataBytesInfo.Data)); - writer.BaseStream.Position = sdataBytesInfo.exportDirModuleNameStreamOffset; + writer.Position = sdataBytesInfo.exportDirModuleNameStreamOffset; writer.Write(namesBaseOffset + sdataBytesInfo.moduleNameOffset); - writer.BaseStream.Position = sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset; + writer.Position = sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset; writer.Write(rva + sdataBytesInfo.addressOfFunctionsStreamOffset); // AddressOfFunctions if (sdataBytesInfo.MethodNameOffsets.Length != 0) { writer.Write(rva + sdataBytesInfo.addressOfNamesStreamOffset); // AddressOfNames @@ -440,7 +440,7 @@ void PatchSdataBytesBlob() { } uint funcBaseRva = (uint)stubsChunk.RVA; - writer.BaseStream.Position = sdataBytesInfo.addressOfFunctionsStreamOffset; + writer.Position = sdataBytesInfo.addressOfFunctionsStreamOffset; int currentFuncIndex = 0; foreach (var info in sortedOrdinalMethodInfos) { int zeroes = info.FunctionIndex - currentFuncIndex; @@ -459,17 +459,17 @@ void PatchSdataBytesBlob() { var nameOffsets = sdataBytesInfo.MethodNameOffsets; if (nameOffsets.Length != 0) { - writer.BaseStream.Position = sdataBytesInfo.addressOfNamesStreamOffset; + writer.Position = sdataBytesInfo.addressOfNamesStreamOffset; foreach (var info in sortedNameMethodInfos) writer.Write(namesBaseOffset + nameOffsets[info.NameIndex]); - writer.BaseStream.Position = sdataBytesInfo.addressOfNameOrdinalsStreamOffset; + writer.Position = sdataBytesInfo.addressOfNameOrdinalsStreamOffset; foreach (var info in sortedNameMethodInfos) writer.Write((ushort)info.FunctionIndex); } } - static void WriteZeroes(BinaryWriter writer, int count) { + static void WriteZeroes(DataWriter writer, int count) { while (count >= 8) { writer.Write(0UL); count -= 8; @@ -478,7 +478,7 @@ static void WriteZeroes(BinaryWriter writer, int count) { writer.Write((byte)0); } - void WriteVtableFixups(BinaryWriter writer) { + void WriteVtableFixups(DataWriter writer) { if (vtables.Count == 0) return; @@ -490,7 +490,7 @@ void WriteVtableFixups(BinaryWriter writer) { } } - void WriteStubs(BinaryWriter writer) { + void WriteStubs(DataWriter writer) { if (vtables.Count == 0) return; if (cpuArch == null) @@ -508,10 +508,10 @@ void WriteStubs(BinaryWriter writer) { uint currentOffset = info.StubChunkOffset - stubCodeOffset; if (expectedOffset != currentOffset) throw new InvalidOperationException(); - var pos = writer.BaseStream.Position; + var pos = writer.Position; cpuArch.WriteStub(stubType, writer, imageBase, stubsBaseRva + currentOffset, vtblBaseRva + info.ManagedVtblOffset); - Debug.Assert(pos + stubSize == writer.BaseStream.Position, "The full stub wasn't written"); - if (pos + stubSize != writer.BaseStream.Position) + Debug.Assert(pos + stubSize == writer.Position, "The full stub wasn't written"); + if (pos + stubSize != writer.Position) throw new InvalidOperationException(); if (zeroes != 0) WriteZeroes(writer, zeroes); diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 57fb6619a..dda803b93 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -10,7 +10,7 @@ namespace dnlib.DotNet.Writer { public readonly struct MarshalBlobWriter : IDisposable, IFullNameCreatorHelper { readonly ModuleDef module; readonly MemoryStream outStream; - readonly BinaryWriter writer; + readonly DataWriter writer; readonly IWriterError helper; /// @@ -29,7 +29,7 @@ public static byte[] Write(ModuleDef module, MarshalType marshalType, IWriterErr MarshalBlobWriter(ModuleDef module, IWriterError helper) { this.module = module; outStream = new MemoryStream(); - writer = new BinaryWriter(outStream); + writer = new DataWriter(outStream); this.helper = helper; } @@ -107,7 +107,6 @@ byte[] Write(MarshalType marshalType) { break; } - writer.Flush(); return outStream.ToArray(); } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 476d512f1..03290f6b8 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -249,12 +249,12 @@ public MetadataOptions(MetadataHeaderOptions mdhOptions, MetadataFlags flags) { } } - sealed class BinaryWriterContext { + sealed class DataWriterContext { public readonly MemoryStream OutStream; - public readonly BinaryWriter Writer; - public BinaryWriterContext() { + public readonly DataWriter Writer; + public DataWriterContext() { OutStream = new MemoryStream(); - Writer = new BinaryWriter(OutStream); + Writer = new DataWriter(OutStream); } } @@ -383,7 +383,7 @@ public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenCrea readonly Rows importScopeInfos = new Rows(); readonly SortedRows stateMachineMethodInfos = new SortedRows(); readonly SortedRows customDebugInfos = new SortedRows(); - readonly List binaryWriterContexts = new List(); + readonly List binaryWriterContexts = new List(); readonly List serializerMethodContexts = new List(); readonly List exportedMethods = new List(); @@ -3297,7 +3297,7 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, byte[] pdbId if (!debugMetadata.methodDebugInformationInfosUsed) debugMetadata.tablesHeap.MethodDebugInformationTable.Reset(); pdbHeap.ReferencedTypeSystemTables = systemTablesMask; - var writer = new BinaryWriter(output); + var writer = new DataWriter(output); debugMetadata.SetOffset(0, 0); debugMetadata.GetFileLength(); debugMetadata.VerifyWriteTo(writer); @@ -3491,7 +3491,7 @@ IList GetHeaps() { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { var rva2 = rva; metadataHeader.VerifyWriteTo(writer); rva2 += metadataHeader.GetFileLength(); @@ -3521,15 +3521,15 @@ protected static List Sort(IEnumerable pds) { return sorted; } - BinaryWriterContext AllocBinaryWriterContext() { + DataWriterContext AllocBinaryWriterContext() { if (binaryWriterContexts.Count == 0) - return new BinaryWriterContext(); + return new DataWriterContext(); var res = binaryWriterContexts[binaryWriterContexts.Count - 1]; binaryWriterContexts.RemoveAt(binaryWriterContexts.Count - 1); return res; } - void Free(ref BinaryWriterContext ctx) { + void Free(ref DataWriterContext ctx) { binaryWriterContexts.Add(ctx); ctx = null; } diff --git a/src/DotNet/Writer/MetadataHeader.cs b/src/DotNet/Writer/MetadataHeader.cs index 45d97e4be..1f55bb9e4 100644 --- a/src/DotNet/Writer/MetadataHeader.cs +++ b/src/DotNet/Writer/MetadataHeader.cs @@ -134,7 +134,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { writer.Write(options.Signature ?? MetadataHeaderOptions.DEFAULT_SIGNATURE); writer.Write(options.MajorVersion ?? 1); writer.Write(options.MinorVersion ?? 1); diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 22b639083..096c1b98b 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -134,7 +134,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { writer.Write(code); if (HasExtraSections) { var rva2 = rva + (uint)code.Length; diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index d148e3e2c..e5bcba81b 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -103,12 +103,12 @@ internal void InitializeReusedMethodBodies(IPEImage peImage, uint fileOffsetDelt } } - internal void WriteReusedMethodBodies(BinaryWriter writer, long destStreamBaseOffset) { + internal void WriteReusedMethodBodies(DataWriter writer, long destStreamBaseOffset) { foreach (var info in reusedMethods) { Debug.Assert(info.MethodBody.RVA == info.RVA); if (info.MethodBody.RVA != info.RVA) throw new InvalidOperationException(); - writer.BaseStream.Position = destStreamBaseOffset + (uint)info.MethodBody.FileOffset; + writer.Position = destStreamBaseOffset + (uint)info.MethodBody.FileOffset; info.MethodBody.VerifyWriteTo(writer); } } @@ -152,7 +152,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { var rva2 = rva; foreach (var mb in tinyMethods) { mb.VerifyWriteTo(writer); diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 5a9ee91fb..6b7f98a7d 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -250,9 +250,9 @@ long WriteFile() { InitializeChunkProperties(); OnWriterEvent(ModuleWriterEvent.BeginWriteChunks); - var writer = new BinaryWriter(destStream); + var writer = new DataWriter(destStream); WriteChunks(writer, chunks, 0, peHeaders.FileAlignment); - long imageLength = writer.BaseStream.Position - destStreamBaseOffset; + long imageLength = writer.Position - destStreamBaseOffset; OnWriterEvent(ModuleWriterEvent.EndWriteChunks); OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 105172aa2..fe674a721 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -674,7 +674,7 @@ protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offse /// All chunks /// File offset of first chunk /// File alignment - protected void WriteChunks(BinaryWriter writer, List chunks, FileOffset offset, uint fileAlignment) { + protected void WriteChunks(DataWriter writer, List chunks, FileOffset offset, uint fileAlignment) { foreach (var chunk in chunks) { chunk.VerifyWriteTo(writer); // If it has zero size, it's not present in the file (eg. a section that wasn't needed) @@ -839,11 +839,11 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { entryPointToken = new MDToken(Table.Method, metadata.GetRid(pdbState.UserEntryPoint)).Raw; var pdbId = new byte[20]; - var pdbIdWriter = new BinaryWriter(new MemoryStream(pdbId)); + var pdbIdWriter = new DataWriter(new MemoryStream(pdbId)); var pdbGuid = TheOptions.PdbGuid; pdbIdWriter.Write(pdbGuid.ToByteArray()); pdbIdWriter.Write(GetTimeDateStamp()); - Debug.Assert(pdbIdWriter.BaseStream.Position == pdbId.Length); + Debug.Assert(pdbIdWriter.Position == pdbId.Length); metadata.WritePortablePdb(pdbStream, entryPointToken, pdbId); @@ -873,7 +873,7 @@ static byte[] CreateEmbeddedPortablePdbBlob(MemoryStream portablePdbStream) { var compressedData = Compress(portablePdbStream); var data = new byte[4 + 4 + compressedData.Length]; var stream = new MemoryStream(data); - var writer = new BinaryWriter(stream); + var writer = new DataWriter(stream); writer.Write(0x4244504D);//"MPDB" writer.Write((uint)portablePdbStream.Length); writer.Write(compressedData); @@ -893,7 +893,7 @@ static byte[] Compress(MemoryStream sourceStream) { static byte[] GetCodeViewData(Guid guid, uint age, string filename) { var stream = new MemoryStream(); - var writer = new BinaryWriter(stream); + var writer = new DataWriter(stream); writer.Write(0x53445352); writer.Write(guid.ToByteArray()); writer.Write(age); diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 5a9447382..a2b831dce 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -456,20 +456,20 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.EndCalculateRvasAndFileOffsets); OnWriterEvent(ModuleWriterEvent.BeginWriteChunks); - var writer = new BinaryWriter(destStream); + var writer = new DataWriter(destStream); WriteChunks(writer, chunks, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment); - long imageLength = writer.BaseStream.Position - destStreamBaseOffset; + long imageLength = writer.Position - destStreamBaseOffset; if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { - var pos = writer.BaseStream.Position; + var pos = writer.Position; foreach (var info in reusedChunks) { Debug.Assert(info.Chunk.RVA == info.RVA); if (info.Chunk.RVA != info.RVA) throw new InvalidOperationException(); - writer.BaseStream.Position = destStreamBaseOffset + (uint)info.Chunk.FileOffset; + writer.Position = destStreamBaseOffset + (uint)info.Chunk.FileOffset; info.Chunk.VerifyWriteTo(writer); } methodBodies.WriteReusedMethodBodies(writer, destStreamBaseOffset); - writer.BaseStream.Position = pos; + writer.Position = pos; } var sectionSizes = new SectionSizes(peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment, headerLen, GetSectionSizeInfos); UpdateHeaderFields(writer, entryPointIsManagedOrNoEntryPoint, entryPointToken, ref sectionSizes); @@ -484,7 +484,7 @@ long WriteFile() { if (Options.AddCheckSum) { destStream.Position = destStreamBaseOffset; uint newCheckSum = destStream.CalculatePECheckSum(imageLength, checkSumOffset); - writer.BaseStream.Position = checkSumOffset; + writer.Position = checkSumOffset; writer.Write(newCheckSum); } OnWriterEvent(ModuleWriterEvent.EndWritePEChecksum); @@ -534,7 +534,7 @@ Characteristics GetCharacteristics() { /// Updates the PE header and COR20 header fields that need updating. All sections are /// also updated, and the new ones are added. /// - void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPoint, uint entryPointToken, ref SectionSizes sectionSizes) { + void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoint, uint entryPointToken, ref SectionSizes sectionSizes) { long fileHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.FileHeader.StartOffset; long optionalHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.StartOffset; long sectionsOffset = destStreamBaseOffset + (long)peImage.ImageSectionHeaders[0].StartOffset; @@ -543,30 +543,30 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo // Update PE file header var peOptions = Options.PEHeadersOptions; - writer.BaseStream.Position = fileHeaderOffset; + writer.Position = fileHeaderOffset; writer.Write((ushort)(peOptions.Machine ?? module.Machine)); writer.Write((ushort)(origSections.Count + sections.Count)); WriteUInt32(writer, peOptions.TimeDateStamp); WriteUInt32(writer, peOptions.PointerToSymbolTable); WriteUInt32(writer, peOptions.NumberOfSymbols); - writer.BaseStream.Position += 2; // sizeof(SizeOfOptionalHeader) + writer.Position += 2; // sizeof(SizeOfOptionalHeader) writer.Write((ushort)(peOptions.Characteristics ?? GetCharacteristics())); // Update optional header - writer.BaseStream.Position = optionalHeaderOffset; + writer.Position = optionalHeaderOffset; bool is32BitOptionalHeader = peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader32; if (is32BitOptionalHeader) { - writer.BaseStream.Position += 2; + writer.Position += 2; WriteByte(writer, peOptions.MajorLinkerVersion); WriteByte(writer, peOptions.MinorLinkerVersion); writer.Write(sectionSizes.SizeOfCode); writer.Write(sectionSizes.SizeOfInitdData); writer.Write(sectionSizes.SizeOfUninitdData); - writer.BaseStream.Position += 4; // EntryPoint + writer.Position += 4; // EntryPoint writer.Write(sectionSizes.BaseOfCode); writer.Write(sectionSizes.BaseOfData); WriteUInt32(writer, peOptions.ImageBase); - writer.BaseStream.Position += 8; // SectionAlignment, FileAlignment + writer.Position += 8; // SectionAlignment, FileAlignment WriteUInt16(writer, peOptions.MajorOperatingSystemVersion); WriteUInt16(writer, peOptions.MinorOperatingSystemVersion); WriteUInt16(writer, peOptions.MajorImageVersion); @@ -576,7 +576,7 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo WriteUInt32(writer, peOptions.Win32VersionValue); writer.Write(sectionSizes.SizeOfImage); writer.Write(sectionSizes.SizeOfHeaders); - checkSumOffset = writer.BaseStream.Position; + checkSumOffset = writer.Position; writer.Write(0); // CheckSum WriteUInt16(writer, peOptions.Subsystem); WriteUInt16(writer, peOptions.DllCharacteristics); @@ -588,16 +588,16 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo WriteUInt32(writer, peOptions.NumberOfRvaAndSizes); } else { - writer.BaseStream.Position += 2; + writer.Position += 2; WriteByte(writer, peOptions.MajorLinkerVersion); WriteByte(writer, peOptions.MinorLinkerVersion); writer.Write(sectionSizes.SizeOfCode); writer.Write(sectionSizes.SizeOfInitdData); writer.Write(sectionSizes.SizeOfUninitdData); - writer.BaseStream.Position += 4; // EntryPoint + writer.Position += 4; // EntryPoint writer.Write(sectionSizes.BaseOfCode); WriteUInt64(writer, peOptions.ImageBase); - writer.BaseStream.Position += 8; // SectionAlignment, FileAlignment + writer.Position += 8; // SectionAlignment, FileAlignment WriteUInt16(writer, peOptions.MajorOperatingSystemVersion); WriteUInt16(writer, peOptions.MinorOperatingSystemVersion); WriteUInt16(writer, peOptions.MajorImageVersion); @@ -607,7 +607,7 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo WriteUInt32(writer, peOptions.Win32VersionValue); writer.Write(sectionSizes.SizeOfImage); writer.Write(sectionSizes.SizeOfHeaders); - checkSumOffset = writer.BaseStream.Position; + checkSumOffset = writer.Position; writer.Write(0); // CheckSum WriteUInt16(writer, peOptions.Subsystem ?? GetSubsystem()); WriteUInt16(writer, peOptions.DllCharacteristics ?? module.DllCharacteristics); @@ -621,34 +621,34 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo // Update Win32 resources data directory, if we wrote a new one if (win32Resources != null) { - writer.BaseStream.Position = dataDirOffset + 2 * 8; + writer.Position = dataDirOffset + 2 * 8; writer.WriteDataDirectory(win32Resources); } // Clear the security descriptor directory - writer.BaseStream.Position = dataDirOffset + 4 * 8; + writer.Position = dataDirOffset + 4 * 8; writer.WriteDataDirectory(null); // Write a new debug directory - writer.BaseStream.Position = dataDirOffset + 6 * 8; + writer.Position = dataDirOffset + 6 * 8; writer.WriteDebugDirectory(debugDirectory); // Write a new Metadata data directory - writer.BaseStream.Position = dataDirOffset + 14 * 8; + writer.Position = dataDirOffset + 14 * 8; writer.WriteDataDirectory(imageCor20Header); // Update old sections, and add new sections - writer.BaseStream.Position = sectionsOffset; + writer.Position = sectionsOffset; foreach (var section in origSections) { - writer.BaseStream.Position += 0x14; + writer.Position += 0x14; writer.Write((uint)section.Chunk.FileOffset); // PointerToRawData - writer.BaseStream.Position += 0x10; + writer.Position += 0x10; } foreach (var section in sections) section.WriteHeaderTo(writer, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment, (uint)section.RVA); // Write the .NET header - writer.BaseStream.Position = cor20Offset; + writer.Position = cor20Offset; writer.Write(0x48); // cb WriteUInt16(writer, Options.Cor20HeaderOptions.MajorRuntimeVersion); WriteUInt16(writer, Options.Cor20HeaderOptions.MinorRuntimeVersion); @@ -665,56 +665,56 @@ void UpdateHeaderFields(BinaryWriter writer, bool entryPointIsManagedOrNoEntryPo UpdateVTableFixups(writer); } - static void WriteDataDirectory(BinaryWriter writer, ImageDataDirectory dataDir) { + static void WriteDataDirectory(DataWriter writer, ImageDataDirectory dataDir) { writer.Write((uint)dataDir.VirtualAddress); writer.Write(dataDir.Size); } - static void WriteByte(BinaryWriter writer, byte? value) { + static void WriteByte(DataWriter writer, byte? value) { if (value == null) - writer.BaseStream.Position++; + writer.Position++; else writer.Write(value.Value); } - static void WriteUInt16(BinaryWriter writer, ushort? value) { + static void WriteUInt16(DataWriter writer, ushort? value) { if (value == null) - writer.BaseStream.Position += 2; + writer.Position += 2; else writer.Write(value.Value); } - static void WriteUInt16(BinaryWriter writer, Subsystem? value) { + static void WriteUInt16(DataWriter writer, Subsystem? value) { if (value == null) - writer.BaseStream.Position += 2; + writer.Position += 2; else writer.Write((ushort)value.Value); } - static void WriteUInt16(BinaryWriter writer, DllCharacteristics? value) { + static void WriteUInt16(DataWriter writer, DllCharacteristics? value) { if (value == null) - writer.BaseStream.Position += 2; + writer.Position += 2; else writer.Write((ushort)value.Value); } - static void WriteUInt32(BinaryWriter writer, uint? value) { + static void WriteUInt32(DataWriter writer, uint? value) { if (value == null) - writer.BaseStream.Position += 4; + writer.Position += 4; else writer.Write(value.Value); } - static void WriteUInt32(BinaryWriter writer, ulong? value) { + static void WriteUInt32(DataWriter writer, ulong? value) { if (value == null) - writer.BaseStream.Position += 4; + writer.Position += 4; else writer.Write((uint)value.Value); } - static void WriteUInt64(BinaryWriter writer, ulong? value) { + static void WriteUInt64(DataWriter writer, ulong? value) { if (value == null) - writer.BaseStream.Position += 8; + writer.Position += 8; else writer.Write(value.Value); } @@ -756,13 +756,13 @@ IEnumerable GetSectionSizeInfos() { yield return new SectionSizeInfo(section.GetVirtualSize(), section.Characteristics); } - void UpdateVTableFixups(BinaryWriter writer) { + void UpdateVTableFixups(DataWriter writer) { var vtableFixups = module.VTableFixups; if (vtableFixups == null || vtableFixups.VTables.Count == 0) return; - writer.BaseStream.Position = ToWriterOffset(vtableFixups.RVA); - if (writer.BaseStream.Position == 0) { + writer.Position = ToWriterOffset(vtableFixups.RVA); + if (writer.Position == 0) { Error("Could not convert RVA to file offset"); return; } @@ -773,9 +773,9 @@ void UpdateVTableFixups(BinaryWriter writer) { writer.Write((ushort)vtable.Methods.Count); writer.Write((ushort)vtable.Flags); - long pos = writer.BaseStream.Position; - writer.BaseStream.Position = ToWriterOffset(vtable.RVA); - if (writer.BaseStream.Position == 0) { + long pos = writer.Position; + writer.Position = ToWriterOffset(vtable.RVA); + if (writer.Position == 0) { if (vtable.RVA != 0 || vtable.Methods.Count > 0) Error("Could not convert RVA to file offset"); } @@ -786,7 +786,7 @@ void UpdateVTableFixups(BinaryWriter writer) { writer.Write(0); } } - writer.BaseStream.Position = pos; + writer.Position = pos; } } diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index 4b5102344..e7a17b187 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -76,7 +76,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { var rva2 = rva; foreach (var resourceData in resources) { int padding = (int)rva2.AlignUp(alignment) - (int)rva2; diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index de9281681..acd615e9e 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -335,8 +335,8 @@ IEnumerable GetSectionSizeInfos() { } /// - public void WriteTo(BinaryWriter writer) { - startOffset = writer.BaseStream.Position; + public void WriteTo(DataWriter writer) { + startOffset = writer.Position; // DOS header writer.Write(dosHeader); @@ -380,7 +380,7 @@ public void WriteTo(BinaryWriter writer) { writer.Write(options.Win32VersionValue ?? 0); writer.Write(sectionSizes.SizeOfImage); writer.Write(sectionSizes.SizeOfHeaders); - checkSumOffset = writer.BaseStream.Position; + checkSumOffset = writer.Position; writer.Write(0); // CheckSum writer.Write((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM)); writer.Write((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics)); @@ -412,7 +412,7 @@ public void WriteTo(BinaryWriter writer) { writer.Write(options.Win32VersionValue ?? 0); writer.Write(sectionSizes.SizeOfImage); writer.Write(sectionSizes.SizeOfHeaders); - checkSumOffset = writer.BaseStream.Position; + checkSumOffset = writer.Position; writer.Write(0); // CheckSum writer.Write((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM)); writer.Write((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics)); @@ -451,7 +451,7 @@ public void WriteTo(BinaryWriter writer) { emptySections++; } if (emptySections != 0) - writer.BaseStream.Position += emptySections * 0x28; + writer.Position += emptySections * 0x28; } /// @@ -459,10 +459,10 @@ public void WriteTo(BinaryWriter writer) { /// /// Writer /// Length of PE file - public void WriteCheckSum(BinaryWriter writer, long length) { - writer.BaseStream.Position = startOffset; - uint checkSum = writer.BaseStream.CalculatePECheckSum(length, checkSumOffset); - writer.BaseStream.Position = checkSumOffset; + public void WriteCheckSum(DataWriter writer, long length) { + writer.Position = startOffset; + uint checkSum = writer.InternalStream.CalculatePECheckSum(length, checkSumOffset); + writer.Position = checkSumOffset; writer.Write(checkSum); } diff --git a/src/DotNet/Writer/PESection.cs b/src/DotNet/Writer/PESection.cs index ecb085dcc..ad784d644 100644 --- a/src/DotNet/Writer/PESection.cs +++ b/src/DotNet/Writer/PESection.cs @@ -61,7 +61,7 @@ public PESection(string name, uint characteristics) { /// File alignment /// Section alignment /// Current - public uint WriteHeaderTo(BinaryWriter writer, uint fileAlignment, uint sectionAlignment, uint rva) { + public uint WriteHeaderTo(DataWriter writer, uint fileAlignment, uint sectionAlignment, uint rva) { uint vs = GetVirtualSize(); uint fileLen = GetFileLength(); uint alignedVs = Utils.AlignUp(vs, sectionAlignment); diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs index 454905e44..fe92efbbd 100644 --- a/src/DotNet/Writer/PdbHeap.cs +++ b/src/DotNet/Writer/PdbHeap.cs @@ -76,7 +76,7 @@ public override uint GetRawLength() { } /// - protected override void WriteToImpl(BinaryWriter writer) { + protected override void WriteToImpl(DataWriter writer) { if (!referencedTypeSystemTablesInitd) throw new InvalidOperationException("ReferencedTypeSystemTables hasn't been initialized yet"); writer.Write(pdbId); diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index e71d02d43..c45c9f933 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -83,7 +83,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; // 3 = IMAGE_REL_BASED_HIGHLOW, A = IMAGE_REL_BASED_DIR64 uint relocType = is64bit ? 0xA000U : 0x3000; diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index c4e448e7e..684cee051 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -22,7 +22,7 @@ public struct SignatureWriter : IDisposable { readonly ISignatureWriterHelper helper; RecursionCounter recursionCounter; readonly MemoryStream outStream; - readonly BinaryWriter writer; + readonly DataWriter writer; readonly bool disposeStream; /// @@ -38,7 +38,7 @@ public static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig) { } } - internal static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig, BinaryWriterContext context) { + internal static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig, DataWriterContext context) { using (var writer = new SignatureWriter(helper, context)) { writer.Write(typeSig); return writer.GetResult(); @@ -58,7 +58,7 @@ public static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig s } } - internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig sig, BinaryWriterContext context) { + internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig sig, DataWriterContext context) { using (var writer = new SignatureWriter(helper, context)) { writer.Write(sig); return writer.GetResult(); @@ -69,11 +69,11 @@ internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig this.helper = helper; recursionCounter = new RecursionCounter(); outStream = new MemoryStream(); - writer = new BinaryWriter(outStream); + writer = new DataWriter(outStream); disposeStream = true; } - SignatureWriter(ISignatureWriterHelper helper, BinaryWriterContext context) { + SignatureWriter(ISignatureWriterHelper helper, DataWriterContext context) { this.helper = helper; recursionCounter = new RecursionCounter(); outStream = context.OutStream; @@ -344,8 +344,6 @@ public void Dispose() { return; if (outStream != null) outStream.Dispose(); - if (writer != null) - ((IDisposable)writer).Dispose(); } } } diff --git a/src/DotNet/Writer/StartupStub.cs b/src/DotNet/Writer/StartupStub.cs index a69742500..74aef7bb5 100644 --- a/src/DotNet/Writer/StartupStub.cs +++ b/src/DotNet/Writer/StartupStub.cs @@ -84,7 +84,7 @@ public uint GetFileLength() { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { if (!Enable) return; if (cpuArch == null) diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index 637915f75..eaacd860a 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -198,7 +198,7 @@ uint AddToCache(UTF8String s) { public override uint GetRawLength() => nextOffset; /// - protected override void WriteToImpl(BinaryWriter writer) { + protected override void WriteToImpl(DataWriter writer) { if (originalData != null) writer.Write(originalData); else diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index e484b761e..a6417e549 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -40,6 +40,6 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) => writer.WriteZeros(size); + public void WriteTo(DataWriter writer) => writer.WriteZeros(size); } } diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 31700a107..c57866aaf 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -385,7 +385,7 @@ internal void GetSystemTableRows(out ulong mask, uint[] tables) { uint[] systemTables; /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { writer.Write(options.Reserved1 ?? 0); writer.Write(majorVersion); writer.Write(minorVersion); diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index 723956446..d670f654d 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -102,7 +102,7 @@ uint AddToCache(string s) { public override uint GetRawLength() => nextOffset; /// - protected override void WriteToImpl(BinaryWriter writer) { + protected override void WriteToImpl(DataWriter writer) { if (originalData != null) writer.Write(originalData); else @@ -122,7 +122,7 @@ protected override void WriteToImpl(BinaryWriter writer) { } } - void WriteString(BinaryWriter writer, string s) { + void WriteString(DataWriter writer, string s) { writer.WriteCompressedUInt32((uint)s.Length * 2 + 1); byte last = 0; for (int i = 0; i < s.Length; i++) { @@ -135,7 +135,7 @@ void WriteString(BinaryWriter writer, string s) { } /// - public int GetRawDataSize(string data) => Utils.GetCompressedUInt32Length((uint)data.Length * 2 + 1) + data.Length * 2 + 1; + public int GetRawDataSize(string data) => DataWriter.GetCompressedUInt32Length((uint)data.Length * 2 + 1) + data.Length * 2 + 1; /// public void SetRawData(uint offset, byte[] rawData) { @@ -147,7 +147,7 @@ public void SetRawData(uint offset, byte[] rawData) { /// public IEnumerable> GetAllRawData() { var memStream = new MemoryStream(); - var writer = new BinaryWriter(memStream); + var writer = new DataWriter(memStream); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { memStream.Position = 0; diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index d24515f09..f0b48c20f 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -350,7 +350,7 @@ void FindDirectoryEntries(ResourceDirectory dir) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(BinaryWriter writer) { + public void WriteTo(DataWriter writer) { uint offset = 0; // The order here must be the same as in SetOffset() @@ -402,7 +402,7 @@ public void WriteTo(BinaryWriter writer) { } } - uint WriteTo(BinaryWriter writer, ResourceDirectory dir) { + uint WriteTo(DataWriter writer, ResourceDirectory dir) { writer.Write(dir.Characteristics); writer.Write(dir.TimeDateStamp); writer.Write(dir.MajorVersion); @@ -454,7 +454,7 @@ static void GetNamedAndIds(ResourceDirectory dir, out List 0x1FFFFFFF) { helper.Error("UInt32 value is too big and can't be compressed"); value = 0x1FFFFFFF; @@ -13,7 +11,7 @@ public static uint WriteCompressedUInt32(this BinaryWriter writer, IWriterError return value; } - public static int WriteCompressedInt32(this BinaryWriter writer, IWriterError helper, int value) { + public static int WriteCompressedInt32(this DataWriter writer, IWriterError helper, int value) { if (value < -0x10000000) { helper.Error("Int32 value is too small and can't be compressed."); value = -0x10000000; @@ -26,7 +24,7 @@ public static int WriteCompressedInt32(this BinaryWriter writer, IWriterError he return value; } - public static void Write(this BinaryWriter writer, IWriterError helper, UTF8String s) { + public static void Write(this DataWriter writer, IWriterError helper, UTF8String s) { if (UTF8String.IsNull(s)) { helper.Error("UTF8String is null"); s = UTF8String.Empty; diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 750984ca1..5fbe9b969 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -5,6 +5,7 @@ using System.IO; using System.Runtime.Serialization; using System.Text; +using dnlib.DotNet.Writer; namespace dnlib.IO { /// @@ -779,6 +780,29 @@ public string ReadString(int byteCount, Encoding encoding) { byte[] AllocTempBuffer() => new byte[(int)Math.Min(0x2000, BytesLeft)]; + /// + /// Copies the data, starting from , to + /// + /// Destination + /// Number of bytes written + public void CopyTo(DataWriter destination) { + if (destination == null) + ThrowArgumentNullException(nameof(destination)); + CopyTo(destination.InternalStream, AllocTempBuffer()); + } + + /// + /// Copies the data, starting from , to + /// + /// Destination + /// Temp buffer during writing + /// Number of bytes written + public void CopyTo(DataWriter destination, byte[] dataBuffer) { + if (destination == null) + ThrowArgumentNullException(nameof(destination)); + CopyTo(destination.InternalStream, dataBuffer); + } + /// /// Copies the data, starting from , to /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 67638d85d..618864cb6 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -309,6 +309,7 @@ + From 74131c54cc192e2b1b37ecaa15a019a40b35d321 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:36:34 +0100 Subject: [PATCH 150/511] Rename methods --- src/DotNet/CpuArch.cs | 30 ++-- src/DotNet/MD/ColumnInfo.cs | 10 +- .../Portable/LocalConstantSigBlobWriter.cs | 74 +++++----- .../PortablePdbCustomDebugInfoWriter.cs | 28 ++-- src/DotNet/Writer/BlobHeap.cs | 10 +- src/DotNet/Writer/ByteArrayChunk.cs | 2 +- src/DotNet/Writer/CustomAttributeWriter.cs | 126 ++++++++-------- src/DotNet/Writer/DataWriter.cs | 26 ++-- src/DotNet/Writer/DebugDirectory.cs | 16 +- src/DotNet/Writer/DeclSecurityWriter.cs | 4 +- src/DotNet/Writer/Extensions.cs | 4 +- src/DotNet/Writer/GuidHeap.cs | 2 +- src/DotNet/Writer/IChunk.cs | 12 +- src/DotNet/Writer/ImageCor20Header.cs | 10 +- src/DotNet/Writer/ImportAddressTable.cs | 8 +- src/DotNet/Writer/ImportDirectory.cs | 32 ++-- src/DotNet/Writer/MDTableWriter.cs | 108 +++++++------- src/DotNet/Writer/ManagedExportsWriter.cs | 56 +++---- src/DotNet/Writer/MarshalBlobWriter.cs | 4 +- src/DotNet/Writer/Metadata.cs | 4 +- src/DotNet/Writer/MetadataHeader.cs | 24 +-- src/DotNet/Writer/MethodBody.cs | 4 +- src/DotNet/Writer/ModuleWriterBase.cs | 20 +-- src/DotNet/Writer/NativeModuleWriter.cs | 74 +++++----- src/DotNet/Writer/NetResources.cs | 2 +- src/DotNet/Writer/PEHeaders.cs | 138 +++++++++--------- src/DotNet/Writer/PESection.cs | 20 +-- src/DotNet/Writer/PdbHeap.cs | 8 +- src/DotNet/Writer/RelocDirectory.cs | 8 +- src/DotNet/Writer/SignatureWriter.cs | 38 ++--- src/DotNet/Writer/StringsHeap.cs | 10 +- src/DotNet/Writer/TablesHeap.cs | 18 +-- src/DotNet/Writer/USHeap.cs | 10 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 32 ++-- src/DotNet/Writer/WriterUtils.cs | 2 +- 35 files changed, 487 insertions(+), 487 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 4e3e9702b..1693904b1 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -142,9 +142,9 @@ public override void WriteStub(StubType stubType, DataWriter writer, ulong image switch (stubType) { case StubType.Export: case StubType.EntryPoint: - writer.Write((ushort)0);// padding - writer.Write((ushort)0x25FF); - writer.Write((uint)imageBase + managedFuncRva); + writer.WriteUInt16((ushort)0);// padding + writer.WriteUInt16((ushort)0x25FF); + writer.WriteUInt32((uint)imageBase + managedFuncRva); break; default: throw new ArgumentOutOfRangeException(); @@ -215,10 +215,10 @@ public override void WriteStub(StubType stubType, DataWriter writer, ulong image switch (stubType) { case StubType.Export: case StubType.EntryPoint: - writer.Write((ushort)0);// padding - writer.Write((ushort)0xA148); - writer.Write(imageBase + managedFuncRva); - writer.Write((ushort)0xE0FF); + writer.WriteUInt16((ushort)0);// padding + writer.WriteUInt16((ushort)0xA148); + writer.WriteUInt64(imageBase + managedFuncRva); + writer.WriteUInt16((ushort)0xE0FF); break; default: throw new ArgumentOutOfRangeException(); @@ -310,12 +310,12 @@ public override void WriteStub(StubType stubType, DataWriter writer, ulong image switch (stubType) { case StubType.Export: case StubType.EntryPoint: - writer.Write(0x40A010180200480BUL); - writer.Write(0x0004000000283024UL); - writer.Write(0x5060101812000810UL); - writer.Write(0x0080006000038004UL); - writer.Write(imageBase + stubRva); - writer.Write(imageBase + managedFuncRva); + writer.WriteUInt64(0x40A010180200480BUL); + writer.WriteUInt64(0x0004000000283024UL); + writer.WriteUInt64(0x5060101812000810UL); + writer.WriteUInt64(0x0080006000038004UL); + writer.WriteUInt64(imageBase + stubRva); + writer.WriteUInt64(imageBase + managedFuncRva); break; default: throw new ArgumentOutOfRangeException(); @@ -380,8 +380,8 @@ public override void WriteStub(StubType stubType, DataWriter writer, ulong image switch (stubType) { case StubType.Export: case StubType.EntryPoint: - writer.Write(0xF000F8DF); - writer.Write((uint)imageBase + managedFuncRva); + writer.WriteUInt32(0xF000F8DF); + writer.WriteUInt32((uint)imageBase + managedFuncRva); break; default: throw new ArgumentOutOfRangeException(); diff --git a/src/DotNet/MD/ColumnInfo.cs b/src/DotNet/MD/ColumnInfo.cs index 1cab63dfc..91664cf73 100644 --- a/src/DotNet/MD/ColumnInfo.cs +++ b/src/DotNet/MD/ColumnInfo.cs @@ -103,9 +103,9 @@ internal uint Unsafe_Read24(ref DataReader reader) { /// The column value public void Write(DataWriter writer, uint value) { switch (size) { - case 1: writer.Write((byte)value); break; - case 2: writer.Write((ushort)value); break; - case 4: writer.Write(value); break; + case 1: writer.WriteByte((byte)value); break; + case 2: writer.WriteUInt16((ushort)value); break; + case 4: writer.WriteUInt32(value); break; default: throw new InvalidOperationException("Invalid column size"); } } @@ -113,9 +113,9 @@ public void Write(DataWriter writer, uint value) { internal void Write24(DataWriter writer, uint value) { Debug.Assert(size == 2 || size == 4); if (size == 2) - writer.Write((ushort)value); + writer.WriteUInt16((ushort)value); else - writer.Write(value); + writer.WriteUInt32(value); } } } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index 8c3366e4b..4698410e9 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -26,7 +26,7 @@ void Write(DataWriter writer, TypeSig type, object value) { return; var et = type.ElementType; - writer.Write((byte)et); + writer.WriteByte((byte)et); switch (et) { case ElementType.Boolean: case ElementType.Char: @@ -43,27 +43,27 @@ void Write(DataWriter writer, TypeSig type, object value) { case ElementType.R4: if (value is float) - writer.Write((float)value); + writer.WriteSingle((float)value); else { helper.Error("Expected a Single constant"); - writer.Write((float)0); + writer.WriteSingle((float)0); } return; case ElementType.R8: if (value is double) - writer.Write((double)value); + writer.WriteDouble((double)value); else { helper.Error("Expected a Double constant"); - writer.Write((double)0); + writer.WriteDouble((double)0); } return; case ElementType.String: if (value == null) - writer.Write((byte)0xFF); + writer.WriteByte((byte)0xFF); else if (value is string) - writer.Write(Encoding.Unicode.GetBytes((string)value)); + writer.WriteBytes(Encoding.Unicode.GetBytes((string)value)); else helper.Error("Expected a String constant"); return; @@ -95,7 +95,7 @@ void Write(DataWriter writer, TypeSig type, object value) { case ElementType.I8: case ElementType.U8: writer.Position--; - writer.Write((byte)underlyingType.GetElementType()); + writer.WriteByte((byte)underlyingType.GetElementType()); WritePrimitiveValue(writer, underlyingType.GetElementType(), value); WriteTypeDefOrRef(writer, tdr); return; @@ -111,30 +111,30 @@ void Write(DataWriter writer, TypeSig type, object value) { if (name == stringDecimal) { if (value is decimal) { var bits = decimal.GetBits((decimal)value); - writer.Write((byte)((((uint)bits[3] >> 31) << 7) | (((uint)bits[3] >> 16) & 0x7F))); - writer.Write(bits[0]); - writer.Write(bits[1]); - writer.Write(bits[2]); + writer.WriteByte((byte)((((uint)bits[3] >> 31) << 7) | (((uint)bits[3] >> 16) & 0x7F))); + writer.WriteInt32(bits[0]); + writer.WriteInt32(bits[1]); + writer.WriteInt32(bits[2]); } else { helper.Error("Expected a Decimal constant"); - writer.Write(new byte[13]); + writer.WriteBytes(new byte[13]); } valueWritten = true; } else if (name == stringDateTime) { if (value is DateTime) - writer.Write(((DateTime)value).Ticks); + writer.WriteInt64(((DateTime)value).Ticks); else { helper.Error("Expected a DateTime constant"); - writer.Write(0L); + writer.WriteInt64(0); } valueWritten = true; } } if (!valueWritten) { if (value is byte[]) - writer.Write((byte[])value); + writer.WriteBytes((byte[])value); else if (value != null) { helper.Error("Unsupported constant: " + value.GetType().FullName); return; @@ -146,7 +146,7 @@ void Write(DataWriter writer, TypeSig type, object value) { case ElementType.Class: WriteTypeDefOrRef(writer, ((ClassSig)type).TypeDefOrRef); if (value is byte[]) - writer.Write((byte[])value); + writer.WriteBytes((byte[])value); else if (value != null) helper.Error("Expected a null constant"); return; @@ -208,91 +208,91 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { switch (et) { case ElementType.Boolean: if (value is bool) - writer.Write((bool)value); + writer.WriteBoolean((bool)value); else { helper.Error("Expected a Boolean constant"); - writer.Write(false); + writer.WriteBoolean(false); } break; case ElementType.Char: if (value is char) - writer.Write((ushort)(char)value); + writer.WriteUInt16((ushort)(char)value); else { helper.Error("Expected a Char constant"); - writer.Write((ushort)0); + writer.WriteUInt16((ushort)0); } break; case ElementType.I1: if (value is sbyte) - writer.Write((sbyte)value); + writer.WriteSByte((sbyte)value); else { helper.Error("Expected a SByte constant"); - writer.Write((sbyte)0); + writer.WriteSByte((sbyte)0); } break; case ElementType.U1: if (value is byte) - writer.Write((byte)value); + writer.WriteByte((byte)value); else { helper.Error("Expected a Byte constant"); - writer.Write((byte)0); + writer.WriteByte((byte)0); } break; case ElementType.I2: if (value is short) - writer.Write((short)value); + writer.WriteInt16((short)value); else { helper.Error("Expected an Int16 constant"); - writer.Write((short)0); + writer.WriteInt16((short)0); } break; case ElementType.U2: if (value is ushort) - writer.Write((ushort)value); + writer.WriteUInt16((ushort)value); else { helper.Error("Expected a UInt16 constant"); - writer.Write((ushort)0); + writer.WriteUInt16((ushort)0); } break; case ElementType.I4: if (value is int) - writer.Write((int)value); + writer.WriteInt32((int)value); else { helper.Error("Expected an Int32 constant"); - writer.Write((int)0); + writer.WriteInt32((int)0); } break; case ElementType.U4: if (value is uint) - writer.Write((uint)value); + writer.WriteUInt32((uint)value); else { helper.Error("Expected a UInt32 constant"); - writer.Write((uint)0); + writer.WriteUInt32((uint)0); } break; case ElementType.I8: if (value is long) - writer.Write((long)value); + writer.WriteInt64((long)value); else { helper.Error("Expected an Int64 constant"); - writer.Write((long)0); + writer.WriteInt64((long)0); } break; case ElementType.U8: if (value is ulong) - writer.Write((ulong)value); + writer.WriteUInt64((ulong)value); else { helper.Error("Expected a UInt64 constant"); - writer.Write((ulong)0); + writer.WriteUInt64((ulong)0); } break; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 3b0624d6b..6371b4454 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -89,8 +89,8 @@ byte[] Write(PdbCustomDebugInfo cdi) { void WriteUTF8Z(string s) { var bytes = Encoding.UTF8.GetBytes(s); - writer.Write(bytes); - writer.Write((byte)0); + writer.WriteBytes(bytes); + writer.WriteByte((byte)0); } void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi) { @@ -117,8 +117,8 @@ void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustom helper.Error("End instruction is before start instruction"); return; } - writer.Write(startOffset); - writer.Write(endOffset - startOffset); + writer.WriteUInt32(startOffset); + writer.WriteUInt32(endOffset - startOffset); } } @@ -128,7 +128,7 @@ void WriteEditAndContinueLocalSlotMap(PdbEditAndContinueLocalSlotMapCustomDebugI helper.Error("Data blob is null"); return; } - writer.Write(d); + writer.WriteBytes(d); } void WriteEditAndContinueLambdaMap(PdbEditAndContinueLambdaMapCustomDebugInfo cdi) { @@ -137,7 +137,7 @@ void WriteEditAndContinueLambdaMap(PdbEditAndContinueLambdaMapCustomDebugInfo cd helper.Error("Data blob is null"); return; } - writer.Write(d); + writer.WriteBytes(d); } void WriteUnknown(PdbUnknownCustomDebugInfo cdi) { @@ -146,7 +146,7 @@ void WriteUnknown(PdbUnknownCustomDebugInfo cdi) { helper.Error("Data blob is null"); return; } - writer.Write(d); + writer.WriteBytes(d); } void WriteTupleElementNames(PortablePdbTupleElementNamesCustomDebugInfo cdi) { @@ -166,13 +166,13 @@ void WriteDefaultNamespace(PdbDefaultNamespaceCustomDebugInfo cdi) { return; } var bytes = Encoding.UTF8.GetBytes(ns); - writer.Write(bytes); + writer.WriteBytes(bytes); } void WriteDynamicLocalVariables(PdbDynamicLocalVariablesCustomDebugInfo cdi) { var flags = cdi.Flags; for (int i = 0; i < flags.Length; i += 8) - writer.Write(ToByte(flags, i)); + writer.WriteByte(ToByte(flags, i)); } static byte ToByte(bool[] flags, int index) { @@ -191,7 +191,7 @@ void WriteEmbeddedSource(PdbEmbeddedSourceCustomDebugInfo cdi) { helper.Error("Source code blob is null"); return; } - writer.Write(d); + writer.WriteBytes(d); } void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { @@ -200,7 +200,7 @@ void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { helper.Error("Source link blob is null"); return; } - writer.Write(d); + writer.WriteBytes(d); } void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { @@ -214,7 +214,7 @@ void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { catchHandlerOffset = 0; else catchHandlerOffset = methodContext.GetOffset(cdi.CatchHandlerInstruction) + 1; - writer.Write(catchHandlerOffset); + writer.WriteUInt32(catchHandlerOffset); foreach (var info in cdi.StepInfos) { if (info.YieldInstruction == null) { @@ -236,8 +236,8 @@ void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { else resumeOffset = GetOffsetSlow(info.BreakpointMethod, info.BreakpointInstruction); uint resumeMethodRid = systemMetadata.GetRid(info.BreakpointMethod); - writer.Write(yieldOffset); - writer.Write(resumeOffset); + writer.WriteUInt32(yieldOffset); + writer.WriteUInt32(resumeOffset); writer.WriteCompressedUInt32(resumeMethodRid); } } diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index 545578e80..d20705ebf 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -100,9 +100,9 @@ uint AddToCache(byte[] data) { /// protected override void WriteToImpl(DataWriter writer) { if (originalData != null) - writer.Write(originalData); + writer.WriteBytes(originalData); else - writer.Write((byte)0); + writer.WriteByte((byte)0); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var data in cached) { @@ -110,11 +110,11 @@ protected override void WriteToImpl(DataWriter writer) { if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); - writer.Write(rawData); + writer.WriteBytes(rawData); } else { writer.WriteCompressedUInt32((uint)data.Length); - writer.Write(data); + writer.WriteBytes(data); } offset += (uint)rawLen; } @@ -139,7 +139,7 @@ public IEnumerable> GetAllRawData() { memStream.Position = 0; memStream.SetLength(0); writer.WriteCompressedUInt32((uint)data.Length); - writer.Write(data); + writer.WriteBytes(data); yield return new KeyValuePair(offset, memStream.ToArray()); offset += (uint)memStream.Length; } diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 414c58e36..f653e247c 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -50,7 +50,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(DataWriter writer) => writer.Write(array); + public void WriteTo(DataWriter writer) => writer.WriteBytes(array); /// public override int GetHashCode() => Utils.GetHashCode(array); diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index a424e607c..67a434cef 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -95,7 +95,7 @@ void Write(CustomAttribute ca) { if (ca.IsRawBlob) { if ((ca.ConstructorArguments != null && ca.ConstructorArguments.Count > 0) || (ca.NamedArguments != null && ca.NamedArguments.Count > 0)) helper.Error("Raw custom attribute contains arguments and/or named arguments"); - writer.Write(ca.RawData); + writer.WriteBytes(ca.RawData); return; } @@ -122,14 +122,14 @@ void Write(CustomAttribute ca) { genericArguments.PushTypeArgs(gis.GenericArguments); } - writer.Write((ushort)1); + writer.WriteUInt16((ushort)1); int numArgs = Math.Min(methodSig.Params.Count, ca.ConstructorArguments.Count); for (int i = 0; i < numArgs; i++) WriteValue(FixTypeSig(methodSig.Params[i]), ca.ConstructorArguments[i]); int numNamedArgs = Math.Min((int)ushort.MaxValue, ca.NamedArguments.Count); - writer.Write((ushort)numNamedArgs); + writer.WriteUInt16((ushort)numNamedArgs); for (int i = 0; i < numNamedArgs; i++) Write(ca.NamedArguments[i]); } @@ -181,9 +181,9 @@ void WriteArrayValue(SZArraySig arrayType, IList args) { } if (args == null) - writer.Write(uint.MaxValue); + writer.WriteUInt32(uint.MaxValue); else { - writer.Write((uint)args.Count); + writer.WriteUInt32((uint)args.Count); var arrayElementType = FixTypeSig(arrayType.Next); for (int i = 0; i < args.Count; i++) WriteValue(arrayElementType, args[i]); @@ -389,86 +389,86 @@ void WriteElem(TypeSig argType, CAArgument value) { switch (argType.ElementType) { case ElementType.Boolean: if (!VerifyTypeAndValue(value, ElementType.Boolean)) - writer.Write(ToUInt64(value.Value) != 0); + writer.WriteBoolean(ToUInt64(value.Value) != 0); else - writer.Write((bool)value.Value); + writer.WriteBoolean((bool)value.Value); break; case ElementType.Char: if (!VerifyTypeAndValue(value, ElementType.Char)) - writer.Write((ushort)ToUInt64(value.Value)); + writer.WriteUInt16((ushort)ToUInt64(value.Value)); else - writer.Write((ushort)(char)value.Value); + writer.WriteUInt16((ushort)(char)value.Value); break; case ElementType.I1: if (!VerifyTypeAndValue(value, ElementType.I1)) - writer.Write((sbyte)ToUInt64(value.Value)); + writer.WriteSByte((sbyte)ToUInt64(value.Value)); else - writer.Write((sbyte)value.Value); + writer.WriteSByte((sbyte)value.Value); break; case ElementType.U1: if (!VerifyTypeAndValue(value, ElementType.U1)) - writer.Write((byte)ToUInt64(value.Value)); + writer.WriteByte((byte)ToUInt64(value.Value)); else - writer.Write((byte)value.Value); + writer.WriteByte((byte)value.Value); break; case ElementType.I2: if (!VerifyTypeAndValue(value, ElementType.I2)) - writer.Write((short)ToUInt64(value.Value)); + writer.WriteInt16((short)ToUInt64(value.Value)); else - writer.Write((short)value.Value); + writer.WriteInt16((short)value.Value); break; case ElementType.U2: if (!VerifyTypeAndValue(value, ElementType.U2)) - writer.Write((ushort)ToUInt64(value.Value)); + writer.WriteUInt16((ushort)ToUInt64(value.Value)); else - writer.Write((ushort)value.Value); + writer.WriteUInt16((ushort)value.Value); break; case ElementType.I4: if (!VerifyTypeAndValue(value, ElementType.I4)) - writer.Write((int)ToUInt64(value.Value)); + writer.WriteInt32((int)ToUInt64(value.Value)); else - writer.Write((int)value.Value); + writer.WriteInt32((int)value.Value); break; case ElementType.U4: if (!VerifyTypeAndValue(value, ElementType.U4)) - writer.Write((uint)ToUInt64(value.Value)); + writer.WriteUInt32((uint)ToUInt64(value.Value)); else - writer.Write((uint)value.Value); + writer.WriteUInt32((uint)value.Value); break; case ElementType.I8: if (!VerifyTypeAndValue(value, ElementType.I8)) - writer.Write((long)ToUInt64(value.Value)); + writer.WriteInt64((long)ToUInt64(value.Value)); else - writer.Write((long)value.Value); + writer.WriteInt64((long)value.Value); break; case ElementType.U8: if (!VerifyTypeAndValue(value, ElementType.U8)) - writer.Write(ToUInt64(value.Value)); + writer.WriteUInt64(ToUInt64(value.Value)); else - writer.Write((ulong)value.Value); + writer.WriteUInt64((ulong)value.Value); break; case ElementType.R4: if (!VerifyTypeAndValue(value, ElementType.R4)) - writer.Write((float)ToDouble(value.Value)); + writer.WriteSingle((float)ToDouble(value.Value)); else - writer.Write((float)value.Value); + writer.WriteSingle((float)value.Value); break; case ElementType.R8: if (!VerifyTypeAndValue(value, ElementType.R8)) - writer.Write(ToDouble(value.Value)); + writer.WriteDouble(ToDouble(value.Value)); else - writer.Write((double)value.Value); + writer.WriteDouble((double)value.Value); break; case ElementType.String: @@ -558,16 +558,16 @@ bool TryWriteEnumUnderlyingTypeValue(object o) { if (o == null) return false; switch (Type.GetTypeCode(o.GetType())) { - case TypeCode.Boolean: writer.Write((bool)o); break; - case TypeCode.Char: writer.Write((ushort)(char)o); break; - case TypeCode.SByte: writer.Write((sbyte)o); break; - case TypeCode.Byte: writer.Write((byte)o); break; - case TypeCode.Int16: writer.Write((short)o); break; - case TypeCode.UInt16: writer.Write((ushort)o); break; - case TypeCode.Int32: writer.Write((int)o); break; - case TypeCode.UInt32: writer.Write((uint)o); break; - case TypeCode.Int64: writer.Write((long)o); break; - case TypeCode.UInt64: writer.Write((ulong)o); break; + case TypeCode.Boolean: writer.WriteBoolean((bool)o); break; + case TypeCode.Char: writer.WriteUInt16((ushort)(char)o); break; + case TypeCode.SByte: writer.WriteSByte((sbyte)o); break; + case TypeCode.Byte: writer.WriteByte((byte)o); break; + case TypeCode.Int16: writer.WriteInt16((short)o); break; + case TypeCode.UInt16: writer.WriteUInt16((ushort)o); break; + case TypeCode.Int32: writer.WriteInt32((int)o); break; + case TypeCode.UInt32: writer.WriteUInt32((uint)o); break; + case TypeCode.Int64: writer.WriteInt64((long)o); break; + case TypeCode.UInt64: writer.WriteUInt64((ulong)o); break; default: return false; } return true; @@ -628,9 +628,9 @@ void Write(CANamedArgument namedArg) { } if (namedArg.IsProperty) - writer.Write((byte)SerializationType.Property); + writer.WriteByte((byte)SerializationType.Property); else - writer.Write((byte)SerializationType.Field); + writer.WriteByte((byte)SerializationType.Field); WriteFieldOrPropType(namedArg.Type); WriteUTF8String(namedArg.Name); @@ -652,34 +652,34 @@ void WriteFieldOrPropType(TypeSig type) { ITypeDefOrRef tdr; switch (type.ElementType) { - case ElementType.Boolean: writer.Write((byte)SerializationType.Boolean); break; - case ElementType.Char: writer.Write((byte)SerializationType.Char); break; - case ElementType.I1: writer.Write((byte)SerializationType.I1); break; - case ElementType.U1: writer.Write((byte)SerializationType.U1); break; - case ElementType.I2: writer.Write((byte)SerializationType.I2); break; - case ElementType.U2: writer.Write((byte)SerializationType.U2); break; - case ElementType.I4: writer.Write((byte)SerializationType.I4); break; - case ElementType.U4: writer.Write((byte)SerializationType.U4); break; - case ElementType.I8: writer.Write((byte)SerializationType.I8); break; - case ElementType.U8: writer.Write((byte)SerializationType.U8); break; - case ElementType.R4: writer.Write((byte)SerializationType.R4); break; - case ElementType.R8: writer.Write((byte)SerializationType.R8); break; - case ElementType.String: writer.Write((byte)SerializationType.String); break; - case ElementType.Object: writer.Write((byte)SerializationType.TaggedObject); break; + case ElementType.Boolean: writer.WriteByte((byte)SerializationType.Boolean); break; + case ElementType.Char: writer.WriteByte((byte)SerializationType.Char); break; + case ElementType.I1: writer.WriteByte((byte)SerializationType.I1); break; + case ElementType.U1: writer.WriteByte((byte)SerializationType.U1); break; + case ElementType.I2: writer.WriteByte((byte)SerializationType.I2); break; + case ElementType.U2: writer.WriteByte((byte)SerializationType.U2); break; + case ElementType.I4: writer.WriteByte((byte)SerializationType.I4); break; + case ElementType.U4: writer.WriteByte((byte)SerializationType.U4); break; + case ElementType.I8: writer.WriteByte((byte)SerializationType.I8); break; + case ElementType.U8: writer.WriteByte((byte)SerializationType.U8); break; + case ElementType.R4: writer.WriteByte((byte)SerializationType.R4); break; + case ElementType.R8: writer.WriteByte((byte)SerializationType.R8); break; + case ElementType.String: writer.WriteByte((byte)SerializationType.String); break; + case ElementType.Object: writer.WriteByte((byte)SerializationType.TaggedObject); break; case ElementType.SZArray: - writer.Write((byte)SerializationType.SZArray); + writer.WriteByte((byte)SerializationType.SZArray); WriteFieldOrPropType(type.Next); break; case ElementType.Class: tdr = ((TypeDefOrRefSig)type).TypeDefOrRef; if (CheckCorLibType(type, "Type")) - writer.Write((byte)SerializationType.Type); + writer.WriteByte((byte)SerializationType.Type); else if (tdr is TypeRef) { // Could be an enum TypeRef that couldn't be resolved, so the code // assumed it's a class and created a ClassSig. - writer.Write((byte)SerializationType.Enum); + writer.WriteByte((byte)SerializationType.Enum); WriteType(tdr); } else @@ -691,19 +691,19 @@ void WriteFieldOrPropType(TypeSig type) { var enumType = GetEnumTypeDef(type); // If TypeRef => assume it's an enum that couldn't be resolved if (enumType != null || tdr is TypeRef) { - writer.Write((byte)SerializationType.Enum); + writer.WriteByte((byte)SerializationType.Enum); WriteType(tdr); } else { helper.Error("Custom attribute type doesn't seem to be an enum."); - writer.Write((byte)SerializationType.Enum); + writer.WriteByte((byte)SerializationType.Enum); WriteType(tdr); } break; default: helper.Error("Custom attribute: Invalid type"); - writer.Write((byte)0xFF); + writer.WriteByte((byte)0xFF); break; } @@ -740,10 +740,10 @@ static bool CheckCorLibType(ITypeDefOrRef tdr, string name) { void WriteUTF8String(UTF8String s) { if ((object)s == null || s.Data == null) - writer.Write((byte)0xFF); + writer.WriteByte((byte)0xFF); else { writer.WriteCompressedUInt32((uint)s.Data.Length); - writer.Write(s.Data); + writer.WriteBytes(s.Data); } } diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs index a646941bc..97a669afe 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/DataWriter.cs @@ -27,25 +27,25 @@ public DataWriter(Stream stream) { static void ThrowArgumentOutOfRangeException(string message) => throw new ArgumentOutOfRangeException(message); - public void Write(bool value) => stream.WriteByte(value ? (byte)1 : (byte)0); - public void Write(sbyte value) => stream.WriteByte((byte)value); - public void Write(byte value) => stream.WriteByte(value); + public void WriteBoolean(bool value) => stream.WriteByte(value ? (byte)1 : (byte)0); + public void WriteSByte(sbyte value) => stream.WriteByte((byte)value); + public void WriteByte(byte value) => stream.WriteByte(value); - public void Write(short value) { + public void WriteInt16(short value) { var buffer = this.buffer; buffer[0] = (byte)value; buffer[1] = (byte)(value >> 8); stream.Write(buffer, 0, 2); } - public void Write(ushort value) { + public void WriteUInt16(ushort value) { var buffer = this.buffer; buffer[0] = (byte)value; buffer[1] = (byte)(value >> 8); stream.Write(buffer, 0, 2); } - public void Write(int value) { + public void WriteInt32(int value) { var buffer = this.buffer; buffer[0] = (byte)value; buffer[1] = (byte)(value >> 8); @@ -54,7 +54,7 @@ public void Write(int value) { stream.Write(buffer, 0, 4); } - public void Write(uint value) { + public void WriteUInt32(uint value) { var buffer = this.buffer; buffer[0] = (byte)value; buffer[1] = (byte)(value >> 8); @@ -63,7 +63,7 @@ public void Write(uint value) { stream.Write(buffer, 0, 4); } - public void Write(long value) { + public void WriteInt64(long value) { var buffer = this.buffer; buffer[0] = (byte)value; buffer[1] = (byte)(value >> 8); @@ -76,7 +76,7 @@ public void Write(long value) { stream.Write(buffer, 0, 8); } - public void Write(ulong value) { + public void WriteUInt64(ulong value) { var buffer = this.buffer; buffer[0] = (byte)value; buffer[1] = (byte)(value >> 8); @@ -89,7 +89,7 @@ public void Write(ulong value) { stream.Write(buffer, 0, 8); } - public unsafe void Write(float value) { + public unsafe void WriteSingle(float value) { uint tmp = *(uint*)&value; var buffer = this.buffer; buffer[0] = (byte)tmp; @@ -99,7 +99,7 @@ public unsafe void Write(float value) { stream.Write(buffer, 0, 4); } - public unsafe void Write(double value) { + public unsafe void WriteDouble(double value) { ulong tmp = *(ulong*)&value; var buffer = this.buffer; buffer[0] = (byte)tmp; @@ -113,8 +113,8 @@ public unsafe void Write(double value) { stream.Write(buffer, 0, 8); } - public void Write(byte[] source) => stream.Write(source, 0, source.Length); - public void Write(byte[] source, int index, int length) => stream.Write(source, index, length); + public void WriteBytes(byte[] source) => stream.Write(source, 0, source.Length); + public void WriteBytes(byte[] source, int index, int length) => stream.Write(source, index, length); public void WriteCompressedUInt32(uint value) { if (value <= 0x7F) diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index e87c5d1f4..3c6fcd08a 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -114,14 +114,14 @@ static uint GetLength(List entries, FileOffset offset, RVA public void WriteTo(DataWriter writer) { uint offset = 0; foreach (var entry in entries) { - writer.Write(entry.DebugDirectory.Characteristics); - writer.Write(entry.DebugDirectory.TimeDateStamp); - writer.Write(entry.DebugDirectory.MajorVersion); - writer.Write(entry.DebugDirectory.MinorVersion); - writer.Write((uint)entry.DebugDirectory.Type); - writer.Write(entry.Chunk.GetFileLength()); - writer.Write((uint)entry.Chunk.RVA); - writer.Write((uint)entry.Chunk.FileOffset); + writer.WriteUInt32(entry.DebugDirectory.Characteristics); + writer.WriteUInt32(entry.DebugDirectory.TimeDateStamp); + writer.WriteUInt16(entry.DebugDirectory.MajorVersion); + writer.WriteUInt16(entry.DebugDirectory.MinorVersion); + writer.WriteUInt32((uint)entry.DebugDirectory.Type); + writer.WriteUInt32(entry.Chunk.GetFileLength()); + writer.WriteUInt32((uint)entry.Chunk.RVA); + writer.WriteUInt32((uint)entry.Chunk.FileOffset); offset += HEADER_SIZE; } diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 76ab14c63..7b7d6706a 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -48,7 +48,7 @@ byte[] Write(IList secAttrs) { byte[] WriteFormat2(IList secAttrs) { var stream = new MemoryStream(); var writer = new DataWriter(stream); - writer.Write((byte)'.'); + writer.WriteByte((byte)'.'); WriteCompressedUInt32(writer, (uint)secAttrs.Count); foreach (var sa in secAttrs) { @@ -77,7 +77,7 @@ byte[] WriteFormat2(IList secAttrs) { namedArgsBlob = Array2.Empty(); } WriteCompressedUInt32(writer, (uint)namedArgsBlob.Length); - writer.Write(namedArgsBlob); + writer.WriteBytes(namedArgsBlob); } return stream.ToArray(); diff --git a/src/DotNet/Writer/Extensions.cs b/src/DotNet/Writer/Extensions.cs index 642240968..320b7f83e 100644 --- a/src/DotNet/Writer/Extensions.cs +++ b/src/DotNet/Writer/Extensions.cs @@ -13,10 +13,10 @@ public static partial class Extensions { public static void WriteZeros(this DataWriter writer, int count) { if (count <= 0x20) { for (int i = 0; i < count; i++) - writer.Write((byte)0); + writer.WriteByte((byte)0); } else - writer.Write(new byte[count]); + writer.WriteBytes(new byte[count]); } } } diff --git a/src/DotNet/Writer/GuidHeap.cs b/src/DotNet/Writer/GuidHeap.cs index 862c8e312..56e0ded1a 100644 --- a/src/DotNet/Writer/GuidHeap.cs +++ b/src/DotNet/Writer/GuidHeap.cs @@ -43,7 +43,7 @@ protected override void WriteToImpl(DataWriter writer) { foreach (var kv in guids) { if (userRawData == null || !userRawData.TryGetValue(offset, out var rawData)) rawData = kv.Key.ToByteArray(); - writer.Write(rawData); + writer.WriteBytes(rawData); offset += 16; } } diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index bae2182d2..3dbcd9580 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -91,19 +91,19 @@ public static void VerifyWriteTo(this IChunk chunk, DataWriter writer) { /// The data internal static void WriteDataDirectory(this DataWriter writer, IChunk chunk) { if (chunk == null || chunk.GetVirtualSize() == 0) - writer.Write(0UL); + writer.WriteUInt64(0); else { - writer.Write((uint)chunk.RVA); - writer.Write(chunk.GetVirtualSize()); + writer.WriteUInt32((uint)chunk.RVA); + writer.WriteUInt32(chunk.GetVirtualSize()); } } internal static void WriteDebugDirectory(this DataWriter writer, DebugDirectory chunk) { if (chunk == null || chunk.GetVirtualSize() == 0) - writer.Write(0UL); + writer.WriteUInt64(0); else { - writer.Write((uint)chunk.RVA); - writer.Write((uint)(chunk.Count * DebugDirectory.HEADER_SIZE)); + writer.WriteUInt32((uint)chunk.RVA); + writer.WriteUInt32((uint)(chunk.Count * DebugDirectory.HEADER_SIZE)); } } } diff --git a/src/DotNet/Writer/ImageCor20Header.cs b/src/DotNet/Writer/ImageCor20Header.cs index 11e2d6dbc..5f12af42b 100644 --- a/src/DotNet/Writer/ImageCor20Header.cs +++ b/src/DotNet/Writer/ImageCor20Header.cs @@ -116,12 +116,12 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public void WriteTo(DataWriter writer) { - writer.Write(0x48); // cb - writer.Write(options.MajorRuntimeVersion ?? Cor20HeaderOptions.DEFAULT_MAJOR_RT_VER); - writer.Write(options.MinorRuntimeVersion ?? Cor20HeaderOptions.DEFAULT_MINOR_RT_VER); + writer.WriteInt32(0x48); // cb + writer.WriteUInt16(options.MajorRuntimeVersion ?? Cor20HeaderOptions.DEFAULT_MAJOR_RT_VER); + writer.WriteUInt16(options.MinorRuntimeVersion ?? Cor20HeaderOptions.DEFAULT_MINOR_RT_VER); writer.WriteDataDirectory(Metadata); - writer.Write((uint)(options.Flags ?? ComImageFlags.ILOnly)); - writer.Write(options.EntryPoint ?? 0); + writer.WriteUInt32((uint)(options.Flags ?? ComImageFlags.ILOnly)); + writer.WriteUInt32(options.EntryPoint ?? 0); writer.WriteDataDirectory(NetResources); writer.WriteDataDirectory(StrongNameSignature); writer.WriteDataDirectory(null); // Code manager table diff --git a/src/DotNet/Writer/ImportAddressTable.cs b/src/DotNet/Writer/ImportAddressTable.cs index 11bee424d..6c33c7469 100644 --- a/src/DotNet/Writer/ImportAddressTable.cs +++ b/src/DotNet/Writer/ImportAddressTable.cs @@ -53,12 +53,12 @@ public void WriteTo(DataWriter writer) { if (!Enable) return; if (is64bit) { - writer.Write((ulong)(uint)ImportDirectory.CorXxxMainRVA); - writer.Write(0UL); + writer.WriteUInt64((ulong)(uint)ImportDirectory.CorXxxMainRVA); + writer.WriteUInt64(0); } else { - writer.Write((uint)ImportDirectory.CorXxxMainRVA); - writer.Write(0); + writer.WriteUInt32((uint)ImportDirectory.CorXxxMainRVA); + writer.WriteInt32(0); } } } diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index 55a8e18ca..1875ef622 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -91,31 +91,31 @@ public uint GetFileLength() { public void WriteTo(DataWriter writer) { if (!Enable) return; - writer.Write((uint)importLookupTableRVA); - writer.Write(0); // DateTimeStamp - writer.Write(0); // ForwarderChain - writer.Write((uint)mscoreeDllRVA); // Name - writer.Write((uint)ImportAddressTable.RVA); - writer.Write(0UL); - writer.Write(0UL); - writer.Write(0); + writer.WriteUInt32((uint)importLookupTableRVA); + writer.WriteInt32(0); // DateTimeStamp + writer.WriteInt32(0); // ForwarderChain + writer.WriteUInt32((uint)mscoreeDllRVA); // Name + writer.WriteUInt32((uint)ImportAddressTable.RVA); + writer.WriteUInt64(0); + writer.WriteUInt64(0); + writer.WriteInt32(0); // ImportLookupTable if (is64bit) { - writer.Write((ulong)(uint)corXxxMainRVA); - writer.Write(0UL); + writer.WriteUInt64((ulong)(uint)corXxxMainRVA); + writer.WriteUInt64(0); } else { - writer.Write((uint)corXxxMainRVA); - writer.Write(0); + writer.WriteUInt32((uint)corXxxMainRVA); + writer.WriteInt32(0); } writer.WriteZeros(stringsPadding); - writer.Write((ushort)0); - writer.Write(Encoding.UTF8.GetBytes(IsExeFile ? "_CorExeMain\0" : "_CorDllMain\0")); - writer.Write(Encoding.UTF8.GetBytes("mscoree.dll\0")); + writer.WriteUInt16((ushort)0); + writer.WriteBytes(Encoding.UTF8.GetBytes(IsExeFile ? "_CorExeMain\0" : "_CorDllMain\0")); + writer.WriteBytes(Encoding.UTF8.GetBytes("mscoree.dll\0")); - writer.Write((byte)0); + writer.WriteByte((byte)0); } } } diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index 5f7b96573..36dde93f0 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -23,7 +23,7 @@ public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; - writer.Write(row.Token); - writer.Write(row.FuncCode); + writer.WriteUInt32(row.Token); + writer.WriteUInt32(row.FuncCode); } } @@ -569,7 +569,7 @@ public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; - writer.Write(row.Token); + writer.WriteUInt32(row.Token); } } @@ -587,12 +587,12 @@ public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; - writer.Write(row.Processor); + writer.WriteUInt32(row.Processor); } } @@ -621,9 +621,9 @@ public static void Write(this DataWriter writer, Metadata metadata, MDTable table) { for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; - writer.Write(row.OSPlatformId); - writer.Write(row.OSMajorVersion); - writer.Write(row.OSMinorVersion); + writer.WriteUInt32(row.OSPlatformId); + writer.WriteUInt32(row.OSMajorVersion); + writer.WriteUInt32(row.OSMinorVersion); } } @@ -642,11 +642,11 @@ public static void Write(this DataWriter writer, Metadata metadata, MDTable methodNameOffsets.ToArray(); @@ -326,9 +326,9 @@ void WriteSdataBlob(uint timestamp) { vtbl.SdataChunkOffset = (uint)writer.Position; foreach (var info in vtbl.Methods) { info.ManagedVtblOffset = (uint)writer.Position; - writer.Write(0x06000000 + metadata.GetRid(info.Method)); + writer.WriteUInt32(0x06000000 + metadata.GetRid(info.Method)); if ((vtbl.Flags & VTableFlags.Bit64) != 0) - writer.Write(0U); + writer.WriteUInt32(0); } } @@ -391,18 +391,18 @@ void WriteSdataBlob(uint timestamp) { // Write IMAGE_EXPORT_DIRECTORY Debug.Assert((writer.Position & 3) == 0); exportDirOffset = (uint)writer.Position; - writer.Write(0U); // Characteristics - writer.Write(timestamp); - writer.Write(0U); // MajorVersion, MinorVersion + writer.WriteUInt32(0); // Characteristics + writer.WriteUInt32(timestamp); + writer.WriteUInt32(0); // MajorVersion, MinorVersion sdataBytesInfo.exportDirModuleNameStreamOffset = (uint)writer.Position; - writer.Write(0U); // Name - writer.Write(ordinalBase); // Base - writer.Write((uint)funcSize); // NumberOfFunctions - writer.Write(sdataBytesInfo.MethodNameOffsets.Length); // NumberOfNames + writer.WriteUInt32(0); // Name + writer.WriteInt32(ordinalBase); // Base + writer.WriteUInt32((uint)funcSize); // NumberOfFunctions + writer.WriteInt32(sdataBytesInfo.MethodNameOffsets.Length); // NumberOfNames sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset = (uint)writer.Position; - writer.Write(0U); // AddressOfFunctions - writer.Write(0U); // AddressOfNames - writer.Write(0U); // AddressOfNameOrdinals + writer.WriteUInt32(0); // AddressOfFunctions + writer.WriteUInt32(0); // AddressOfNames + writer.WriteUInt32(0); // AddressOfNameOrdinals sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.Position; WriteZeroes(writer, funcSize * 4); @@ -420,7 +420,7 @@ void WriteSdata(DataWriter writer) { if (sdataBytesInfo.Data == null) return; PatchSdataBytesBlob(); - writer.Write(sdataBytesInfo.Data); + writer.WriteBytes(sdataBytesInfo.Data); } void PatchSdataBytesBlob() { @@ -430,13 +430,13 @@ void PatchSdataBytesBlob() { var writer = new DataWriter(new MemoryStream(sdataBytesInfo.Data)); writer.Position = sdataBytesInfo.exportDirModuleNameStreamOffset; - writer.Write(namesBaseOffset + sdataBytesInfo.moduleNameOffset); + writer.WriteUInt32(namesBaseOffset + sdataBytesInfo.moduleNameOffset); writer.Position = sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset; - writer.Write(rva + sdataBytesInfo.addressOfFunctionsStreamOffset); // AddressOfFunctions + writer.WriteUInt32(rva + sdataBytesInfo.addressOfFunctionsStreamOffset); // AddressOfFunctions if (sdataBytesInfo.MethodNameOffsets.Length != 0) { - writer.Write(rva + sdataBytesInfo.addressOfNamesStreamOffset); // AddressOfNames - writer.Write(rva + sdataBytesInfo.addressOfNameOrdinalsStreamOffset); // AddressOfNameOrdinals + writer.WriteUInt32(rva + sdataBytesInfo.addressOfNamesStreamOffset); // AddressOfNames + writer.WriteUInt32(rva + sdataBytesInfo.addressOfNameOrdinalsStreamOffset); // AddressOfNameOrdinals } uint funcBaseRva = (uint)stubsChunk.RVA; @@ -447,35 +447,35 @@ void PatchSdataBytesBlob() { if (zeroes < 0) throw new InvalidOperationException(); while (zeroes-- > 0) - writer.Write(0); - writer.Write(funcBaseRva + info.StubChunkOffset); + writer.WriteInt32(0); + writer.WriteUInt32(funcBaseRva + info.StubChunkOffset); currentFuncIndex = info.FunctionIndex + 1; } foreach (var info in sortedNameMethodInfos) { if (info.FunctionIndex != currentFuncIndex++) throw new InvalidOperationException(); - writer.Write(funcBaseRva + info.StubChunkOffset); + writer.WriteUInt32(funcBaseRva + info.StubChunkOffset); } var nameOffsets = sdataBytesInfo.MethodNameOffsets; if (nameOffsets.Length != 0) { writer.Position = sdataBytesInfo.addressOfNamesStreamOffset; foreach (var info in sortedNameMethodInfos) - writer.Write(namesBaseOffset + nameOffsets[info.NameIndex]); + writer.WriteUInt32(namesBaseOffset + nameOffsets[info.NameIndex]); writer.Position = sdataBytesInfo.addressOfNameOrdinalsStreamOffset; foreach (var info in sortedNameMethodInfos) - writer.Write((ushort)info.FunctionIndex); + writer.WriteUInt16((ushort)info.FunctionIndex); } } static void WriteZeroes(DataWriter writer, int count) { while (count >= 8) { - writer.Write(0UL); + writer.WriteUInt64(0); count -= 8; } for (int i = 0; i < count; i++) - writer.Write((byte)0); + writer.WriteByte((byte)0); } void WriteVtableFixups(DataWriter writer) { @@ -484,9 +484,9 @@ void WriteVtableFixups(DataWriter writer) { foreach (var vtbl in vtables) { Debug.Assert(vtbl.Methods.Count <= ushort.MaxValue); - writer.Write((uint)sdataChunk.RVA + vtbl.SdataChunkOffset); - writer.Write((ushort)vtbl.Methods.Count); - writer.Write((ushort)vtbl.Flags); + writer.WriteUInt32((uint)sdataChunk.RVA + vtbl.SdataChunkOffset); + writer.WriteUInt16((ushort)vtbl.Methods.Count); + writer.WriteUInt16((ushort)vtbl.Flags); } } diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index dda803b93..e003c3850 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -41,7 +41,7 @@ byte[] Write(MarshalType marshalType) { if (type != NativeType.RawBlob) { if ((uint)type > byte.MaxValue) helper.Error("Invalid MarshalType.NativeType"); - writer.Write((byte)type); + writer.WriteByte((byte)type); } bool canWrite = true; switch (type) { @@ -100,7 +100,7 @@ byte[] Write(MarshalType marshalType) { case NativeType.RawBlob: var data = ((RawMarshalType)marshalType).Data; if (data != null) - writer.Write(data); + writer.WriteBytes(data); break; default: diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 03290f6b8..64ec31e3a 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3198,9 +3198,9 @@ uint GetDocumentNameBlobOffset(string name) { outStream.Position = 0; var parts = name.Split(directorySeparatorCharArray); if (parts.Length == 1) - writer.Write((byte)0); + writer.WriteByte((byte)0); else - writer.Write(directorySeparatorCharUtf8); + writer.WriteBytes(directorySeparatorCharUtf8); for (int i = 0; i < parts.Length; i++) { var part = parts[i]; uint partOffset = debugMetadata.blobHeap.Add(Encoding.UTF8.GetBytes(part)); diff --git a/src/DotNet/Writer/MetadataHeader.cs b/src/DotNet/Writer/MetadataHeader.cs index 1f55bb9e4..21269ec41 100644 --- a/src/DotNet/Writer/MetadataHeader.cs +++ b/src/DotNet/Writer/MetadataHeader.cs @@ -135,21 +135,21 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public void WriteTo(DataWriter writer) { - writer.Write(options.Signature ?? MetadataHeaderOptions.DEFAULT_SIGNATURE); - writer.Write(options.MajorVersion ?? 1); - writer.Write(options.MinorVersion ?? 1); - writer.Write(options.Reserved1 ?? 0); + writer.WriteUInt32(options.Signature ?? MetadataHeaderOptions.DEFAULT_SIGNATURE); + writer.WriteUInt16(options.MajorVersion ?? 1); + writer.WriteUInt16(options.MinorVersion ?? 1); + writer.WriteUInt32(options.Reserved1 ?? 0); var s = GetVersionString(); - writer.Write(Utils.AlignUp(s.Length, 4)); - writer.Write(s); + writer.WriteInt32(Utils.AlignUp(s.Length, 4)); + writer.WriteBytes(s); writer.WriteZeros(Utils.AlignUp(s.Length, 4) - s.Length); - writer.Write((byte)(options.StorageFlags ?? 0)); - writer.Write(options.Reserved2 ?? 0); - writer.Write((ushort)heaps.Count); + writer.WriteByte((byte)(options.StorageFlags ?? 0)); + writer.WriteByte(options.Reserved2 ?? 0); + writer.WriteUInt16((ushort)heaps.Count); foreach (var heap in heaps) { - writer.Write((uint)(heap.FileOffset - offset)); - writer.Write(heap.GetFileLength()); - writer.Write(s = GetAsciizName(heap.Name)); + writer.WriteUInt32((uint)(heap.FileOffset - offset)); + writer.WriteUInt32(heap.GetFileLength()); + writer.WriteBytes(s = GetAsciizName(heap.Name)); if (s.Length > 32) throw new ModuleWriterException($"Heap name '{heap.Name}' is > 32 bytes"); writer.WriteZeros(Utils.AlignUp(s.Length, 4) - s.Length); diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 096c1b98b..5ce95c4b1 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -135,11 +135,11 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public void WriteTo(DataWriter writer) { - writer.Write(code); + writer.WriteBytes(code); if (HasExtraSections) { var rva2 = rva + (uint)code.Length; writer.WriteZeros((int)rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT) - (int)rva2); - writer.Write(extraSections); + writer.WriteBytes(extraSections); } } diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index fe674a721..aa9768286 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -841,8 +841,8 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { var pdbId = new byte[20]; var pdbIdWriter = new DataWriter(new MemoryStream(pdbId)); var pdbGuid = TheOptions.PdbGuid; - pdbIdWriter.Write(pdbGuid.ToByteArray()); - pdbIdWriter.Write(GetTimeDateStamp()); + pdbIdWriter.WriteBytes(pdbGuid.ToByteArray()); + pdbIdWriter.WriteUInt32(GetTimeDateStamp()); Debug.Assert(pdbIdWriter.Position == pdbId.Length); metadata.WritePortablePdb(pdbStream, entryPointToken, pdbId); @@ -874,9 +874,9 @@ static byte[] CreateEmbeddedPortablePdbBlob(MemoryStream portablePdbStream) { var data = new byte[4 + 4 + compressedData.Length]; var stream = new MemoryStream(data); var writer = new DataWriter(stream); - writer.Write(0x4244504D);//"MPDB" - writer.Write((uint)portablePdbStream.Length); - writer.Write(compressedData); + writer.WriteInt32(0x4244504D);//"MPDB" + writer.WriteUInt32((uint)portablePdbStream.Length); + writer.WriteBytes(compressedData); Debug.Assert(stream.Position == data.Length); return data; } @@ -894,11 +894,11 @@ static byte[] Compress(MemoryStream sourceStream) { static byte[] GetCodeViewData(Guid guid, uint age, string filename) { var stream = new MemoryStream(); var writer = new DataWriter(stream); - writer.Write(0x53445352); - writer.Write(guid.ToByteArray()); - writer.Write(age); - writer.Write(Encoding.UTF8.GetBytes(filename)); - writer.Write((byte)0); + writer.WriteInt32(0x53445352); + writer.WriteBytes(guid.ToByteArray()); + writer.WriteUInt32(age); + writer.WriteBytes(Encoding.UTF8.GetBytes(filename)); + writer.WriteByte((byte)0); return stream.ToArray(); } diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index a2b831dce..cfc7dfb79 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -485,7 +485,7 @@ long WriteFile() { destStream.Position = destStreamBaseOffset; uint newCheckSum = destStream.CalculatePECheckSum(imageLength, checkSumOffset); writer.Position = checkSumOffset; - writer.Write(newCheckSum); + writer.WriteUInt32(newCheckSum); } OnWriterEvent(ModuleWriterEvent.EndWritePEChecksum); @@ -544,13 +544,13 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin // Update PE file header var peOptions = Options.PEHeadersOptions; writer.Position = fileHeaderOffset; - writer.Write((ushort)(peOptions.Machine ?? module.Machine)); - writer.Write((ushort)(origSections.Count + sections.Count)); + writer.WriteUInt16((ushort)(peOptions.Machine ?? module.Machine)); + writer.WriteUInt16((ushort)(origSections.Count + sections.Count)); WriteUInt32(writer, peOptions.TimeDateStamp); WriteUInt32(writer, peOptions.PointerToSymbolTable); WriteUInt32(writer, peOptions.NumberOfSymbols); writer.Position += 2; // sizeof(SizeOfOptionalHeader) - writer.Write((ushort)(peOptions.Characteristics ?? GetCharacteristics())); + writer.WriteUInt16((ushort)(peOptions.Characteristics ?? GetCharacteristics())); // Update optional header writer.Position = optionalHeaderOffset; @@ -559,12 +559,12 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin writer.Position += 2; WriteByte(writer, peOptions.MajorLinkerVersion); WriteByte(writer, peOptions.MinorLinkerVersion); - writer.Write(sectionSizes.SizeOfCode); - writer.Write(sectionSizes.SizeOfInitdData); - writer.Write(sectionSizes.SizeOfUninitdData); + writer.WriteUInt32(sectionSizes.SizeOfCode); + writer.WriteUInt32(sectionSizes.SizeOfInitdData); + writer.WriteUInt32(sectionSizes.SizeOfUninitdData); writer.Position += 4; // EntryPoint - writer.Write(sectionSizes.BaseOfCode); - writer.Write(sectionSizes.BaseOfData); + writer.WriteUInt32(sectionSizes.BaseOfCode); + writer.WriteUInt32(sectionSizes.BaseOfData); WriteUInt32(writer, peOptions.ImageBase); writer.Position += 8; // SectionAlignment, FileAlignment WriteUInt16(writer, peOptions.MajorOperatingSystemVersion); @@ -574,10 +574,10 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin WriteUInt16(writer, peOptions.MajorSubsystemVersion); WriteUInt16(writer, peOptions.MinorSubsystemVersion); WriteUInt32(writer, peOptions.Win32VersionValue); - writer.Write(sectionSizes.SizeOfImage); - writer.Write(sectionSizes.SizeOfHeaders); + writer.WriteUInt32(sectionSizes.SizeOfImage); + writer.WriteUInt32(sectionSizes.SizeOfHeaders); checkSumOffset = writer.Position; - writer.Write(0); // CheckSum + writer.WriteInt32(0); // CheckSum WriteUInt16(writer, peOptions.Subsystem); WriteUInt16(writer, peOptions.DllCharacteristics); WriteUInt32(writer, peOptions.SizeOfStackReserve); @@ -591,11 +591,11 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin writer.Position += 2; WriteByte(writer, peOptions.MajorLinkerVersion); WriteByte(writer, peOptions.MinorLinkerVersion); - writer.Write(sectionSizes.SizeOfCode); - writer.Write(sectionSizes.SizeOfInitdData); - writer.Write(sectionSizes.SizeOfUninitdData); + writer.WriteUInt32(sectionSizes.SizeOfCode); + writer.WriteUInt32(sectionSizes.SizeOfInitdData); + writer.WriteUInt32(sectionSizes.SizeOfUninitdData); writer.Position += 4; // EntryPoint - writer.Write(sectionSizes.BaseOfCode); + writer.WriteUInt32(sectionSizes.BaseOfCode); WriteUInt64(writer, peOptions.ImageBase); writer.Position += 8; // SectionAlignment, FileAlignment WriteUInt16(writer, peOptions.MajorOperatingSystemVersion); @@ -605,10 +605,10 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin WriteUInt16(writer, peOptions.MajorSubsystemVersion); WriteUInt16(writer, peOptions.MinorSubsystemVersion); WriteUInt32(writer, peOptions.Win32VersionValue); - writer.Write(sectionSizes.SizeOfImage); - writer.Write(sectionSizes.SizeOfHeaders); + writer.WriteUInt32(sectionSizes.SizeOfImage); + writer.WriteUInt32(sectionSizes.SizeOfHeaders); checkSumOffset = writer.Position; - writer.Write(0); // CheckSum + writer.WriteInt32(0); // CheckSum WriteUInt16(writer, peOptions.Subsystem ?? GetSubsystem()); WriteUInt16(writer, peOptions.DllCharacteristics ?? module.DllCharacteristics); WriteUInt64(writer, peOptions.SizeOfStackReserve); @@ -641,7 +641,7 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin writer.Position = sectionsOffset; foreach (var section in origSections) { writer.Position += 0x14; - writer.Write((uint)section.Chunk.FileOffset); // PointerToRawData + writer.WriteUInt32((uint)section.Chunk.FileOffset); // PointerToRawData writer.Position += 0x10; } foreach (var section in sections) @@ -649,12 +649,12 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin // Write the .NET header writer.Position = cor20Offset; - writer.Write(0x48); // cb + writer.WriteInt32(0x48); // cb WriteUInt16(writer, Options.Cor20HeaderOptions.MajorRuntimeVersion); WriteUInt16(writer, Options.Cor20HeaderOptions.MinorRuntimeVersion); writer.WriteDataDirectory(metadata); - writer.Write((uint)GetComImageFlags(entryPointIsManagedOrNoEntryPoint)); - writer.Write(entryPointToken); + writer.WriteUInt32((uint)GetComImageFlags(entryPointIsManagedOrNoEntryPoint)); + writer.WriteUInt32(entryPointToken); writer.WriteDataDirectory(netResources); writer.WriteDataDirectory(strongNameSignature); WriteDataDirectory(writer, module.Metadata.ImageCor20Header.CodeManagerTable); @@ -666,57 +666,57 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin } static void WriteDataDirectory(DataWriter writer, ImageDataDirectory dataDir) { - writer.Write((uint)dataDir.VirtualAddress); - writer.Write(dataDir.Size); + writer.WriteUInt32((uint)dataDir.VirtualAddress); + writer.WriteUInt32(dataDir.Size); } static void WriteByte(DataWriter writer, byte? value) { if (value == null) writer.Position++; else - writer.Write(value.Value); + writer.WriteByte(value.Value); } static void WriteUInt16(DataWriter writer, ushort? value) { if (value == null) writer.Position += 2; else - writer.Write(value.Value); + writer.WriteUInt16(value.Value); } static void WriteUInt16(DataWriter writer, Subsystem? value) { if (value == null) writer.Position += 2; else - writer.Write((ushort)value.Value); + writer.WriteUInt16((ushort)value.Value); } static void WriteUInt16(DataWriter writer, DllCharacteristics? value) { if (value == null) writer.Position += 2; else - writer.Write((ushort)value.Value); + writer.WriteUInt16((ushort)value.Value); } static void WriteUInt32(DataWriter writer, uint? value) { if (value == null) writer.Position += 4; else - writer.Write(value.Value); + writer.WriteUInt32(value.Value); } static void WriteUInt32(DataWriter writer, ulong? value) { if (value == null) writer.Position += 4; else - writer.Write((uint)value.Value); + writer.WriteUInt32((uint)value.Value); } static void WriteUInt64(DataWriter writer, ulong? value) { if (value == null) writer.Position += 8; else - writer.Write(value.Value); + writer.WriteUInt64(value.Value); } ComImageFlags GetComImageFlags(bool isManagedEntryPoint) { @@ -769,9 +769,9 @@ void UpdateVTableFixups(DataWriter writer) { foreach (var vtable in vtableFixups) { if (vtable.Methods.Count > ushort.MaxValue) throw new ModuleWriterException("Too many methods in vtable"); - writer.Write((uint)vtable.RVA); - writer.Write((ushort)vtable.Methods.Count); - writer.Write((ushort)vtable.Flags); + writer.WriteUInt32((uint)vtable.RVA); + writer.WriteUInt16((ushort)vtable.Methods.Count); + writer.WriteUInt16((ushort)vtable.Flags); long pos = writer.Position; writer.Position = ToWriterOffset(vtable.RVA); @@ -781,9 +781,9 @@ void UpdateVTableFixups(DataWriter writer) { } else { foreach (var method in vtable.Methods) { - writer.Write(GetMethodToken(method)); + writer.WriteUInt32(GetMethodToken(method)); if (vtable.Is64Bit) - writer.Write(0); + writer.WriteInt32(0); } } writer.Position = pos; diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index e7a17b187..53a3a49c6 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -82,7 +82,7 @@ public void WriteTo(DataWriter writer) { int padding = (int)rva2.AlignUp(alignment) - (int)rva2; writer.WriteZeros(padding); rva2 += (uint)padding; - writer.Write(resourceData.GetFileLength()); + writer.WriteUInt32(resourceData.GetFileLength()); resourceData.VerifyWriteTo(writer); rva2 += 4 + resourceData.GetFileLength(); } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index acd615e9e..9ce0c5576 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -339,89 +339,89 @@ public void WriteTo(DataWriter writer) { startOffset = writer.Position; // DOS header - writer.Write(dosHeader); + writer.WriteBytes(dosHeader); // PE magic - writer.Write(0x00004550); + writer.WriteInt32(0x00004550); // Image file header - writer.Write((ushort)GetMachine()); - writer.Write((ushort)SectionsCount); + writer.WriteUInt16((ushort)GetMachine()); + writer.WriteUInt16((ushort)SectionsCount); Debug.Assert(SectionsCount == sections.Count, "One or more sections are empty! The PE file could be bigger than it should be. Empty sections should be removed."); - writer.Write(options.TimeDateStamp ?? PEHeadersOptions.CreateNewTimeDateStamp()); - writer.Write(options.PointerToSymbolTable ?? 0); - writer.Write(options.NumberOfSymbols ?? 0); - writer.Write((ushort)(Use32BitOptionalHeader() ? 0xE0U : 0xF0)); - writer.Write((ushort)GetCharacteristics()); + writer.WriteUInt32(options.TimeDateStamp ?? PEHeadersOptions.CreateNewTimeDateStamp()); + writer.WriteUInt32(options.PointerToSymbolTable ?? 0); + writer.WriteUInt32(options.NumberOfSymbols ?? 0); + writer.WriteUInt16((ushort)(Use32BitOptionalHeader() ? 0xE0U : 0xF0)); + writer.WriteUInt16((ushort)GetCharacteristics()); var sectionSizes = new SectionSizes(fileAlignment, sectionAlignment, length, () => GetSectionSizeInfos()); // Image optional header uint ep = StartupStub == null || !StartupStub.Enable ? 0 : (uint)StartupStub.EntryPointRVA; if (Use32BitOptionalHeader()) { - writer.Write((ushort)0x010B); - writer.Write(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION); - writer.Write(options.MinorLinkerVersion ?? PEHeadersOptions.DEFAULT_MINOR_LINKER_VERSION); - writer.Write(sectionSizes.SizeOfCode); - writer.Write(sectionSizes.SizeOfInitdData); - writer.Write(sectionSizes.SizeOfUninitdData); - writer.Write(ep); - writer.Write(sectionSizes.BaseOfCode); - writer.Write(sectionSizes.BaseOfData); - writer.Write((uint)imageBase); - writer.Write(sectionAlignment); - writer.Write(fileAlignment); - writer.Write(options.MajorOperatingSystemVersion ?? 4); - writer.Write(options.MinorOperatingSystemVersion ?? 0); - writer.Write(options.MajorImageVersion ?? 0); - writer.Write(options.MinorImageVersion ?? 0); - writer.Write(options.MajorSubsystemVersion ?? 4); - writer.Write(options.MinorSubsystemVersion ?? 0); - writer.Write(options.Win32VersionValue ?? 0); - writer.Write(sectionSizes.SizeOfImage); - writer.Write(sectionSizes.SizeOfHeaders); + writer.WriteUInt16((ushort)0x010B); + writer.WriteByte(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION); + writer.WriteByte(options.MinorLinkerVersion ?? PEHeadersOptions.DEFAULT_MINOR_LINKER_VERSION); + writer.WriteUInt32(sectionSizes.SizeOfCode); + writer.WriteUInt32(sectionSizes.SizeOfInitdData); + writer.WriteUInt32(sectionSizes.SizeOfUninitdData); + writer.WriteUInt32(ep); + writer.WriteUInt32(sectionSizes.BaseOfCode); + writer.WriteUInt32(sectionSizes.BaseOfData); + writer.WriteUInt32((uint)imageBase); + writer.WriteUInt32(sectionAlignment); + writer.WriteUInt32(fileAlignment); + writer.WriteUInt16(options.MajorOperatingSystemVersion ?? 4); + writer.WriteUInt16(options.MinorOperatingSystemVersion ?? 0); + writer.WriteUInt16(options.MajorImageVersion ?? 0); + writer.WriteUInt16(options.MinorImageVersion ?? 0); + writer.WriteUInt16(options.MajorSubsystemVersion ?? 4); + writer.WriteUInt16(options.MinorSubsystemVersion ?? 0); + writer.WriteUInt32(options.Win32VersionValue ?? 0); + writer.WriteUInt32(sectionSizes.SizeOfImage); + writer.WriteUInt32(sectionSizes.SizeOfHeaders); checkSumOffset = writer.Position; - writer.Write(0); // CheckSum - writer.Write((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM)); - writer.Write((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics)); - writer.Write((uint)(options.SizeOfStackReserve ?? 0x00100000)); - writer.Write((uint)(options.SizeOfStackCommit ?? 0x00001000)); - writer.Write((uint)(options.SizeOfHeapReserve ?? 0x00100000)); - writer.Write((uint)(options.SizeOfHeapCommit ?? 0x00001000)); - writer.Write(options.LoaderFlags ?? 0x00000000); - writer.Write(options.NumberOfRvaAndSizes ?? 0x00000010); + writer.WriteInt32(0); // CheckSum + writer.WriteUInt16((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM)); + writer.WriteUInt16((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics)); + writer.WriteUInt32((uint)(options.SizeOfStackReserve ?? 0x00100000)); + writer.WriteUInt32((uint)(options.SizeOfStackCommit ?? 0x00001000)); + writer.WriteUInt32((uint)(options.SizeOfHeapReserve ?? 0x00100000)); + writer.WriteUInt32((uint)(options.SizeOfHeapCommit ?? 0x00001000)); + writer.WriteUInt32(options.LoaderFlags ?? 0x00000000); + writer.WriteUInt32(options.NumberOfRvaAndSizes ?? 0x00000010); } else { - writer.Write((ushort)0x020B); - writer.Write(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION); - writer.Write(options.MinorLinkerVersion ?? PEHeadersOptions.DEFAULT_MINOR_LINKER_VERSION); - writer.Write(sectionSizes.SizeOfCode); - writer.Write(sectionSizes.SizeOfInitdData); - writer.Write(sectionSizes.SizeOfUninitdData); - writer.Write(ep); - writer.Write(sectionSizes.BaseOfCode); - writer.Write(imageBase); - writer.Write(sectionAlignment); - writer.Write(fileAlignment); - writer.Write(options.MajorOperatingSystemVersion ?? 4); - writer.Write(options.MinorOperatingSystemVersion ?? 0); - writer.Write(options.MajorImageVersion ?? 0); - writer.Write(options.MinorImageVersion ?? 0); - writer.Write(options.MajorSubsystemVersion ?? 4); - writer.Write(options.MinorSubsystemVersion ?? 0); - writer.Write(options.Win32VersionValue ?? 0); - writer.Write(sectionSizes.SizeOfImage); - writer.Write(sectionSizes.SizeOfHeaders); + writer.WriteUInt16((ushort)0x020B); + writer.WriteByte(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION); + writer.WriteByte(options.MinorLinkerVersion ?? PEHeadersOptions.DEFAULT_MINOR_LINKER_VERSION); + writer.WriteUInt32(sectionSizes.SizeOfCode); + writer.WriteUInt32(sectionSizes.SizeOfInitdData); + writer.WriteUInt32(sectionSizes.SizeOfUninitdData); + writer.WriteUInt32(ep); + writer.WriteUInt32(sectionSizes.BaseOfCode); + writer.WriteUInt64(imageBase); + writer.WriteUInt32(sectionAlignment); + writer.WriteUInt32(fileAlignment); + writer.WriteUInt16(options.MajorOperatingSystemVersion ?? 4); + writer.WriteUInt16(options.MinorOperatingSystemVersion ?? 0); + writer.WriteUInt16(options.MajorImageVersion ?? 0); + writer.WriteUInt16(options.MinorImageVersion ?? 0); + writer.WriteUInt16(options.MajorSubsystemVersion ?? 4); + writer.WriteUInt16(options.MinorSubsystemVersion ?? 0); + writer.WriteUInt32(options.Win32VersionValue ?? 0); + writer.WriteUInt32(sectionSizes.SizeOfImage); + writer.WriteUInt32(sectionSizes.SizeOfHeaders); checkSumOffset = writer.Position; - writer.Write(0); // CheckSum - writer.Write((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM)); - writer.Write((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics)); - writer.Write(options.SizeOfStackReserve ?? 0x0000000000400000); - writer.Write(options.SizeOfStackCommit ?? 0x0000000000004000); - writer.Write(options.SizeOfHeapReserve ?? 0x0000000000100000); - writer.Write(options.SizeOfHeapCommit ?? 0x0000000000002000); - writer.Write(options.LoaderFlags ?? 0x00000000); - writer.Write(options.NumberOfRvaAndSizes ?? 0x00000010); + writer.WriteInt32(0); // CheckSum + writer.WriteUInt16((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM)); + writer.WriteUInt16((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics)); + writer.WriteUInt64(options.SizeOfStackReserve ?? 0x0000000000400000); + writer.WriteUInt64(options.SizeOfStackCommit ?? 0x0000000000004000); + writer.WriteUInt64(options.SizeOfHeapReserve ?? 0x0000000000100000); + writer.WriteUInt64(options.SizeOfHeapCommit ?? 0x0000000000002000); + writer.WriteUInt32(options.LoaderFlags ?? 0x00000000); + writer.WriteUInt32(options.NumberOfRvaAndSizes ?? 0x00000010); } writer.WriteDataDirectory(ExportDirectory); @@ -463,7 +463,7 @@ public void WriteCheckSum(DataWriter writer, long length) { writer.Position = startOffset; uint checkSum = writer.InternalStream.CalculatePECheckSum(length, checkSumOffset); writer.Position = checkSumOffset; - writer.Write(checkSum); + writer.WriteUInt32(checkSum); } Machine GetMachine() => options.Machine ?? Machine.I386; diff --git a/src/DotNet/Writer/PESection.cs b/src/DotNet/Writer/PESection.cs index ad784d644..eeb9a594c 100644 --- a/src/DotNet/Writer/PESection.cs +++ b/src/DotNet/Writer/PESection.cs @@ -68,16 +68,16 @@ public uint WriteHeaderTo(DataWriter writer, uint fileAlignment, uint sectionAli uint rawSize = Utils.AlignUp(fileLen, fileAlignment); uint dataOffset = (uint)FileOffset; - writer.Write(Encoding.UTF8.GetBytes(Name + "\0\0\0\0\0\0\0\0"), 0, 8); - writer.Write(vs); // VirtualSize - writer.Write((uint)rva); // VirtualAddress - writer.Write(rawSize); // SizeOfRawData - writer.Write(dataOffset); // PointerToRawData - writer.Write(0); // PointerToRelocations - writer.Write(0); // PointerToLinenumbers - writer.Write((ushort)0); // NumberOfRelocations - writer.Write((ushort)0); // NumberOfLinenumbers - writer.Write(Characteristics); + writer.WriteBytes(Encoding.UTF8.GetBytes(Name + "\0\0\0\0\0\0\0\0"), 0, 8); + writer.WriteUInt32(vs); // VirtualSize + writer.WriteUInt32((uint)rva); // VirtualAddress + writer.WriteUInt32(rawSize); // SizeOfRawData + writer.WriteUInt32(dataOffset); // PointerToRawData + writer.WriteInt32(0); // PointerToRelocations + writer.WriteInt32(0); // PointerToLinenumbers + writer.WriteUInt16((ushort)0); // NumberOfRelocations + writer.WriteUInt16((ushort)0); // NumberOfLinenumbers + writer.WriteUInt32(Characteristics); return alignedVs; } diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs index fe92efbbd..bdf211783 100644 --- a/src/DotNet/Writer/PdbHeap.cs +++ b/src/DotNet/Writer/PdbHeap.cs @@ -79,13 +79,13 @@ public override uint GetRawLength() { protected override void WriteToImpl(DataWriter writer) { if (!referencedTypeSystemTablesInitd) throw new InvalidOperationException("ReferencedTypeSystemTables hasn't been initialized yet"); - writer.Write(pdbId); - writer.Write(entryPoint); - writer.Write(referencedTypeSystemTables); + writer.WriteBytes(pdbId); + writer.WriteUInt32(entryPoint); + writer.WriteUInt64(referencedTypeSystemTables); ulong t = referencedTypeSystemTables; for (int i = 0; i < typeSystemTableRows.Length; i++, t >>= 1) { if (((int)t & 1) != 0) - writer.Write(typeSystemTableRows[i]); + writer.WriteUInt32(typeSystemTableRows[i]); } } } diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index c45c9f933..f7fe504e0 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -88,12 +88,12 @@ public void WriteTo(DataWriter writer) { // 3 = IMAGE_REL_BASED_HIGHLOW, A = IMAGE_REL_BASED_DIR64 uint relocType = is64bit ? 0xA000U : 0x3000; foreach (var pageList in relocSections) { - writer.Write(pageList[0] & ~0xFFFU); - writer.Write((uint)(8 + ((pageList.Count + 1) & ~1) * 2)); + writer.WriteUInt32(pageList[0] & ~0xFFFU); + writer.WriteUInt32((uint)(8 + ((pageList.Count + 1) & ~1) * 2)); foreach (var rva in pageList) - writer.Write((ushort)(relocType | (rva & 0xFFF))); + writer.WriteUInt16((ushort)(relocType | (rva & 0xFFF))); if ((pageList.Count & 1) != 0) - writer.Write((ushort)0); + writer.WriteUInt16((ushort)0); } } diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index 684cee051..1ae7e2b96 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -91,12 +91,12 @@ void Write(TypeSig typeSig) { const ElementType DEFAULT_ELEMENT_TYPE = ElementType.Boolean; if (typeSig == null) { helper.Error("TypeSig is null"); - writer.Write((byte)DEFAULT_ELEMENT_TYPE); + writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); return; } if (!recursionCounter.Increment()) { helper.Error("Infinite recursion"); - writer.Write((byte)DEFAULT_ELEMENT_TYPE); + writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); return; } @@ -121,31 +121,31 @@ void Write(TypeSig typeSig) { case ElementType.U: case ElementType.Object: case ElementType.Sentinel: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); break; case ElementType.Ptr: case ElementType.ByRef: case ElementType.SZArray: case ElementType.Pinned: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); Write(typeSig.Next); break; case ElementType.ValueType: case ElementType.Class: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); Write(((TypeDefOrRefSig)typeSig).TypeDefOrRef); break; case ElementType.Var: case ElementType.MVar: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); WriteCompressedUInt32(((GenericSig)typeSig).Number); break; case ElementType.Array: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); var ary = (ArraySig)typeSig; Write(ary.Next); WriteCompressedUInt32(ary.Rank); @@ -160,7 +160,7 @@ void Write(TypeSig typeSig) { break; case ElementType.GenericInst: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); var gis = (GenericInstSig)typeSig; Write(gis.GenericType); count = WriteCompressedUInt32((uint)gis.GenericArguments.Count); @@ -169,25 +169,25 @@ void Write(TypeSig typeSig) { break; case ElementType.ValueArray: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); Write(typeSig.Next); WriteCompressedUInt32((typeSig as ValueArraySig).Size); break; case ElementType.FnPtr: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); Write((typeSig as FnPtrSig).Signature); break; case ElementType.CModReqd: case ElementType.CModOpt: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); Write((typeSig as ModifierSig).Modifier); Write(typeSig.Next); break; case ElementType.Module: - writer.Write((byte)typeSig.ElementType); + writer.WriteByte((byte)typeSig.ElementType); WriteCompressedUInt32((typeSig as ModuleSig).Index); Write(typeSig.Next); break; @@ -197,7 +197,7 @@ void Write(TypeSig typeSig) { case ElementType.Internal: default: helper.Error("Unknown or unsupported element type"); - writer.Write((byte)DEFAULT_ELEMENT_TYPE); + writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); break; } @@ -244,7 +244,7 @@ void Write(CallingConventionSig sig) { Write(gim); else { helper.Error("Unknown calling convention sig"); - writer.Write((byte)sig.GetCallingConvention()); + writer.WriteByte((byte)sig.GetCallingConvention()); } recursionCounter.Decrement(); @@ -260,7 +260,7 @@ void Write(MethodBaseSig sig) { return; } - writer.Write((byte)sig.GetCallingConvention()); + writer.WriteByte((byte)sig.GetCallingConvention()); if (sig.Generic) WriteCompressedUInt32(sig.GenParamCount); @@ -274,7 +274,7 @@ void Write(MethodBaseSig sig) { Write(sig.Params[(int)i]); if (sig.ParamsAfterSentinel != null && sig.ParamsAfterSentinel.Count > 0) { - writer.Write((byte)ElementType.Sentinel); + writer.WriteByte((byte)ElementType.Sentinel); for (uint i = 0, j = (uint)sig.Params.Count; i < (uint)sig.ParamsAfterSentinel.Count && j < count; i++, j++) Write(sig.ParamsAfterSentinel[(int)i]); } @@ -292,7 +292,7 @@ void Write(FieldSig sig) { return; } - writer.Write((byte)sig.GetCallingConvention()); + writer.WriteByte((byte)sig.GetCallingConvention()); Write(sig.Type); recursionCounter.Decrement(); @@ -308,7 +308,7 @@ void Write(LocalSig sig) { return; } - writer.Write((byte)sig.GetCallingConvention()); + writer.WriteByte((byte)sig.GetCallingConvention()); uint count = WriteCompressedUInt32((uint)sig.Locals.Count); if (count >= 0x10000) { // ldloc 0xFFFF is invalid, see the ldloc documentation @@ -330,7 +330,7 @@ void Write(GenericInstMethodSig sig) { return; } - writer.Write((byte)sig.GetCallingConvention()); + writer.WriteByte((byte)sig.GetCallingConvention()); uint count = WriteCompressedUInt32((uint)sig.GenericArguments.Count); for (uint i = 0; i < count; i++) Write(sig.GenericArguments[(int)i]); diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index eaacd860a..9915537e5 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -200,20 +200,20 @@ uint AddToCache(UTF8String s) { /// protected override void WriteToImpl(DataWriter writer) { if (originalData != null) - writer.Write(originalData); + writer.WriteBytes(originalData); else - writer.Write((byte)0); + writer.WriteByte((byte)0); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != s.Data.Length + 1) throw new InvalidOperationException("Invalid length of raw data"); - writer.Write(rawData); + writer.WriteBytes(rawData); } else { - writer.Write(s.Data); - writer.Write((byte)0); + writer.WriteBytes(s.Data); + writer.WriteByte((byte)0); } offset += (uint)s.Data.Length + 1; } diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index c57866aaf..968d6f0b5 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -386,19 +386,19 @@ internal void GetSystemTableRows(out ulong mask, uint[] tables) { /// public void WriteTo(DataWriter writer) { - writer.Write(options.Reserved1 ?? 0); - writer.Write(majorVersion); - writer.Write(minorVersion); - writer.Write((byte)GetMDStreamFlags()); - writer.Write(GetLog2Rid()); - writer.Write(GetValidMask()); - writer.Write(GetSortedMask()); + writer.WriteUInt32(options.Reserved1 ?? 0); + writer.WriteByte(majorVersion); + writer.WriteByte(minorVersion); + writer.WriteByte((byte)GetMDStreamFlags()); + writer.WriteByte(GetLog2Rid()); + writer.WriteUInt64(GetValidMask()); + writer.WriteUInt64(GetSortedMask()); foreach (var mdt in Tables) { if (!mdt.IsEmpty) - writer.Write(mdt.Rows); + writer.WriteInt32(mdt.Rows); } if (options.ExtraData.HasValue) - writer.Write(options.ExtraData.Value); + writer.WriteUInt32(options.ExtraData.Value); writer.Write(metadata, ModuleTable); writer.Write(metadata, TypeRefTable); diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index d670f654d..717f21489 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -104,9 +104,9 @@ uint AddToCache(string s) { /// protected override void WriteToImpl(DataWriter writer) { if (originalData != null) - writer.Write(originalData); + writer.WriteBytes(originalData); else - writer.Write((byte)0); + writer.WriteByte((byte)0); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { @@ -114,7 +114,7 @@ protected override void WriteToImpl(DataWriter writer) { if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); - writer.Write(rawData); + writer.WriteBytes(rawData); } else WriteString(writer, s); @@ -127,11 +127,11 @@ void WriteString(DataWriter writer, string s) { byte last = 0; for (int i = 0; i < s.Length; i++) { ushort c = (ushort)s[i]; - writer.Write(c); + writer.WriteUInt16(c); if (c > 0xFF || (1 <= c && c <= 8) || (0x0E <= c && c <= 0x1F) || c == 0x27 || c == 0x2D || c == 0x7F) last = 1; } - writer.Write(last); + writer.WriteByte(last); } /// diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index f0b48c20f..123b7df8c 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -383,8 +383,8 @@ public void WriteTo(DataWriter writer) { var bytes = Encoding.Unicode.GetBytes(s); if (bytes.Length / 2 > ushort.MaxValue) throw new ModuleWriterException("Win32 resource entry name is too long"); - writer.Write((ushort)(bytes.Length / 2)); - writer.Write(bytes); + writer.WriteUInt16((ushort)(bytes.Length / 2)); + writer.WriteBytes(bytes); offset += 2 + (uint)bytes.Length; } @@ -403,29 +403,29 @@ public void WriteTo(DataWriter writer) { } uint WriteTo(DataWriter writer, ResourceDirectory dir) { - writer.Write(dir.Characteristics); - writer.Write(dir.TimeDateStamp); - writer.Write(dir.MajorVersion); - writer.Write(dir.MinorVersion); + writer.WriteUInt32(dir.Characteristics); + writer.WriteUInt32(dir.TimeDateStamp); + writer.WriteUInt16(dir.MajorVersion); + writer.WriteUInt16(dir.MinorVersion); GetNamedAndIds(dir, out var named, out var ids); if (named.Count > ushort.MaxValue || ids.Count > ushort.MaxValue) throw new ModuleWriterException("Too many named/id Win32 resource entries"); - writer.Write((ushort)named.Count); - writer.Write((ushort)ids.Count); + writer.WriteUInt16((ushort)named.Count); + writer.WriteUInt16((ushort)ids.Count); // These must be sorted in ascending order. Names are case insensitive. named.Sort((a, b) => a.Name.Name.ToUpperInvariant().CompareTo(b.Name.Name.ToUpperInvariant())); ids.Sort((a, b) => a.Name.Id.CompareTo(b.Name.Id)); foreach (var d in named) { - writer.Write(0x80000000 | stringsDict[d.Name.Name]); - writer.Write(GetDirectoryEntryOffset(d)); + writer.WriteUInt32(0x80000000 | stringsDict[d.Name.Name]); + writer.WriteUInt32(GetDirectoryEntryOffset(d)); } foreach (var d in ids) { - writer.Write(d.Name.Id); - writer.Write(GetDirectoryEntryOffset(d)); + writer.WriteInt32(d.Name.Id); + writer.WriteUInt32(GetDirectoryEntryOffset(d)); } return 16 + (uint)(named.Count + ids.Count) * 8; @@ -455,10 +455,10 @@ static void GetNamedAndIds(ResourceDirectory dir, out List Date: Mon, 19 Mar 2018 20:36:44 +0100 Subject: [PATCH 151/511] Enable VerifyWriteTo() check again since we're not using BinaryWriter --- src/DotNet/Writer/DataWriter.cs | 5 ++++- src/DotNet/Writer/IChunk.cs | 10 ++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs index 97a669afe..e8441c2f0 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/DataWriter.cs @@ -21,10 +21,13 @@ public long Position { } public DataWriter(Stream stream) { - this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); + if (stream == null) + ThrowArgumentNullException(nameof(stream)); + this.stream = stream; buffer = new byte[BUFFER_LEN]; } + static void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName); static void ThrowArgumentOutOfRangeException(string message) => throw new ArgumentOutOfRangeException(message); public void WriteBoolean(bool value) => stream.WriteByte(value ? (byte)1 : (byte)0); diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index 3dbcd9580..24ca5f24b 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -71,19 +71,17 @@ public static partial class Extensions { /// Destination /// Not all bytes were written public static void VerifyWriteTo(this IChunk chunk, DataWriter writer) { -#if DEBUG - // PERF: Calling the BaseStream property is pretty expensive so only do it in DEBUG builds long pos = writer.Position; -#endif // Uncomment this to add some debug info, useful when comparing old vs new version //System.Diagnostics.Debug.WriteLine($" RVA 0x{(uint)chunk.RVA:X8} OFFS 0x{(uint)chunk.FileOffset:X8} VSIZE 0x{chunk.GetVirtualSize():X8} {chunk.GetType().FullName}"); chunk.WriteTo(writer); -#if DEBUG if (writer.Position - pos != chunk.GetFileLength()) - throw new IOException("Did not write all bytes"); -#endif + VerifyWriteToThrow(chunk); } + static void VerifyWriteToThrow(IChunk chunk) => + throw new IOException($"Did not write all bytes: {chunk.GetType().FullName}"); + /// /// Writes a data directory /// From 4cde390bd79714baa23a52f6f5e8dde440d41ed0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:36:53 +0100 Subject: [PATCH 152/511] Remove unnecessary usings --- src/DotNet/CpuArch.cs | 1 - src/DotNet/MD/ColumnInfo.cs | 3 +-- src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs | 1 - src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs | 1 - src/DotNet/Utils.cs | 1 - src/DotNet/Writer/ByteArrayChunk.cs | 1 - src/DotNet/Writer/ChunkListBase.cs | 3 +-- src/DotNet/Writer/DataReaderChunk.cs | 1 - src/DotNet/Writer/DebugDirectory.cs | 1 - src/DotNet/Writer/GuidHeap.cs | 3 +-- src/DotNet/Writer/HeapBase.cs | 1 - src/DotNet/Writer/ImageCor20Header.cs | 1 - src/DotNet/Writer/ImportAddressTable.cs | 1 - src/DotNet/Writer/ImportDirectory.cs | 1 - src/DotNet/Writer/MDTableWriter.cs | 1 - src/DotNet/Writer/MetadataHeader.cs | 3 +-- src/DotNet/Writer/MethodBody.cs | 1 - src/DotNet/Writer/MethodBodyChunks.cs | 3 +-- src/DotNet/Writer/ModuleWriter.cs | 1 - src/DotNet/Writer/NativeModuleWriter.cs | 1 - src/DotNet/Writer/NetResources.cs | 1 - src/DotNet/Writer/PEHeaders.cs | 1 - src/DotNet/Writer/PESection.cs | 1 - src/DotNet/Writer/PdbHeap.cs | 1 - src/DotNet/Writer/RelocDirectory.cs | 1 - src/DotNet/Writer/StartupStub.cs | 1 - src/DotNet/Writer/StringsHeap.cs | 3 +-- src/DotNet/Writer/StrongNameSignature.cs | 1 - src/DotNet/Writer/TablesHeap.cs | 1 - src/DotNet/Writer/Win32ResourcesChunk.cs | 3 +-- 30 files changed, 7 insertions(+), 37 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 1693904b1..f072e7061 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using dnlib.DotNet.Writer; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/MD/ColumnInfo.cs b/src/DotNet/MD/ColumnInfo.cs index 91664cf73..5de5ec797 100644 --- a/src/DotNet/MD/ColumnInfo.cs +++ b/src/DotNet/MD/ColumnInfo.cs @@ -1,8 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Diagnostics; -using System.IO; using dnlib.DotNet.Writer; using dnlib.IO; diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index 76fe84953..ed264e376 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System.Collections.Generic; -using System.IO; using System.Text; using dnlib.DotNet.Writer; diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index 4698410e9..fb735705c 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.IO; using System.Text; using dnlib.DotNet.Writer; diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index d58124975..63e463655 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Text; namespace dnlib.DotNet { diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index f653e247c..8ff323493 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index 583b1cd02..e3fbc1cf5 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; -using System.IO; +using System.Collections.Generic; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/DataReaderChunk.cs b/src/DotNet/Writer/DataReaderChunk.cs index c283f4367..111521830 100644 --- a/src/DotNet/Writer/DataReaderChunk.cs +++ b/src/DotNet/Writer/DataReaderChunk.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index 3c6fcd08a..ad4489908 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using dnlib.DotNet.Pdb; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/GuidHeap.cs b/src/DotNet/Writer/GuidHeap.cs index 56e0ded1a..3c12e9ad6 100644 --- a/src/DotNet/Writer/GuidHeap.cs +++ b/src/DotNet/Writer/GuidHeap.cs @@ -1,8 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; -using System.IO; namespace dnlib.DotNet.Writer { /// diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index 1e8c3ce18..3d6903da7 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/ImageCor20Header.cs b/src/DotNet/Writer/ImageCor20Header.cs index 5f12af42b..4385fd9c5 100644 --- a/src/DotNet/Writer/ImageCor20Header.cs +++ b/src/DotNet/Writer/ImageCor20Header.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using dnlib.IO; using dnlib.PE; using dnlib.DotNet.MD; diff --git a/src/DotNet/Writer/ImportAddressTable.cs b/src/DotNet/Writer/ImportAddressTable.cs index 6c33c7469..05ce2e9ee 100644 --- a/src/DotNet/Writer/ImportAddressTable.cs +++ b/src/DotNet/Writer/ImportAddressTable.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index 1875ef622..7445e9617 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using System.Text; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index 36dde93f0..d39bdd0c5 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using dnlib.DotNet.MD; namespace dnlib.DotNet.Writer { diff --git a/src/DotNet/Writer/MetadataHeader.cs b/src/DotNet/Writer/MetadataHeader.cs index 21269ec41..1d159810e 100644 --- a/src/DotNet/Writer/MetadataHeader.cs +++ b/src/DotNet/Writer/MetadataHeader.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; -using System.IO; +using System.Collections.Generic; using System.Text; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 5ce95c4b1..2b74dfd9f 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System.Diagnostics; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index e5bcba81b..db692eb32 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -1,9 +1,8 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 6b7f98a7d..122de3b51 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using dnlib.DotNet.MD; using dnlib.PE; using dnlib.W32Resources; diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index cfc7dfb79..b5e5cfa83 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using dnlib.IO; using dnlib.PE; using dnlib.W32Resources; diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index 53a3a49c6..a1fbb8bc0 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 9ce0c5576..148bc11ed 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/PESection.cs b/src/DotNet/Writer/PESection.cs index eeb9a594c..8bbbfe597 100644 --- a/src/DotNet/Writer/PESection.cs +++ b/src/DotNet/Writer/PESection.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using System.Text; using dnlib.PE; diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs index bdf211783..a668410e3 100644 --- a/src/DotNet/Writer/PdbHeap.cs +++ b/src/DotNet/Writer/PdbHeap.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.IO; namespace dnlib.DotNet.Writer { /// diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index f7fe504e0..44a13fb15 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/StartupStub.cs b/src/DotNet/Writer/StartupStub.cs index 74aef7bb5..e46f26f4a 100644 --- a/src/DotNet/Writer/StartupStub.cs +++ b/src/DotNet/Writer/StartupStub.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index 9915537e5..03d091239 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -1,8 +1,7 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; -using System.IO; using dnlib.IO; using dnlib.DotNet.MD; using System.Diagnostics; diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index a6417e549..1802838bd 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 968d6f0b5..b7aab5c01 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.IO; using dnlib.IO; using dnlib.PE; using dnlib.DotNet.MD; diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 123b7df8c..82bdf1a34 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -1,9 +1,8 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Text; using dnlib.IO; using dnlib.PE; From 8aaa1250e0a17eb79fb705956cea7da9794e7c27 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:37:04 +0100 Subject: [PATCH 153/511] Use DataWriter, remove unnecessary casts --- src/DotNet/CpuArch.cs | 10 +- .../Portable/LocalConstantSigBlobWriter.cs | 24 ++--- .../PortablePdbCustomDebugInfoWriter.cs | 2 +- .../WindowsPdb/PdbCustomDebugInfoWriter.cs | 100 +++++++++--------- src/DotNet/Writer/BlobHeap.cs | 2 +- src/DotNet/Writer/Extensions.cs | 2 +- src/DotNet/Writer/ImportDirectory.cs | 4 +- src/DotNet/Writer/ManagedExportsWriter.cs | 2 +- src/DotNet/Writer/Metadata.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 2 +- src/DotNet/Writer/PESection.cs | 8 +- src/DotNet/Writer/RelocDirectory.cs | 2 +- src/DotNet/Writer/StringsHeap.cs | 4 +- src/DotNet/Writer/USHeap.cs | 2 +- 14 files changed, 83 insertions(+), 83 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index f072e7061..032b41b76 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -141,8 +141,8 @@ public override void WriteStub(StubType stubType, DataWriter writer, ulong image switch (stubType) { case StubType.Export: case StubType.EntryPoint: - writer.WriteUInt16((ushort)0);// padding - writer.WriteUInt16((ushort)0x25FF); + writer.WriteUInt16(0);// padding + writer.WriteUInt16(0x25FF); writer.WriteUInt32((uint)imageBase + managedFuncRva); break; default: @@ -214,10 +214,10 @@ public override void WriteStub(StubType stubType, DataWriter writer, ulong image switch (stubType) { case StubType.Export: case StubType.EntryPoint: - writer.WriteUInt16((ushort)0);// padding - writer.WriteUInt16((ushort)0xA148); + writer.WriteUInt16(0);// padding + writer.WriteUInt16(0xA148); writer.WriteUInt64(imageBase + managedFuncRva); - writer.WriteUInt16((ushort)0xE0FF); + writer.WriteUInt16(0xE0FF); break; default: throw new ArgumentOutOfRangeException(); diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index fb735705c..c1c6c3d4b 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -45,7 +45,7 @@ void Write(DataWriter writer, TypeSig type, object value) { writer.WriteSingle((float)value); else { helper.Error("Expected a Single constant"); - writer.WriteSingle((float)0); + writer.WriteSingle(0); } return; @@ -54,7 +54,7 @@ void Write(DataWriter writer, TypeSig type, object value) { writer.WriteDouble((double)value); else { helper.Error("Expected a Double constant"); - writer.WriteDouble((double)0); + writer.WriteDouble(0); } return; @@ -216,10 +216,10 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { case ElementType.Char: if (value is char) - writer.WriteUInt16((ushort)(char)value); + writer.WriteUInt16((char)value); else { helper.Error("Expected a Char constant"); - writer.WriteUInt16((ushort)0); + writer.WriteUInt16(0); } break; @@ -228,7 +228,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteSByte((sbyte)value); else { helper.Error("Expected a SByte constant"); - writer.WriteSByte((sbyte)0); + writer.WriteSByte(0); } break; @@ -237,7 +237,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteByte((byte)value); else { helper.Error("Expected a Byte constant"); - writer.WriteByte((byte)0); + writer.WriteByte(0); } break; @@ -246,7 +246,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteInt16((short)value); else { helper.Error("Expected an Int16 constant"); - writer.WriteInt16((short)0); + writer.WriteInt16(0); } break; @@ -255,7 +255,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteUInt16((ushort)value); else { helper.Error("Expected a UInt16 constant"); - writer.WriteUInt16((ushort)0); + writer.WriteUInt16(0); } break; @@ -264,7 +264,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteInt32((int)value); else { helper.Error("Expected an Int32 constant"); - writer.WriteInt32((int)0); + writer.WriteInt32(0); } break; @@ -273,7 +273,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteUInt32((uint)value); else { helper.Error("Expected a UInt32 constant"); - writer.WriteUInt32((uint)0); + writer.WriteUInt32(0); } break; @@ -282,7 +282,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteInt64((long)value); else { helper.Error("Expected an Int64 constant"); - writer.WriteInt64((long)0); + writer.WriteInt64(0); } break; @@ -291,7 +291,7 @@ void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { writer.WriteUInt64((ulong)value); else { helper.Error("Expected a UInt64 constant"); - writer.WriteUInt64((ulong)0); + writer.WriteUInt64(0); } break; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 6371b4454..1e4540f21 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -90,7 +90,7 @@ byte[] Write(PdbCustomDebugInfo cdi) { void WriteUTF8Z(string s) { var bytes = Encoding.UTF8.GetBytes(s); writer.WriteBytes(bytes); - writer.WriteByte((byte)0); + writer.WriteByte(0); } void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi) { diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs index 1b81aa873..03b5e8035 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs @@ -14,12 +14,12 @@ namespace dnlib.DotNet.Pdb.WindowsPdb { sealed class PdbCustomDebugInfoWriterContext { public ILogger Logger; public readonly MemoryStream MemoryStream; - public readonly BinaryWriter Writer; + public readonly DataWriter Writer; public readonly Dictionary InstructionToOffsetDict; public PdbCustomDebugInfoWriterContext() { MemoryStream = new MemoryStream(); - Writer = new BinaryWriter(MemoryStream); + Writer = new DataWriter(MemoryStream); InstructionToOffsetDict = new Dictionary(); } } @@ -33,7 +33,7 @@ struct PdbCustomDebugInfoWriter { readonly MethodDef method; readonly ILogger logger; readonly MemoryStream memoryStream; - readonly BinaryWriter writer; + readonly DataWriter writer; readonly Dictionary instructionToOffsetDict; uint bodySize; bool instructionToOffsetDictInitd; @@ -106,9 +106,9 @@ byte[] Write(IList customDebugInfos) { return null; } - writer.Write((byte)CustomDebugInfoConstants.Version); - writer.Write((byte)customDebugInfos.Count); - writer.Write((ushort)0); + writer.WriteByte(CustomDebugInfoConstants.Version); + writer.WriteByte((byte)customDebugInfos.Count); + writer.WriteUInt16(0); for (int i = 0; i < customDebugInfos.Count; i++) { var info = customDebugInfos[i]; @@ -121,11 +121,11 @@ byte[] Write(IList customDebugInfos) { return null; } - var recordPos = writer.BaseStream.Position; - writer.Write((byte)CustomDebugInfoConstants.RecordVersion); - writer.Write((byte)info.Kind); - writer.Write((ushort)0); - writer.Write((uint)0); + var recordPos = writer.Position; + writer.WriteByte(CustomDebugInfoConstants.RecordVersion); + writer.WriteByte((byte)info.Kind); + writer.WriteUInt16(0); + writer.WriteUInt32(0); int count, j, k; uint token; @@ -141,9 +141,9 @@ byte[] Write(IList customDebugInfos) { Error("UsingCounts contains more than 0xFFFF elements"); return null; } - writer.Write((ushort)count); + writer.WriteUInt16((ushort)count); for (j = 0; j < count; j++) - writer.Write(usingRec.UsingCounts[j]); + writer.WriteUInt16(usingRec.UsingCounts[j]); break; case PdbCustomDebugInfoKind.ForwardMethodInfo: @@ -155,7 +155,7 @@ byte[] Write(IList customDebugInfos) { token = GetMethodToken(fwdMethodRec.Method); if (token == 0) return null; - writer.Write(token); + writer.WriteUInt32(token); break; case PdbCustomDebugInfoKind.ForwardModuleInfo: @@ -167,7 +167,7 @@ byte[] Write(IList customDebugInfos) { token = GetMethodToken(fwdModRec.Method); if (token == 0) return null; - writer.Write(token); + writer.WriteUInt32(token); break; case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: @@ -177,16 +177,16 @@ byte[] Write(IList customDebugInfos) { return null; } count = smLocalScopesRec.Scopes.Count; - writer.Write(count); + writer.WriteInt32(count); for (j = 0; j < count; j++) { var scope = smLocalScopesRec.Scopes[j]; if (scope.IsSynthesizedLocal) { - writer.Write(0); - writer.Write(0); + writer.WriteInt32(0); + writer.WriteInt32(0); } else { - writer.Write(GetInstructionOffset(scope.Start, nullIsEndOfMethod: false)); - writer.Write(GetInstructionOffset(scope.End, nullIsEndOfMethod: true) - 1); + writer.WriteUInt32(GetInstructionOffset(scope.Start, nullIsEndOfMethod: false)); + writer.WriteUInt32(GetInstructionOffset(scope.End, nullIsEndOfMethod: true) - 1); } } break; @@ -212,7 +212,7 @@ byte[] Write(IList customDebugInfos) { return null; } count = dynLocListRec.Locals.Count; - writer.Write(count); + writer.WriteInt32(count); for (j = 0; j < count; j++) { var dynLoc = dynLocListRec.Locals[j]; if (dynLoc == null) { @@ -236,20 +236,20 @@ byte[] Write(IList customDebugInfos) { } for (k = 0; k < dynLoc.Flags.Count; k++) - writer.Write(dynLoc.Flags[k]); + writer.WriteByte(dynLoc.Flags[k]); while (k++ < 64) - writer.Write((byte)0); - writer.Write(dynLoc.Flags.Count); + writer.WriteByte(0); + writer.WriteInt32(dynLoc.Flags.Count); if (dynLoc.Local == null) - writer.Write(0); + writer.WriteInt32(0); else - writer.Write(dynLoc.Local.Index); + writer.WriteInt32(dynLoc.Local.Index); for (k = 0; k < name.Length; k++) - writer.Write((ushort)name[k]); + writer.WriteUInt16(name[k]); while (k++ < 64) - writer.Write((ushort)0); + writer.WriteUInt16(0); } break; @@ -259,7 +259,7 @@ byte[] Write(IList customDebugInfos) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } - writer.Write(encLocalMapRec.Data); + writer.WriteBytes(encLocalMapRec.Data); break; case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: @@ -268,7 +268,7 @@ byte[] Write(IList customDebugInfos) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } - writer.Write(encLambdaRec.Data); + writer.WriteBytes(encLambdaRec.Data); break; case PdbCustomDebugInfoKind.TupleElementNames: @@ -278,25 +278,25 @@ byte[] Write(IList customDebugInfos) { return null; } count = tupleListRec.Names.Count; - writer.Write(count); + writer.WriteInt32(count); for (j = 0; j < count; j++) { var tupleInfo = tupleListRec.Names[j]; if (tupleInfo == null) { Error("Tuple name info is null"); return null; } - writer.Write(tupleInfo.TupleElementNames.Count); + writer.WriteInt32(tupleInfo.TupleElementNames.Count); for (k = 0; k < tupleInfo.TupleElementNames.Count; k++) WriteUTF8Z(tupleInfo.TupleElementNames[k]); if (tupleInfo.Local == null) { - writer.Write(-1); - writer.Write(GetInstructionOffset(tupleInfo.ScopeStart, nullIsEndOfMethod: false)); - writer.Write(GetInstructionOffset(tupleInfo.ScopeEnd, nullIsEndOfMethod: true)); + writer.WriteInt32(-1); + writer.WriteUInt32(GetInstructionOffset(tupleInfo.ScopeStart, nullIsEndOfMethod: false)); + writer.WriteUInt32(GetInstructionOffset(tupleInfo.ScopeEnd, nullIsEndOfMethod: true)); } else { - writer.Write(tupleInfo.Local.Index); - writer.Write(0L); + writer.WriteInt32(tupleInfo.Local.Index); + writer.WriteInt64(0L); } WriteUTF8Z(tupleInfo.Name); } @@ -308,27 +308,27 @@ byte[] Write(IList customDebugInfos) { Error("Unsupported custom debug info class {0}", info.GetType()); return null; } - writer.Write(unkRec.Data); + writer.WriteBytes(unkRec.Data); break; } - var pos = writer.BaseStream.Position; + var pos = writer.Position; var recLen = (pos - recordPos); var alignedLen = (recLen + 3) & ~3; if (alignedLen > uint.MaxValue) { Error("Custom debug info record is too big"); return null; } - writer.BaseStream.Position = recordPos + 3; + writer.Position = recordPos + 3; if (info.Kind <= PdbCustomDebugInfoKind.DynamicLocals) - writer.Write((byte)0); + writer.WriteByte(0); else - writer.Write((byte)(alignedLen - recLen)); - writer.Write((uint)alignedLen); + writer.WriteByte((byte)(alignedLen - recLen)); + writer.WriteUInt32((uint)alignedLen); - writer.BaseStream.Position = pos; - while (writer.BaseStream.Position < recordPos + alignedLen) - writer.Write((byte)0); + writer.Position = pos; + while (writer.Position < recordPos + alignedLen) + writer.WriteByte(0); } return memoryStream.ToArray(); @@ -355,8 +355,8 @@ void WriteUnicodeZ(string s) { } for (int i = 0; i < s.Length; i++) - writer.Write((ushort)s[i]); - writer.Write((ushort)0); + writer.WriteUInt16(s[i]); + writer.WriteUInt16(0); } void WriteUTF8Z(string s) { @@ -370,8 +370,8 @@ void WriteUTF8Z(string s) { return; } - writer.Write(Encoding.UTF8.GetBytes(s)); - writer.Write((byte)0); + writer.WriteBytes(Encoding.UTF8.GetBytes(s)); + writer.WriteByte(0); } uint GetMethodToken(IMethodDefOrRef method) { diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index d20705ebf..952d0eca7 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -102,7 +102,7 @@ protected override void WriteToImpl(DataWriter writer) { if (originalData != null) writer.WriteBytes(originalData); else - writer.WriteByte((byte)0); + writer.WriteByte(0); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var data in cached) { diff --git a/src/DotNet/Writer/Extensions.cs b/src/DotNet/Writer/Extensions.cs index 320b7f83e..0723f1420 100644 --- a/src/DotNet/Writer/Extensions.cs +++ b/src/DotNet/Writer/Extensions.cs @@ -13,7 +13,7 @@ public static partial class Extensions { public static void WriteZeros(this DataWriter writer, int count) { if (count <= 0x20) { for (int i = 0; i < count; i++) - writer.WriteByte((byte)0); + writer.WriteByte(0); } else writer.WriteBytes(new byte[count]); diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index 7445e9617..fe22b990d 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -110,11 +110,11 @@ public void WriteTo(DataWriter writer) { } writer.WriteZeros(stringsPadding); - writer.WriteUInt16((ushort)0); + writer.WriteUInt16(0); writer.WriteBytes(Encoding.UTF8.GetBytes(IsExeFile ? "_CorExeMain\0" : "_CorDllMain\0")); writer.WriteBytes(Encoding.UTF8.GetBytes("mscoree.dll\0")); - writer.WriteByte((byte)0); + writer.WriteByte(0); } } } diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 143835f27..e432eca88 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -475,7 +475,7 @@ static void WriteZeroes(DataWriter writer, int count) { count -= 8; } for (int i = 0; i < count; i++) - writer.WriteByte((byte)0); + writer.WriteByte(0); } void WriteVtableFixups(DataWriter writer) { diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 64ec31e3a..9d01295d4 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3198,7 +3198,7 @@ uint GetDocumentNameBlobOffset(string name) { outStream.Position = 0; var parts = name.Split(directorySeparatorCharArray); if (parts.Length == 1) - writer.WriteByte((byte)0); + writer.WriteByte(0); else writer.WriteBytes(directorySeparatorCharUtf8); for (int i = 0; i < parts.Length; i++) { diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index aa9768286..37ac74217 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -898,7 +898,7 @@ static byte[] GetCodeViewData(Guid guid, uint age, string filename) { writer.WriteBytes(guid.ToByteArray()); writer.WriteUInt32(age); writer.WriteBytes(Encoding.UTF8.GetBytes(filename)); - writer.WriteByte((byte)0); + writer.WriteByte(0); return stream.ToArray(); } diff --git a/src/DotNet/Writer/PESection.cs b/src/DotNet/Writer/PESection.cs index 8bbbfe597..df7a44c98 100644 --- a/src/DotNet/Writer/PESection.cs +++ b/src/DotNet/Writer/PESection.cs @@ -69,13 +69,13 @@ public uint WriteHeaderTo(DataWriter writer, uint fileAlignment, uint sectionAli writer.WriteBytes(Encoding.UTF8.GetBytes(Name + "\0\0\0\0\0\0\0\0"), 0, 8); writer.WriteUInt32(vs); // VirtualSize - writer.WriteUInt32((uint)rva); // VirtualAddress - writer.WriteUInt32(rawSize); // SizeOfRawData + writer.WriteUInt32(rva); // VirtualAddress + writer.WriteUInt32(rawSize); // SizeOfRawData writer.WriteUInt32(dataOffset); // PointerToRawData writer.WriteInt32(0); // PointerToRelocations writer.WriteInt32(0); // PointerToLinenumbers - writer.WriteUInt16((ushort)0); // NumberOfRelocations - writer.WriteUInt16((ushort)0); // NumberOfLinenumbers + writer.WriteUInt16(0); // NumberOfRelocations + writer.WriteUInt16(0); // NumberOfLinenumbers writer.WriteUInt32(Characteristics); return alignedVs; diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index 44a13fb15..03c911a33 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -92,7 +92,7 @@ public void WriteTo(DataWriter writer) { foreach (var rva in pageList) writer.WriteUInt16((ushort)(relocType | (rva & 0xFFF))); if ((pageList.Count & 1) != 0) - writer.WriteUInt16((ushort)0); + writer.WriteUInt16(0); } } diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index 03d091239..a1909a11c 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -201,7 +201,7 @@ protected override void WriteToImpl(DataWriter writer) { if (originalData != null) writer.WriteBytes(originalData); else - writer.WriteByte((byte)0); + writer.WriteByte(0); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { @@ -212,7 +212,7 @@ protected override void WriteToImpl(DataWriter writer) { } else { writer.WriteBytes(s.Data); - writer.WriteByte((byte)0); + writer.WriteByte(0); } offset += (uint)s.Data.Length + 1; } diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index 717f21489..44d8e4087 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -106,7 +106,7 @@ protected override void WriteToImpl(DataWriter writer) { if (originalData != null) writer.WriteBytes(originalData); else - writer.WriteByte((byte)0); + writer.WriteByte(0); uint offset = originalData != null ? (uint)originalData.Length : 1; foreach (var s in cached) { From b2c63b0550c7321d2570ef61deee8ace34466894 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:37:15 +0100 Subject: [PATCH 154/511] Only call GetRid() if the member has CAs or CDIs --- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 2 +- src/DotNet/Writer/Metadata.cs | 93 ++++++++++++------- 2 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 946c5a0f5..92ccc8924 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -207,7 +207,7 @@ void Write(MethodDef method, List cdiBuilder) { var info = new CurrentMethod(this, method, instrToOffset); var body = method.Body; - var symbolToken = new SymbolToken((int)new MDToken(MD.Table.Method, metadata.GetRid(method)).Raw); + var symbolToken = new SymbolToken((int)new MDToken(MD.Table.Method, rid).Raw); writer.OpenMethod(symbolToken); seqPointsHelper.Write(this, info.Method.Body.Instructions); diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 9d01295d4..af04c927b 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -1517,44 +1517,57 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { if (type == null) continue; - rid = GetRid(type); - AddCustomAttributes(Table.TypeDef, rid, type); - AddCustomDebugInformationList(Table.TypeDef, rid, type); + if (type.HasCustomAttributes || type.HasCustomDebugInfos) { + rid = GetRid(type); + AddCustomAttributes(Table.TypeDef, rid, type); + AddCustomDebugInformationList(Table.TypeDef, rid, type); + } foreach (var field in type.Fields) { if (field == null) continue; - rid = GetRid(field); - AddCustomAttributes(Table.Field, rid, field); - AddCustomDebugInformationList(Table.Field, rid, field); + if (field.HasCustomAttributes || field.HasCustomDebugInfos) { + rid = GetRid(field); + AddCustomAttributes(Table.Field, rid, field); + AddCustomDebugInformationList(Table.Field, rid, field); + } } foreach (var method in type.Methods) { if (method == null) continue; - AddCustomAttributes(Table.Method, GetRid(method), method); - // Method custom debug info is added later when writing method bodies + if (method.HasCustomAttributes) { + rid = GetRid(method); + AddCustomAttributes(Table.Method, rid, method); + // Method custom debug info is added later when writing method bodies + } foreach (var pd in method.ParamDefs) { if (pd == null) continue; - rid = GetRid(pd); - AddCustomAttributes(Table.Param, rid, pd); - AddCustomDebugInformationList(Table.Param, rid, pd); + if (pd.HasCustomAttributes || pd.HasCustomDebugInfos) { + rid = GetRid(pd); + AddCustomAttributes(Table.Param, rid, pd); + AddCustomDebugInformationList(Table.Param, rid, pd); + } } } foreach (var evt in type.Events) { if (evt == null) continue; - rid = GetRid(evt); - AddCustomAttributes(Table.Event, rid, evt); - AddCustomDebugInformationList(Table.Event, rid, evt); + if (evt.HasCustomAttributes || evt.HasCustomDebugInfos) { + rid = GetRid(evt); + AddCustomAttributes(Table.Event, rid, evt); + AddCustomDebugInformationList(Table.Event, rid, evt); + } } foreach (var prop in type.Properties) { if (prop == null) continue; - rid = GetRid(prop); - AddCustomAttributes(Table.Property, rid, prop); - AddCustomDebugInformationList(Table.Property, rid, prop); + if (prop.HasCustomAttributes || prop.HasCustomDebugInfos) { + rid = GetRid(prop); + AddCustomAttributes(Table.Property, rid, prop); + AddCustomDebugInformationList(Table.Property, rid, prop); + } } } } @@ -1654,19 +1667,25 @@ void SortTables() { foreach (var info in nestedClassInfos.infos) tablesHeap.NestedClassTable.Create(info.row); foreach (var info in interfaceImplInfos.infos) { - uint rid = interfaceImplInfos.Rid(info.data); - AddCustomAttributes(Table.InterfaceImpl, rid, info.data); - AddCustomDebugInformationList(Table.InterfaceImpl, rid, info.data); + if (info.data.HasCustomAttributes || info.data.HasCustomDebugInfos) { + uint rid = interfaceImplInfos.Rid(info.data); + AddCustomAttributes(Table.InterfaceImpl, rid, info.data); + AddCustomDebugInformationList(Table.InterfaceImpl, rid, info.data); + } } foreach (var info in declSecurityInfos.infos) { - uint rid = declSecurityInfos.Rid(info.data); - AddCustomAttributes(Table.DeclSecurity, rid, info.data); - AddCustomDebugInformationList(Table.DeclSecurity, rid, info.data); + if (info.data.HasCustomAttributes || info.data.HasCustomDebugInfos) { + uint rid = declSecurityInfos.Rid(info.data); + AddCustomAttributes(Table.DeclSecurity, rid, info.data); + AddCustomDebugInformationList(Table.DeclSecurity, rid, info.data); + } } foreach (var info in genericParamInfos.infos) { - uint rid = genericParamInfos.Rid(info.data); - AddCustomAttributes(Table.GenericParam, rid, info.data); - AddCustomDebugInformationList(Table.GenericParam, rid, info.data); + if (info.data.HasCustomAttributes || info.data.HasCustomDebugInfos) { + uint rid = genericParamInfos.Rid(info.data); + AddCustomAttributes(Table.GenericParam, rid, info.data); + AddCustomDebugInformationList(Table.GenericParam, rid, info.data); + } } } @@ -1689,9 +1708,11 @@ void InitializeGenericParamConstraintTable() { foreach (var info in genericParamConstraintInfos.infos) tablesHeap.GenericParamConstraintTable.Create(info.row); foreach (var info in genericParamConstraintInfos.infos) { - uint rid = genericParamConstraintInfos.Rid(info.data); - AddCustomAttributes(Table.GenericParamConstraint, rid, info.data); - AddCustomDebugInformationList(Table.GenericParamConstraint, rid, info.data); + if (info.data.HasCustomAttributes || info.data.HasCustomDebugInfos) { + uint rid = genericParamConstraintInfos.Rid(info.data); + AddCustomAttributes(Table.GenericParamConstraint, rid, info.data); + AddCustomDebugInformationList(Table.GenericParamConstraint, rid, info.data); + } } } @@ -2664,12 +2685,14 @@ void AddMethodImpls(MethodDef method, IList overrides) { Error("Method declaring type == null. Method {0} ({1:X8})", method, method.MDToken.Raw); return; } - uint rid = GetRid(method.DeclaringType); - foreach (var ovr in overrides) { - var row = new RawMethodImplRow(rid, - AddMethodDefOrRef(ovr.MethodBody), - AddMethodDefOrRef(ovr.MethodDeclaration)); - methodImplInfos.Add(method, row); + if (overrides.Count != 0) { + uint rid = GetRid(method.DeclaringType); + foreach (var ovr in overrides) { + var row = new RawMethodImplRow(rid, + AddMethodDefOrRef(ovr.MethodBody), + AddMethodDefOrRef(ovr.MethodDeclaration)); + methodImplInfos.Add(method, row); + } } } From 3b08358c18d18b1e027871307c6de86f60d984b7 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:37:24 +0100 Subject: [PATCH 155/511] Use for loops --- src/DotNet/AssemblyDef.cs | 15 ++- src/DotNet/AssemblyResolver.cs | 8 +- src/DotNet/CustomAttribute.cs | 25 +++- src/DotNet/CustomAttributeReader.cs | 10 +- src/DotNet/Emit/DynamicMethodBodyReader.cs | 10 +- src/DotNet/Emit/LocalList.cs | 6 +- src/DotNet/Emit/MethodBodyReaderBase.cs | 49 ++++--- src/DotNet/Emit/MethodUtils.cs | 20 ++- src/DotNet/ExportedType.cs | 10 +- src/DotNet/FullNameCreator.cs | 16 ++- src/DotNet/MD/MDTable.cs | 21 +-- src/DotNet/MD/MetadataBase.cs | 4 +- src/DotNet/MD/TableInfo.cs | 8 +- src/DotNet/ParameterList.cs | 5 +- src/DotNet/Pdb/Managed/DbiFunction.cs | 6 +- src/DotNet/Pdb/Managed/DbiModule.cs | 4 +- src/DotNet/Pdb/Managed/PdbReader.cs | 4 +- src/DotNet/Pdb/PdbState.cs | 36 +++-- .../Pdb/Portable/ImportScopeBlobWriter.cs | 4 +- .../PortablePdbCustomDebugInfoWriter.cs | 15 ++- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 5 +- .../Pdb/Portable/SymbolReaderCreator.cs | 5 +- .../WindowsPdb/PdbCustomDebugInfoReader.cs | 19 +-- .../PseudoCustomDebugInfoFactory.cs | 4 +- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 47 +++++-- src/DotNet/Resolver.cs | 9 +- src/DotNet/SecurityAttribute.cs | 10 +- src/DotNet/TypeDef.cs | 125 +++++++++++++----- src/DotNet/TypeHelper.cs | 4 +- src/DotNet/TypeNameParser.cs | 4 +- src/DotNet/TypeSig.cs | 5 +- src/DotNet/Writer/DeclSecurityWriter.cs | 4 +- src/DotNet/Writer/MDTableWriter.cs | 2 +- src/DotNet/Writer/Metadata.cs | 121 ++++++++++++----- src/DotNet/Writer/MetadataHeader.cs | 10 +- src/DotNet/Writer/ModuleWriterBase.cs | 12 +- src/DotNet/Writer/NativeModuleWriter.cs | 5 +- src/DotNet/Writer/NormalMetadata.cs | 21 ++- src/DotNet/Writer/PreserveTokensMetadata.cs | 21 ++- src/DotNet/Writer/Win32ResourcesChunk.cs | 21 ++- 40 files changed, 533 insertions(+), 197 deletions(-) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index dc8ad258d..0a55a4cb4 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -336,7 +336,10 @@ public AssemblyAttributes ContentType { /// Name of module /// A instance or null if it wasn't found. public ModuleDef FindModule(UTF8String name) { - foreach (var module in Modules) { + var modules = Modules; + int count = modules.Count; + for (int i = 0; i < count; i++) { + var module = modules[i]; if (module == null) continue; if (UTF8String.CaseInsensitiveEquals(module.Name, name)) @@ -519,7 +522,10 @@ public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = nu /// are separated by a / character. /// An existing or null if it wasn't found. public TypeDef Find(string fullName, bool isReflectionName) { - foreach (var module in Modules) { + var modules = Modules; + int count = modules.Count; + for (int i = 0; i < count; i++) { + var module = modules[i]; if (module == null) continue; var type = module.Find(fullName, isReflectionName); @@ -537,7 +543,10 @@ public TypeDef Find(string fullName, bool isReflectionName) { /// The type ref /// An existing or null if it wasn't found. public TypeDef Find(TypeRef typeRef) { - foreach (var module in Modules) { + var modules = Modules; + int count = modules.Count; + for (int i = 0; i < count; i++) { + var module = modules[i]; if (module == null) continue; var type = module.Find(typeRef); diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 8401bdd58..9a0f6bc43 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -262,7 +262,10 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { if (asm1 != resolvedAssembly && asm2 != resolvedAssembly) { // This assembly was just resolved if (enableTypeDefCache) { - foreach (var module in resolvedAssembly.Modules) { + var modules = resolvedAssembly.Modules; + int count = modules.Count; + for (int i = 0; i < count; i++) { + var module = modules[i]; if (module != null) module.EnableTypeDefFindCache = true; } @@ -444,7 +447,8 @@ AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, Mod AssemblyDef FindClosestAssembly(IAssembly assembly) { AssemblyDef closest = null; var asmComparer = AssemblyNameComparer.CompareAll; - foreach (var asm in cachedAssemblies.Values) { + foreach (var kv in cachedAssemblies) { + var asm = kv.Value; if (asm == null) continue; if (asmComparer.CompareClosest(assembly, closest, asm) == 1) diff --git a/src/DotNet/CustomAttribute.cs b/src/DotNet/CustomAttribute.cs index 4043b48d1..8a363f45a 100644 --- a/src/DotNet/CustomAttribute.cs +++ b/src/DotNet/CustomAttribute.cs @@ -80,7 +80,10 @@ public string TypeFullName { /// public IEnumerable Fields { get { - foreach (var namedArg in namedArguments) { + var namedArguments = this.namedArguments; + int count = namedArguments.Count; + for (int i = 0; i < count; i++) { + var namedArg = namedArguments[i]; if (namedArg.IsField) yield return namedArg; } @@ -92,7 +95,10 @@ public IEnumerable Fields { /// public IEnumerable Properties { get { - foreach (var namedArg in namedArguments) { + var namedArguments = this.namedArguments; + int count = namedArguments.Count; + for (int i = 0; i < count; i++) { + var namedArg = namedArguments[i]; if (namedArg.IsProperty) yield return namedArg; } @@ -211,7 +217,10 @@ internal CustomAttribute(ICustomAttributeType ctor, List arguments, /// true if it's a field, false if it's a property /// A instance or null if not found public CANamedArgument GetNamedArgument(string name, bool isField) { - foreach (var namedArg in namedArguments) { + var namedArguments = this.namedArguments; + int count = namedArguments.Count; + for (int i = 0; i < count; i++) { + var namedArg = namedArguments[i]; if (namedArg.IsField == isField && UTF8String.ToSystemStringOrEmpty(namedArg.Name) == name) return namedArg; } @@ -225,7 +234,10 @@ public CANamedArgument GetNamedArgument(string name, bool isField) { /// true if it's a field, false if it's a property /// A instance or null if not found public CANamedArgument GetNamedArgument(UTF8String name, bool isField) { - foreach (var namedArg in namedArguments) { + var namedArguments = this.namedArguments; + int count = namedArguments.Count; + for (int i = 0; i < count; i++) { + var namedArg = namedArguments[i]; if (namedArg.IsField == isField && UTF8String.Equals(namedArg.Name, name)) return namedArg; } @@ -291,8 +303,11 @@ public CAArgument Clone() { value = ((CAArgument)value).Clone(); else if (value is IList args) { var newArgs = new List(args.Count); - foreach (var arg in args) + int count = args.Count; + for (int i = 0; i < count; i++) { + var arg = args[i]; newArgs.Add(arg.Clone()); + } value = newArgs; } return new CAArgument(type, value); diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 5545031b4..813cc0099 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -252,13 +252,15 @@ CustomAttribute Read(ICustomAttributeType ctor) { genericArguments.PushTypeArgs(gis.GenericArguments); } - bool isEmpty = methodSig.Params.Count == 0 && reader.Position == reader.Length; + var methodSigParams = methodSig.Params; + bool isEmpty = methodSigParams.Count == 0 && reader.Position == reader.Length; if (!isEmpty && reader.ReadUInt16() != 1) throw new CABlobParserException("Invalid CA blob prolog"); - var ctorArgs = new List(methodSig.Params.Count); - foreach (var arg in methodSig.Params) - ctorArgs.Add(ReadFixedArg(FixTypeSig(arg))); + var ctorArgs = new List(methodSigParams.Count); + int count = methodSigParams.Count; + for (int i = 0; i < count; i++) + ctorArgs.Add(ReadFixedArg(FixTypeSig(methodSigParams[i]))); // Some tools don't write the next ushort if there are no named arguments. int numNamedArgs = reader.Position == reader.Length ? 0 : reader.ReadUInt16(); diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index d4e224d6f..fba319f77 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -181,7 +181,9 @@ static List CreateExceptionInfos(IList ehInfos) { var infos = new List(ehInfos.Count); - foreach (var ehInfo in ehInfos) { + int count = ehInfos.Count; + for (int i = 0; i < count; i++) { + var ehInfo = ehInfos[i]; var eh = new ExceptionInfo { CatchAddr = (int[])ehCatchAddrFieldInfo.Read(ehInfo), CatchClass = (Type[])ehCatchClassFieldInfo.Read(ehInfo), @@ -206,8 +208,10 @@ void UpdateLocals(byte[] localsSig) { if (sig == null) return; - foreach (var local in sig.Locals) - locals.Add(new Local(local)); + var sigLocals = sig.Locals; + int count = sigLocals.Count; + for (int i = 0; i < count; i++) + locals.Add(new Local(sigLocals[i])); } MethodDef CreateMethodDef(SR.MethodBase delMethod) { diff --git a/src/DotNet/Emit/LocalList.cs b/src/DotNet/Emit/LocalList.cs index c6a68c06e..3a8aebf5b 100644 --- a/src/DotNet/Emit/LocalList.cs +++ b/src/DotNet/Emit/LocalList.cs @@ -42,10 +42,10 @@ public Local this[int index] { /// Constructor /// /// All locals that will be owned by this instance - public LocalList(IEnumerable locals) { + public LocalList(IList locals) { this.locals = new LazyList(this); - foreach (var local in locals) - this.locals.Add(local); + for (int i = 0; i < locals.Count; i++) + this.locals.Add(locals[i]); } /// diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index 27db4622b..c535004db 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -74,11 +74,13 @@ protected MethodBodyReaderBase(DataReader reader, IList parameters) { /// /// A list of types of all locals or null if none protected void SetLocals(IList newLocals) { + var locals = this.locals; locals.Clear(); if (newLocals == null) return; - foreach (var typeSig in newLocals) - locals.Add(new Local(typeSig)); + int count = newLocals.Count; + for (int i = 0; i < count; i++) + locals.Add(new Local(newLocals[i])); } /// @@ -86,11 +88,13 @@ protected void SetLocals(IList newLocals) { /// /// A list of types of all locals or null if none protected void SetLocals(IList newLocals) { + var locals = this.locals; locals.Clear(); if (newLocals == null) return; - foreach (var local in newLocals) - locals.Add(new Local(local.Type)); + int count = newLocals.Count; + for (int i = 0; i < count; i++) + locals.Add(new Local(newLocals[i].Type)); } /// @@ -100,8 +104,9 @@ protected void SetLocals(IList newLocals) { protected void ReadInstructions(int numInstrs) { codeStartOffs = reader.Position; codeEndOffs = reader.Length; // We don't know the end pos so use the last one - instructions = new List(numInstrs); + this.instructions = new List(numInstrs); currentOffset = 0; + var instructions = this.instructions; for (int i = 0; i < numInstrs && reader.Position < codeEndOffs; i++) instructions.Add(ReadOneInstruction()); FixBranches(); @@ -117,8 +122,9 @@ protected void ReadInstructionsNumBytes(uint codeSize) { if (codeEndOffs < codeStartOffs || codeEndOffs > reader.Length) throw new InvalidMethodException("Invalid code size"); - instructions = new List(); //TODO: Estimate number of instructions based on codeSize + this.instructions = new List(); //TODO: Estimate number of instructions based on codeSize currentOffset = 0; + var instructions = this.instructions; while (reader.Position < codeEndOffs) instructions.Add(ReadOneInstruction()); reader.Position = codeEndOffs; @@ -130,7 +136,10 @@ protected void ReadInstructionsNumBytes(uint codeSize) { /// instead of an offset. /// void FixBranches() { - foreach (var instr in instructions) { + var instructions = this.instructions; + int count = instructions.Count; + for (int i = 0; i < count; i++) { + var instr = instructions[i]; switch (instr.OpCode.OperandType) { case OperandType.InlineBrTarget: case OperandType.ShortInlineBrTarget: @@ -140,8 +149,8 @@ void FixBranches() { case OperandType.InlineSwitch: var uintTargets = (IList)instr.Operand; var targets = new Instruction[uintTargets.Count]; - for (int i = 0; i < uintTargets.Count; i++) - targets[i] = GetInstruction(uintTargets[i]); + for (int j = 0; j < uintTargets.Count; j++) + targets[j] = GetInstruction(uintTargets[j]); instr.Operand = targets; break; } @@ -155,6 +164,7 @@ void FixBranches() { /// The instruction or null if there's no instruction at . protected Instruction GetInstruction(uint offset) { // The instructions are sorted and all Offset fields are correct. Do a binary search. + var instructions = this.instructions; int lo = 0, hi = instructions.Count - 1; while (lo <= hi && hi != -1) { int i = (lo + hi) / 2; @@ -444,6 +454,7 @@ protected static bool IsArgOperandInstruction(Instruction instr) { /// A parameter index /// A or null if is invalid protected Parameter GetParameter(int index) { + var parameters = this.parameters; if ((uint)index < (uint)parameters.Count) return parameters[index]; return null; @@ -455,6 +466,7 @@ protected Parameter GetParameter(int index) { /// A local index /// A or null if is invalid protected Local GetLocal(int index) { + var locals = this.locals; if ((uint)index < (uint)locals.Count) return locals[index]; return null; @@ -507,6 +519,7 @@ protected bool Add(ExceptionHandler eh) { uint GetOffset(Instruction instr) { if (instr != null) return instr.Offset; + var instructions = this.instructions; if (instructions.Count == 0) return 0; return instructions[instructions.Count - 1].Offset; @@ -522,21 +535,27 @@ public virtual void RestoreMethod(MethodDef method) { var body = method.Body; body.Variables.Clear(); + var locals = this.locals; if (locals != null) { - foreach (var local in locals) - body.Variables.Add(local); + int count = locals.Count; + for (int i = 0; i < count; i++) + body.Variables.Add(locals[i]); } body.Instructions.Clear(); + var instructions = this.instructions; if (instructions != null) { - foreach (var instr in instructions) - body.Instructions.Add(instr); + int count = instructions.Count; + for (int i = 0; i < count; i++) + body.Instructions.Add(instructions[i]); } body.ExceptionHandlers.Clear(); + var exceptionHandlers = this.exceptionHandlers; if (exceptionHandlers != null) { - foreach (var eh in exceptionHandlers) - body.ExceptionHandlers.Add(eh); + int count = exceptionHandlers.Count; + for (int i = 0; i < count; i++) + body.ExceptionHandlers.Add(exceptionHandlers[i]); } } } diff --git a/src/DotNet/Emit/MethodUtils.cs b/src/DotNet/Emit/MethodUtils.cs index 1b2426341..5a018ed88 100644 --- a/src/DotNet/Emit/MethodUtils.cs +++ b/src/DotNet/Emit/MethodUtils.cs @@ -16,7 +16,9 @@ public static class MethodUtils { /// All method parameters, including the hidden 'this' parameter /// if it's an instance method. Use . public static void SimplifyMacros(this IList instructions, IList locals, IList parameters) { - foreach (var instr in instructions) { + int count = instructions.Count; + for (int i = 0; i < count; i++) { + var instr = instructions[i]; switch (instr.OpCode.Code) { case Code.Beq_S: instr.OpCode = OpCodes.Beq; @@ -230,7 +232,9 @@ static T ReadList(IList list, int index) { /// /// All instructions public static void OptimizeMacros(this IList instructions) { - foreach (var instr in instructions) { + int count = instructions.Count; + for (int i = 0; i < count; i++) { + var instr = instructions[i]; Parameter arg; Local local; switch (instr.OpCode.Code) { @@ -413,7 +417,9 @@ public static void OptimizeMacros(this IList instructions) { /// /// All instructions public static void SimplifyBranches(this IList instructions) { - foreach (var instr in instructions) { + int count = instructions.Count; + for (int i = 0; i < count; i++) { + var instr = instructions[i]; switch (instr.OpCode.Code) { case Code.Beq_S: instr.OpCode = OpCodes.Beq; break; case Code.Bge_S: instr.OpCode = OpCodes.Bge; break; @@ -442,7 +448,9 @@ public static void OptimizeBranches(this IList instructions) { UpdateInstructionOffsets(instructions); bool modified = false; - foreach (var instr in instructions) { + int count = instructions.Count; + for (int i = 0; i < count; i++) { + var instr = instructions[i]; OpCode shortOpCode; switch (instr.OpCode.Code) { case Code.Beq: shortOpCode = OpCodes.Beq_S; break; @@ -496,7 +504,9 @@ public static void OptimizeBranches(this IList instructions) { /// Total size in bytes of all instructions public static uint UpdateInstructionOffsets(this IList instructions) { uint offset = 0; - foreach (var instr in instructions) { + int count = instructions.Count; + for (int i = 0; i < count; i++) { + var instr = instructions[i]; instr.Offset = offset; offset += (uint)instr.GetSize(); } diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 3b2fba252..bb6ed505c 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -520,8 +520,14 @@ static TypeDef Resolve(ModuleDef sourceModule, ExportedType et) { } static ExportedType FindExportedType(AssemblyDef asm, ExportedType et) { - foreach (var mod in asm.Modules) { - foreach (var et2 in mod.ExportedTypes) { + var modules = asm.Modules; + int count = modules.Count; + for (int i = 0; i < count; i++) { + var mod = modules[i]; + var exportedTypes = mod.ExportedTypes; + int count2 = exportedTypes.Count; + for (int j = 0; j < count2; j++) { + var et2 = exportedTypes[j]; if (new SigComparer(SigComparerOptions.DontCompareTypeScope).Equals(et, et2)) return et2; } diff --git a/src/DotNet/FullNameCreator.cs b/src/DotNet/FullNameCreator.cs index 7f07fb03e..82eeaaed4 100644 --- a/src/DotNet/FullNameCreator.cs +++ b/src/DotNet/FullNameCreator.cs @@ -1391,7 +1391,9 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { if (isReflection) { sb.Append('['); int i = -1; - foreach (var genArg in typeGenArgs) { + int count = typeGenArgs.Count; + for (int j = 0; j < count; j++) { + var genArg = typeGenArgs[j]; i++; if (i != 0) sb.Append(','); @@ -1417,7 +1419,9 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { else { sb.Append('<'); int i = -1; - foreach (var genArg in typeGenArgs) { + int count = typeGenArgs.Count; + for (int j = 0; j < count; j++) { + var genArg = typeGenArgs[j]; i++; if (i != 0) sb.Append(','); @@ -1529,6 +1533,8 @@ static string EscapeAssemblyName(UTF8String asmSimplName) => EscapeAssemblyName(UTF8String.ToSystemString(asmSimplName)); static string EscapeAssemblyName(string asmSimplName) { + if (asmSimplName.IndexOf(']') < 0) + return asmSimplName; var sb = new StringBuilder(asmSimplName.Length); foreach (var c in asmSimplName) { if (c == ']') @@ -2124,7 +2130,7 @@ void CreateMethodFullName(string declaringType, string name, MethodBaseSig metho sb.Append(')'); } - int PrintMethodArgList(IEnumerable args, bool hasPrintedArgs, bool isAfterSentinel) { + int PrintMethodArgList(IList args, bool hasPrintedArgs, bool isAfterSentinel) { if (args == null) return 0; if (isAfterSentinel) { @@ -2134,7 +2140,9 @@ int PrintMethodArgList(IEnumerable args, bool hasPrintedArgs, bool isAf hasPrintedArgs = true; } int count = 0; - foreach (var arg in args) { + int argsCount = args.Count; + for (int i = 0; i < argsCount; i++) { + var arg = args[i]; count++; if (hasPrintedArgs) sb.Append(','); diff --git a/src/DotNet/MD/MDTable.cs b/src/DotNet/MD/MDTable.cs index 14c575911..a7bcdf68b 100644 --- a/src/DotNet/MD/MDTable.cs +++ b/src/DotNet/MD/MDTable.cs @@ -17,7 +17,7 @@ public sealed class MDTable : IDisposable, IFileSection { DataReader dataReader; // Fix for VS2015 expression evaluator: "The debugger is unable to evaluate this expression" - int Count => tableInfo.Columns.Count; + int Count => tableInfo.Columns.Length; /// public FileOffset StartOffset => (FileOffset)dataReader.StartOffset; @@ -77,15 +77,16 @@ internal MDTable(Table table, uint numRows, TableInfo tableInfo) { this.tableInfo = tableInfo; var columns = tableInfo.Columns; - if (columns.Count > 0) Column0 = columns[0]; - if (columns.Count > 1) Column1 = columns[1]; - if (columns.Count > 2) Column2 = columns[2]; - if (columns.Count > 3) Column3 = columns[3]; - if (columns.Count > 4) Column4 = columns[4]; - if (columns.Count > 5) Column5 = columns[5]; - if (columns.Count > 6) Column6 = columns[6]; - if (columns.Count > 7) Column7 = columns[7]; - if (columns.Count > 8) Column8 = columns[8]; + int length = columns.Length; + if (length > 0) Column0 = columns[0]; + if (length > 1) Column1 = columns[1]; + if (length > 2) Column2 = columns[2]; + if (length > 3) Column3 = columns[3]; + if (length > 4) Column4 = columns[4]; + if (length > 5) Column5 = columns[5]; + if (length > 6) Column6 = columns[6]; + if (length > 7) Column7 = columns[7]; + if (length > 8) Column8 = columns[8]; } // So we don't have to call IList indexer diff --git a/src/DotNet/MD/MetadataBase.cs b/src/DotNet/MD/MetadataBase.cs index abd9f86a6..36dc8866c 100644 --- a/src/DotNet/MD/MetadataBase.cs +++ b/src/DotNet/MD/MetadataBase.cs @@ -675,7 +675,9 @@ void InitializeNestedClassesDictionary() { } var newTypeDefRidToNestedClasses = new Dictionary>(); - foreach (var nestedRid in nestedRids) { + int count = nestedRids.Count; + for (int i = 0; i < count; i++) { + var nestedRid = nestedRids[i]; if (!tablesStream.TryReadNestedClassRow(GetNestedClassRid(nestedRid), out var row)) continue; if (!newTypeDefRidToNestedClasses.TryGetValue(row.EnclosingClass, out var ridList)) diff --git a/src/DotNet/MD/TableInfo.cs b/src/DotNet/MD/TableInfo.cs index 3171533fd..999e10824 100644 --- a/src/DotNet/MD/TableInfo.cs +++ b/src/DotNet/MD/TableInfo.cs @@ -11,7 +11,7 @@ namespace dnlib.DotNet.MD { public sealed class TableInfo { readonly Table table; int rowSize; - readonly IList columns; + readonly ColumnInfo[] columns; readonly string name; /// @@ -30,7 +30,7 @@ public int RowSize { /// /// Returns all the columns /// - public IList Columns => columns; + public ColumnInfo[] Columns => columns; /// /// Returns the name of the table @@ -43,7 +43,7 @@ public int RowSize { /// Table type /// Table name /// All columns - public TableInfo(Table table, string name, IList columns) { + public TableInfo(Table table, string name, ColumnInfo[] columns) { this.table = table; this.name = name; this.columns = columns; @@ -56,7 +56,7 @@ public TableInfo(Table table, string name, IList columns) { /// Table name /// All columns /// Row size - public TableInfo(Table table, string name, IList columns, int rowSize) { + public TableInfo(Table table, string name, ColumnInfo[] columns, int rowSize) { this.table = table; this.name = name; this.columns = columns; diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index 04f4d68e8..d76b7b278 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -197,7 +197,10 @@ ParamDef FindParamDef_NoLock(Parameter param) { else return hiddenThisParamDef; - foreach (var paramDef in method.ParamDefs) { + var paramDefs = method.ParamDefs; + int count = paramDefs.Count; + for (int i = 0; i < count; i++) { + var paramDef = paramDefs[i]; if (paramDef != null && paramDef.Sequence == seq) return paramDef; } diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index a64c63b81..2a0973b7c 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -45,8 +45,10 @@ void FixOffsets(RecursionCounter counter, DbiScope scope) { scope.startOffset -= (int)Address.Offset; scope.endOffset -= (int)Address.Offset; - foreach (var child in scope.Children) - FixOffsets(counter, (DbiScope)child); + var children = scope.Children; + int count = children.Count; + for (int i = 0; i < count; i++) + FixOffsets(counter, (DbiScope)children[i]); counter.Decrement(); } diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index d42fa9e3a..df5a25119 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -20,8 +20,8 @@ public DbiModule() { public string ModuleName { get; private set; } public string ObjectName { get; private set; } - public IList Functions { get; private set; } - public IList Documents { get; private set; } + public List Functions { get; private set; } + public List Documents { get; private set; } public void Read(ref DataReader reader) { reader.Position += 34; diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 9a45c917c..2519b8eac 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -307,8 +307,8 @@ public override IList Documents { if (documentsResult == null) { var docs = new SymbolDocument[documents.Count]; int i = 0; - foreach (var doc in documents.Values) - docs[i++] = doc; + foreach (var kv in documents) + docs[i++] = kv.Value; documentsResult = docs; } return documentsResult; diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index b82b93ea5..787ba2a19 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -94,8 +94,10 @@ public PdbState(SymbolReader reader, ModuleDefMD module) { userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; - foreach (var doc in reader.Documents) - Add_NoLock(new PdbDocument(doc)); + var documents = reader.Documents; + int count = documents.Count; + for (int i = 0; i < count; i++) + Add_NoLock(new PdbDocument(documents[i])); } /// @@ -223,7 +225,10 @@ static Compiler CalculateCompiler(ModuleDef module) { void AddSequencePoints(CilBody body, SymbolMethod method) { int instrIndex = 0; - foreach (var sp in method.SequencePoints) { + var sequencePoints = method.SequencePoints; + int count = sequencePoints.Count; + for (int i = 0; i < count; i++) { + var sp = sequencePoints[i]; var instr = GetInstruction(body.Instructions, sp.Offset, ref instrIndex); if (instr == null) continue; @@ -259,10 +264,15 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), }; - foreach (var cdi in state.SymScope.CustomDebugInfos) - state.PdbScope.CustomDebugInfos.Add(cdi); - - foreach (var symLocal in state.SymScope.Locals) { + var cdis = state.SymScope.CustomDebugInfos; + int count = cdis.Count; + for (int i = 0; i < count; i++) + state.PdbScope.CustomDebugInfos.Add(cdis[i]); + + var locals = state.SymScope.Locals; + count = locals.Count; + for (int i = 0; i < count; i++) { + var symLocal = locals[i]; int localIndex = symLocal.Index; if ((uint)localIndex >= (uint)body.Variables.Count) { // VB sometimes creates a PDB local without a metadata local @@ -274,13 +284,17 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody var attributes = symLocal.Attributes; local.SetAttributes(attributes); var pdbLocal = new PdbLocal(local, name, attributes); - foreach (var cdi in symLocal.CustomDebugInfos) - pdbLocal.CustomDebugInfos.Add(cdi); + cdis = symLocal.CustomDebugInfos; + int count2 = cdis.Count; + for (int j = 0; j < count2; j++) + pdbLocal.CustomDebugInfos.Add(cdis[j]); state.PdbScope.Variables.Add(pdbLocal); } - foreach (var ns in state.SymScope.Namespaces) - state.PdbScope.Namespaces.Add(ns.Name); + var namespaces = state.SymScope.Namespaces; + count = namespaces.Count; + for (int i = 0; i < count; i++) + state.PdbScope.Namespaces.Add(namespaces[i].Name); state.PdbScope.ImportScope = state.SymScope.ImportScope; var constants = state.SymScope.GetConstants(module, gpContext); diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index ed264e376..f249cd144 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -32,7 +32,9 @@ uint WriteUTF8(string s) { } void Write(DataWriter writer, IList imports) { - foreach (var import in imports) { + int count = imports.Count; + for (int i = 0; i < count; i++) { + var import = imports[i]; if (!ImportDefinitionKindUtils.ToImportDefinitionKind(import.Kind, out uint rawKind)) { helper.Error("Unknown import definition kind: " + import.Kind.ToString()); return; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 1e4540f21..15e671768 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -98,7 +98,10 @@ void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustom helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind); return; } - foreach (var scope in cdi.Scopes) { + var cdiScopes = cdi.Scopes; + int count = cdiScopes.Count; + for (int i = 0; i < count; i++) { + var scope = cdiScopes[i]; uint startOffset, endOffset; if (scope.IsSynthesizedLocal) { startOffset = 0; @@ -150,7 +153,10 @@ void WriteUnknown(PdbUnknownCustomDebugInfo cdi) { } void WriteTupleElementNames(PortablePdbTupleElementNamesCustomDebugInfo cdi) { - foreach (var name in cdi.Names) { + var cdiNames = cdi.Names; + int count = cdiNames.Count; + for (int i = 0; i < count; i++) { + var name = cdiNames[i]; if (name == null) { helper.Error("Tuple name is null"); return; @@ -216,7 +222,10 @@ void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { catchHandlerOffset = methodContext.GetOffset(cdi.CatchHandlerInstruction) + 1; writer.WriteUInt32(catchHandlerOffset); - foreach (var info in cdi.StepInfos) { + var cdiStepInfos = cdi.StepInfos; + int count = cdiStepInfos.Count; + for (int i = 0; i < count; i++) { + var info = cdiStepInfos[i]; if (info.YieldInstruction == null) { helper.Error("YieldInstruction is null"); return; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index b0ab96792..fd5a9d347 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -353,8 +353,9 @@ PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef module, int asyncKi var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); asyncMethod.KickoffMethod = module.ResolveToken(kickoffToken) as MethodDef; asyncMethod.CatchHandlerInstruction = asyncCatchHandler; - foreach (var info in asyncStepInfos) - asyncMethod.StepInfos.Add(info); + int count = asyncStepInfos.Count; + for (int i = 0; i < count; i++) + asyncMethod.StepInfos.Add(asyncStepInfos[i]); return asyncMethod; } diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index f90413fe3..38a93c8e8 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -67,7 +67,10 @@ public static SymbolReader TryCreate(Metadata metadata) { } static ImageDebugDirectory TryGetEmbeddedDebugDirectory(IPEImage peImage) { - foreach (var idd in peImage.ImageDebugDirectories) { + var dirs = peImage.ImageDebugDirectories; + int count = dirs.Count; + for (int i = 0; i < count; i++) { + var idd = dirs[i]; if (idd.Type == ImageDebugType.EmbeddedPortablePdb) return idd; } diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index 5d8c981c7..dbbb8cf37 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -271,23 +271,26 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { TypeDef GetNestedType(string name) { if (typeOpt == null) return null; - foreach (var type in typeOpt.NestedTypes) { + var nestedTypes = typeOpt.NestedTypes; + int count = nestedTypes.Count; + for (int i = 0; i < count; i++) { + var type = nestedTypes[i]; if (UTF8String.IsNullOrEmpty(type.Namespace)) { if (type.Name == name) return type; var typeName = type.Name.String; if (typeName.StartsWith(name) && typeName.Length >= name.Length + 2) { - int i = name.Length; - if (typeName[i] == '`') { - Debug.Assert(i + 1 < typeName.Length); + int index = name.Length; + if (typeName[index] == '`') { + Debug.Assert(index + 1 < typeName.Length); bool ok = true; - i++; - while (i < typeName.Length) { - if (!char.IsDigit(typeName[i])) { + index++; + while (index < typeName.Length) { + if (!char.IsDigit(typeName[index])) { ok = false; break; } - i++; + index++; } if (ok) return type; diff --git a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs index a52c3c7d2..edbc17748 100644 --- a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs +++ b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs @@ -22,7 +22,9 @@ public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef modul Debug.Assert(asyncMethod.CatchHandlerInstruction != null); } - foreach (var rawInfo in asyncStepInfos) { + int count = asyncStepInfos.Count; + for (int i = 0; i < count; i++) { + var rawInfo = asyncStepInfos[i]; var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); Debug.Assert(yieldInstruction != null); if (yieldInstruction == null) diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 92ccc8924..b4d7d8184 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -77,7 +77,10 @@ public void Write() { foreach (var type in module.GetTypes()) { if (type == null) continue; - foreach (var method in type.Methods) { + var typeMethods = type.Methods; + int count = typeMethods.Count; + for (int i = 0; i < count; i++) { + var method = typeMethods[i]; if (method == null) continue; if (!ShouldAddMethod(method)) @@ -95,7 +98,10 @@ bool ShouldAddMethod(MethodDef method) { if (body.HasPdbMethod) return true; - foreach (var local in body.Variables) { + var bodyVariables = body.Variables; + int count = bodyVariables.Count; + for (int i = 0; i < count; i++) { + var local = bodyVariables[i]; // Don't check whether it's the empty string. Only check for null. if (local.Name != null) return true; @@ -103,8 +109,10 @@ bool ShouldAddMethod(MethodDef method) { return true; } - foreach (var instr in body.Instructions) { - if (instr.SequencePoint != null) + var bodyInstructions = body.Instructions; + count = bodyInstructions.Count; + for (int i = 0; i < count; i++) { + if (bodyInstructions[i].SequencePoint != null) return true; } @@ -181,7 +189,10 @@ public CurrentMethod(WindowsPdbWriter pdbWriter, MethodDef method, Dictionary cdiBuilder) { writer.CloseScope((int)info.BodySize); } else { - foreach (var childScope in scope.Scopes) - WriteScope(ref info, childScope, 0); + var scopes = scope.Scopes; + int count = scopes.Count; + for (int i = 0; i < count; i++) + WriteScope(ref info, scopes[i], 0); } } else { @@ -256,7 +269,9 @@ void Write(MethodDef method, List cdiBuilder) { void GetPseudoCustomDebugInfos(IList customDebugInfos, List cdiBuilder, out PdbAsyncMethodCustomDebugInfo asyncMethod) { cdiBuilder.Clear(); asyncMethod = null; - foreach (var cdi in customDebugInfos) { + int count = customDebugInfos.Count; + for (int i = 0; i < count; i++) { + var cdi = customDebugInfos[i]; switch (cdi.Kind) { case PdbCustomDebugInfoKind.AsyncMethod: if (asyncMethod != null) @@ -364,10 +379,14 @@ void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { writer.DefineConstant2(constant.Name, constant.Value ?? 0, token.Raw); } } - foreach (var ns in scope.Namespaces) - writer.UsingNamespace(ns); - foreach (var childScope in scope.Scopes) - WriteScope(ref info, childScope, recursionCounter + 1); + var scopeNamespaces = scope.Namespaces; + int count = scopeNamespaces.Count; + for (int i = 0; i < count; i++) + writer.UsingNamespace(scopeNamespaces[i]); + var scopes = scope.Scopes; + count = scopes.Count; + for (int i = 0; i < count; i++) + WriteScope(ref info, scopes[i], recursionCounter + 1); writer.CloseScope(startOffset == 0 && endOffset == info.BodySize ? endOffset : endOffset - localsEndScopeIncValue); } @@ -379,7 +398,9 @@ void AddLocals(MethodDef method, IList locals, uint startOffset, uint Error("Method {0} ({1:X8}) has no local signature token", method, method.MDToken.Raw); return; } - foreach (var local in locals) { + int count = locals.Count; + for (int i = 0; i < count; i++) { + var local = locals[i]; uint attrs = GetPdbLocalFlags(local.Attributes); if (attrs == 0 && local.Name == null) continue; diff --git a/src/DotNet/Resolver.cs b/src/DotNet/Resolver.cs index 03723321f..9a5fb6624 100644 --- a/src/DotNet/Resolver.cs +++ b/src/DotNet/Resolver.cs @@ -91,8 +91,13 @@ TypeDef ResolveExportedType(IList modules, TypeRef typeRef, ModuleDef static ExportedType FindExportedType(IList modules, TypeRef typeRef) { if (typeRef == null) return null; - foreach (var module in modules) { - foreach (var exportedType in module.ExportedTypes) { + int count = modules.Count; + for (int i = 0; i < count; i++) { + var module = modules[i]; + var exportedTypes = module.ExportedTypes; + int count2 = exportedTypes.Count; + for (int j = 0; j < count2; j++) { + var exportedType = exportedTypes[j]; if (new SigComparer(SigComparerOptions.DontCompareTypeScope).Equals(exportedType, typeRef)) return exportedType; } diff --git a/src/DotNet/SecurityAttribute.cs b/src/DotNet/SecurityAttribute.cs index 112b00f74..19db0ae8b 100644 --- a/src/DotNet/SecurityAttribute.cs +++ b/src/DotNet/SecurityAttribute.cs @@ -43,7 +43,10 @@ public string TypeFullName { /// public IEnumerable Fields { get { - foreach (var namedArg in namedArguments) { + var namedArguments = this.namedArguments; + int count = namedArguments.Count; + for (int i = 0; i < count; i++) { + var namedArg = namedArguments[i]; if (namedArg.IsField) yield return namedArg; } @@ -55,7 +58,10 @@ public IEnumerable Fields { /// public IEnumerable Properties { get { - foreach (var namedArg in namedArguments) { + var namedArguments = this.namedArguments; + int count = namedArguments.Count; + for (int i = 0; i < count; i++) { + var namedArg = namedArguments[i]; if (namedArg.IsProperty) yield return namedArg; } diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 96fb4826b..867aabda2 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -907,7 +907,10 @@ public bool IsGlobalModuleType { /// if this is an enum. /// public TypeSig GetEnumUnderlyingType() { - foreach (var field in Fields) { + var fields = Fields; + int count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (!field.IsLiteral && !field.IsStatic) { var fieldSig = field.FieldSig; if (fieldSig != null) @@ -979,7 +982,10 @@ public MethodDef FindMethod(UTF8String name, MethodSig sig, SigComparerOptions o return null; var comparer = new SigComparer(options, sourceModule); bool allowPrivateScope = (options & SigComparerOptions.PrivateScopeMethodIsComparable) != 0; - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (!allowPrivateScope && method.IsPrivateScope) continue; if (!UTF8String.Equals(method.Name, name)) @@ -996,7 +1002,10 @@ public MethodDef FindMethod(UTF8String name, MethodSig sig, SigComparerOptions o /// Name of method /// The or null if not found public MethodDef FindMethod(UTF8String name) { - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (UTF8String.Equals(method.Name, name)) return method; } @@ -1009,7 +1018,10 @@ public MethodDef FindMethod(UTF8String name) { /// Name of method /// All methods with that name public IEnumerable FindMethods(UTF8String name) { - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (UTF8String.Equals(method.Name, name)) yield return method; } @@ -1020,7 +1032,10 @@ public IEnumerable FindMethods(UTF8String name) { /// /// The class constructor or null if none found public MethodDef FindStaticConstructor() { - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method.IsStaticConstructor) return method; } @@ -1059,7 +1074,10 @@ public MethodDef FindOrCreateStaticConstructor() { /// /// All instance constructors public IEnumerable FindInstanceConstructors() { - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method.IsInstanceConstructor) yield return method; } @@ -1070,7 +1088,10 @@ public IEnumerable FindInstanceConstructors() { /// /// All static and instance constructors public IEnumerable FindConstructors() { - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method.IsConstructor) yield return method; } @@ -1081,7 +1102,10 @@ public IEnumerable FindConstructors() { /// /// The default instance constructor or null if none public MethodDef FindDefaultConstructor() { - foreach (var method in Methods) { + var methods = Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (!method.IsInstanceConstructor) continue; var sig = method.MethodSig; @@ -1121,7 +1145,10 @@ public FieldDef FindField(UTF8String name, FieldSig sig, SigComparerOptions opti return null; var comparer = new SigComparer(options, sourceModule); bool allowPrivateScope = (options & SigComparerOptions.PrivateScopeFieldIsComparable) != 0; - foreach (var field in Fields) { + var fields = Fields; + int count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (!allowPrivateScope && field.IsPrivateScope) continue; if (!UTF8String.Equals(field.Name, name)) @@ -1138,7 +1165,10 @@ public FieldDef FindField(UTF8String name, FieldSig sig, SigComparerOptions opti /// Name of field /// The or null if not found public FieldDef FindField(UTF8String name) { - foreach (var field in Fields) { + var fields = Fields; + int count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (UTF8String.Equals(field.Name, name)) return field; } @@ -1151,7 +1181,10 @@ public FieldDef FindField(UTF8String name) { /// Name of field /// All fields with that name public IEnumerable FindFields(UTF8String name) { - foreach (var field in Fields) { + var fields = Fields; + int count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (UTF8String.Equals(field.Name, name)) yield return field; } @@ -1186,7 +1219,10 @@ public EventDef FindEvent(UTF8String name, IType type, SigComparerOptions option if (UTF8String.IsNull(name) || type == null) return null; var comparer = new SigComparer(options, sourceModule); - foreach (var @event in Events) { + var events = Events; + int count = events.Count; + for (int i = 0; i < count; i++) { + var @event = events[i]; if (!UTF8String.Equals(@event.Name, name)) continue; if (comparer.Equals(@event.EventType, type)) @@ -1201,7 +1237,10 @@ public EventDef FindEvent(UTF8String name, IType type, SigComparerOptions option /// Name of event /// The or null if not found public EventDef FindEvent(UTF8String name) { - foreach (var @event in Events) { + var events = Events; + int count = events.Count; + for (int i = 0; i < count; i++) { + var @event = events[i]; if (UTF8String.Equals(@event.Name, name)) return @event; } @@ -1214,7 +1253,10 @@ public EventDef FindEvent(UTF8String name) { /// Name of event /// All events with that name public IEnumerable FindEvents(UTF8String name) { - foreach (var @event in Events) { + var events = Events; + int count = events.Count; + for (int i = 0; i < count; i++) { + var @event = events[i]; if (UTF8String.Equals(@event.Name, name)) yield return @event; } @@ -1249,7 +1291,10 @@ public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig, S if (UTF8String.IsNull(name) || propSig == null) return null; var comparer = new SigComparer(options, sourceModule); - foreach (var prop in Properties) { + var properties = Properties; + int count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (!UTF8String.Equals(prop.Name, name)) continue; if (comparer.Equals(prop.Type, propSig)) @@ -1264,7 +1309,10 @@ public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig, S /// Name of prop /// The or null if not found public PropertyDef FindProperty(UTF8String name) { - foreach (var prop in Properties) { + var properties = Properties; + int count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (UTF8String.Equals(prop.Name, name)) return prop; } @@ -1277,7 +1325,10 @@ public PropertyDef FindProperty(UTF8String name) { /// Name of prop /// All props with that name public IEnumerable FindProperties(UTF8String name) { - foreach (var prop in Properties) { + var properties = Properties; + int count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (UTF8String.Equals(prop.Name, name)) yield return prop; } @@ -1488,13 +1539,19 @@ public void Remove(MethodDef method, bool removeEmptyPropertiesEvents) { if (method == null) return; - foreach (var prop in Properties) { + var properties = Properties; + int count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; prop.GetMethods.Remove(method); prop.SetMethods.Remove(method); prop.OtherMethods.Remove(method); } - foreach (var evt in Events) { + var events = Events; + count = events.Count; + for (int i = 0; i < count; i++) { + var evt = events[i]; if (evt.AddMethod == method) evt.AddMethod = null; if (evt.RemoveMethod == method) @@ -1513,16 +1570,18 @@ public void Remove(MethodDef method, bool removeEmptyPropertiesEvents) { } void RemoveEmptyProperties() { - for (int i = Properties.Count - 1; i >= 0; i--) { - if (Properties[i].IsEmpty) - Properties.RemoveAt(i); + var properties = Properties; + for (int i = properties.Count - 1; i >= 0; i--) { + if (properties[i].IsEmpty) + properties.RemoveAt(i); } } void RemoveEmptyEvents() { - for (int i = Events.Count - 1; i >= 0; i--) { - if (Events[i].IsEmpty) - Events.RemoveAt(i); + var events = Events; + for (int i = events.Count - 1; i >= 0; i--) { + if (events[i].IsEmpty) + events.RemoveAt(i); } } @@ -1723,12 +1782,15 @@ void IListListener.OnClear() { /// Field name /// A list of 0 or more fields with name public IList GetFields(UTF8String name) { - var fields = new List(); - foreach (var field in Fields) { + var result = new List(); + var fields = Fields; + int count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (field.Name == name) - fields.Add(field); + result.Add(field); } - return fields; + return result; } /// @@ -1737,7 +1799,10 @@ public IList GetFields(UTF8String name) { /// Field name /// The field or null if none found public FieldDef GetField(UTF8String name) { - foreach (var field in Fields) { + var fields = Fields; + int count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (field.Name == name) return field; } diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index 192a1fad8..05e61ac57 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -344,7 +344,9 @@ bool ContainsGenericParameter(IList types) { return false; bool res = false; - foreach (var type in types) { + int count = types.Count; + for (int i = 0; i < count; i++) { + var type = types[i]; if (ContainsGenericParameter(type)) { res = true; break; diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index 6d5b7f8b2..e0f7f8dfe 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -298,7 +298,9 @@ internal GenericSig ReadGenericSig() { } internal TypeSig CreateTypeSig(IList tspecs, TypeSig currentSig) { - foreach (var tspec in tspecs) { + int count = tspecs.Count; + for (int i = 0; i < count; i++) { + var tspec = tspecs[i]; switch (tspec.etype) { case ElementType.SZArray: currentSig = new SZArraySig(currentSig); diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index 0c4d3a247..55e5ecd77 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -638,7 +638,10 @@ public GenericParam GenericParam { var gpp = genericParamProvider; if (gpp == null) return null; - foreach (var gp in gpp.GenericParameters) { + var gps = gpp.GenericParameters; + int count = gps.Count; + for (int i = 0; i < count; i++) { + var gp = gps[i]; if (gp.Number == number) return gp; } diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 7b7d6706a..bb30da208 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -51,7 +51,9 @@ byte[] WriteFormat2(IList secAttrs) { writer.WriteByte((byte)'.'); WriteCompressedUInt32(writer, (uint)secAttrs.Count); - foreach (var sa in secAttrs) { + int count = secAttrs.Count; + for (int i = 0; i < count; i++) { + var sa = secAttrs[i]; if (sa == null) { helper.Error("SecurityAttribute is null"); Write(writer, UTF8String.Empty); diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index d39bdd0c5..7c6dd1ca3 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -776,7 +776,7 @@ public static void Write(this DataWriter writer, Metadata metadata, MDTable= 5) { + if (columns.Length >= 5) { var columns4 = columns[4]; for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index af04c927b..9c49d657d 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -1401,6 +1401,7 @@ void Create() { /// aren't written either. /// void InitializeTypeDefsAndMemberDefs() { + int count; int numTypes = allTypeDefs.Length; int typeNum = 0; int notifyNum = 0; @@ -1428,7 +1429,10 @@ void InitializeTypeDefsAndMemberDefs() { AddClassLayout(type); AddNestedType(type, type.DeclaringType); - foreach (var field in type.Fields) { + var fields = type.Fields; + count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (field == null) { Error("Field is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; @@ -1443,7 +1447,10 @@ void InitializeTypeDefsAndMemberDefs() { AddConstant(new MDToken(Table.Field, rid), field); } - foreach (var method in type.Methods) { + var methods = type.Methods; + count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method == null) { Error("Method is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; @@ -1458,7 +1465,10 @@ void InitializeTypeDefsAndMemberDefs() { AddDeclSecurities(new MDToken(Table.Method, rid), method.DeclSecurities); AddImplMap(new MDToken(Table.Method, rid), method); AddMethodImpls(method, method.Overrides); - foreach (var pd in method.ParamDefs) { + var paramDefs = method.ParamDefs; + int count2 = paramDefs.Count; + for (int j = 0; j < count2; j++) { + var pd = paramDefs[j]; if (pd == null) { Error("Param is null. Method {0} ({1:X8})", method, method.MDToken.Raw); continue; @@ -1471,7 +1481,10 @@ void InitializeTypeDefsAndMemberDefs() { } } - foreach (var evt in type.Events) { + var events = type.Events; + count = events.Count; + for (int i = 0; i < count; i++) { + var evt = events[i]; if (evt == null) { Error("Event is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; @@ -1482,7 +1495,10 @@ void InitializeTypeDefsAndMemberDefs() { AddMethodSemantics(evt); } - foreach (var prop in type.Properties) { + var properties = type.Properties; + count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (prop == null) { Error("Property is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; @@ -1501,6 +1517,7 @@ void InitializeTypeDefsAndMemberDefs() { /// Property and Param custom attributes and custom debug infos. /// void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { + int count; int numTypes = allTypeDefs.Length; int typeNum = 0; int notifyNum = 0; @@ -1523,7 +1540,10 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { AddCustomDebugInformationList(Table.TypeDef, rid, type); } - foreach (var field in type.Fields) { + var fields = type.Fields; + count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (field == null) continue; if (field.HasCustomAttributes || field.HasCustomDebugInfos) { @@ -1533,7 +1553,10 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { } } - foreach (var method in type.Methods) { + var methods = type.Methods; + count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method == null) continue; if (method.HasCustomAttributes) { @@ -1541,7 +1564,10 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { AddCustomAttributes(Table.Method, rid, method); // Method custom debug info is added later when writing method bodies } - foreach (var pd in method.ParamDefs) { + var paramDefs = method.ParamDefs; + int count2 = paramDefs.Count; + for (int j = 0; j < count2; j++) { + var pd = paramDefs[j]; if (pd == null) continue; if (pd.HasCustomAttributes || pd.HasCustomDebugInfos) { @@ -1551,7 +1577,10 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { } } } - foreach (var evt in type.Events) { + var events = type.Events; + count = events.Count; + for (int i = 0; i < count; i++) { + var evt = events[i]; if (evt == null) continue; if (evt.HasCustomAttributes || evt.HasCustomDebugInfos) { @@ -1560,7 +1589,10 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { AddCustomDebugInformationList(Table.Event, rid, evt); } } - foreach (var prop in type.Properties) { + var properties = type.Properties; + count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (prop == null) continue; if (prop.HasCustomAttributes || prop.HasCustomDebugInfos) { @@ -1594,8 +1626,10 @@ void InitializeVTableFixups() { } void AddExportedTypes() { - foreach (var et in module.ExportedTypes) - AddExportedType(et); + var exportedTypes = module.ExportedTypes; + int count = exportedTypes.Count; + for (int i = 0; i < count; i++) + AddExportedType(exportedTypes[i]); } /// @@ -1697,7 +1731,10 @@ void InitializeGenericParamConstraintTable() { if (type == null) continue; AddGenericParamConstraints(type.GenericParameters); - foreach (var method in type.Methods) { + var methods = type.Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method == null) continue; AddGenericParamConstraints(method.GenericParameters); @@ -1864,10 +1901,18 @@ void WriteMethodBodies() { (uint)debugMetadata.tablesHeap.LocalConstantTable.Rows + 1, info.ScopeStart, info.ScopeLength); debugMetadata.localScopeInfos.Add(info.Scope, row); - foreach (var local in info.Scope.Variables) + var variables = info.Scope.Variables; + int count = variables.Count; + for (int i = 0; i < count; i++) { + var local = variables[i]; AddLocalVariable(local); - foreach (var constant in info.Scope.Constants) + } + var constants = info.Scope.Constants; + count = constants.Count; + for (int i = 0; i < count; i++) { + var constant = constants[i]; AddLocalConstant(constant); + } AddCustomDebugInformationList(Table.LocalScope, localScopeRid, info.Scope.CustomDebugInfos); } @@ -1909,8 +1954,9 @@ static bool IsEmptyRootScope(CilBody cilBody, PdbScope scope) { protected static bool IsEmpty(IList list) where T : class { if (list == null) return true; - foreach (var e in list) { - if (e != null) + int count = list.Count; + for (int i = 0; i < count; i++) { + if (list[i] != null) return false; } return true; @@ -2340,8 +2386,9 @@ protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { protected void AddGenericParams(MDToken token, IList gps) { if (gps == null) return; - foreach (var gp in gps) - AddGenericParam(token, gp); + int count = gps.Count; + for (int i = 0; i < count; i++) + AddGenericParam(token, gps[i]); } /// @@ -2369,7 +2416,9 @@ protected void AddGenericParam(MDToken owner, GenericParam gp) { void AddGenericParamConstraints(IList gps) { if (gps == null) return; - foreach (var gp in gps) { + int count = gps.Count; + for (int i = 0; i < count; i++) { + var gp = gps[i]; if (gp == null) continue; uint rid = genericParamInfos.Rid(gp); @@ -2385,8 +2434,9 @@ void AddGenericParamConstraints(IList gps) { protected void AddGenericParamConstraints(uint gpRid, IList constraints) { if (constraints == null) return; - foreach (var gpc in constraints) - AddGenericParamConstraint(gpRid, gpc); + int count = constraints.Count; + for (int i = 0; i < count; i++) + AddGenericParamConstraint(gpRid, constraints[i]); } /// @@ -2409,7 +2459,9 @@ protected void AddGenericParamConstraint(uint gpRid, GenericParamConstraint gpc) /// New rid of owner /// All interfaces protected void AddInterfaceImpls(uint typeDefRid, IList ifaces) { - foreach (var iface in ifaces) { + int count = ifaces.Count; + for (int i = 0; i < count; i++) { + var iface = ifaces[i]; if (iface == null) continue; var row = new RawInterfaceImplRow(typeDefRid, @@ -2609,7 +2661,9 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit encodedParent = 0; } var bwctx = AllocBinaryWriterContext(); - foreach (var decl in declSecurities) { + int count = declSecurities.Count; + for (int i = 0; i < count; i++) { + var decl = declSecurities[i]; if (decl == null) continue; var row = new RawDeclSecurityRow((short)decl.Action, @@ -2660,8 +2714,9 @@ protected void AddMethodSemantics(PropertyDef prop) { void AddMethodSemantics(MDToken owner, IList methods, MethodSemanticsAttributes attrs) { if (methods == null) return; - foreach (var method in methods) - AddMethodSemantics(owner, method, attrs); + int count = methods.Count; + for (int i = 0; i < count; i++) + AddMethodSemantics(owner, methods[i], attrs); } void AddMethodSemantics(MDToken owner, MethodDef method, MethodSemanticsAttributes flags) { @@ -2687,7 +2742,9 @@ void AddMethodImpls(MethodDef method, IList overrides) { } if (overrides.Count != 0) { uint rid = GetRid(method.DeclaringType); - foreach (var ovr in overrides) { + int count = overrides.Count; + for (int i = 0; i < count; i++) { + var ovr = overrides[i]; var row = new RawMethodImplRow(rid, AddMethodDefOrRef(ovr.MethodBody), AddMethodDefOrRef(ovr.MethodDeclaration)); @@ -2712,8 +2769,9 @@ protected void AddClassLayout(TypeDef type) { void AddResources(IList resources) { if (resources == null) return; - foreach (var resource in resources) - AddResource(resource); + int count = resources.Count; + for (int i = 0; i < count; i++) + AddResource(resources[i]); } void AddResource(Resource resource) { @@ -2899,8 +2957,9 @@ void AppendExtraData(ref byte[] blob, byte[] extraData) { void AddCustomAttributes(Table table, uint rid, CustomAttributeCollection caList) { var token = new MDToken(table, rid); - foreach (var ca in caList) - AddCustomAttribute(token, ca); + int count = caList.Count; + for (int i = 0; i < count; i++) + AddCustomAttribute(token, caList[i]); } void AddCustomAttribute(MDToken token, CustomAttribute ca) { diff --git a/src/DotNet/Writer/MetadataHeader.cs b/src/DotNet/Writer/MetadataHeader.cs index 1d159810e..7ad35a0cc 100644 --- a/src/DotNet/Writer/MetadataHeader.cs +++ b/src/DotNet/Writer/MetadataHeader.cs @@ -119,7 +119,10 @@ public void SetOffset(FileOffset offset, RVA rva) { length += (uint)GetVersionString().Length; length = Utils.AlignUp(length, 4); length += 4; - foreach (var heap in heaps) { + var heaps = this.heaps; + int count = heaps.Count; + for (int i = 0; i < count; i++) { + var heap = heaps[i]; length += 8; length += (uint)GetAsciizName(heap.Name).Length; length = Utils.AlignUp(length, 4); @@ -144,8 +147,11 @@ public void WriteTo(DataWriter writer) { writer.WriteZeros(Utils.AlignUp(s.Length, 4) - s.Length); writer.WriteByte((byte)(options.StorageFlags ?? 0)); writer.WriteByte(options.Reserved2 ?? 0); + var heaps = this.heaps; writer.WriteUInt16((ushort)heaps.Count); - foreach (var heap in heaps) { + int count = heaps.Count; + for (int i = 0; i < count; i++) { + var heap = heaps[i]; writer.WriteUInt32((uint)(heap.FileOffset - offset)); writer.WriteUInt32(heap.GetFileLength()); writer.WriteBytes(s = GetAsciizName(heap.Name)); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 37ac74217..cbcf63a37 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -348,7 +348,9 @@ protected ModuleWriterOptionsBase(ModuleDef module) { } static bool HasMvidSection(IList sections) { - foreach (var section in sections) { + int count = sections.Count; + for (int i = 0; i < count; i++) { + var section = sections[i]; if (section.VirtualSize != 16) continue; var name = section.Name; @@ -655,7 +657,9 @@ protected void CreateMetadataChunks(ModuleDef module) { /// File alignment /// Section alignment protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offset, RVA rva, uint fileAlignment, uint sectionAlignment) { - foreach (var chunk in chunks) { + int count = chunks.Count; + for (int i = 0; i < count; i++) { + var chunk = chunks[i]; chunk.SetOffset(offset, rva); // If it has zero size, it's not present in the file (eg. a section that wasn't needed) if (chunk.GetVirtualSize() != 0) { @@ -675,7 +679,9 @@ protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offse /// File offset of first chunk /// File alignment protected void WriteChunks(DataWriter writer, List chunks, FileOffset offset, uint fileAlignment) { - foreach (var chunk in chunks) { + int count = chunks.Count; + for (int i = 0; i < count; i++) { + var chunk = chunks[i]; chunk.VerifyWriteTo(writer); // If it has zero size, it's not present in the file (eg. a section that wasn't needed) if (chunk.GetVirtualSize() != 0) { diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index b5e5cfa83..c604253f1 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -779,7 +779,10 @@ void UpdateVTableFixups(DataWriter writer) { Error("Could not convert RVA to file offset"); } else { - foreach (var method in vtable.Methods) { + var methods = vtable.Methods; + int count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; writer.WriteUInt32(GetMethodToken(method)); if (vtable.Is64Bit) writer.WriteInt32(0); diff --git a/src/DotNet/Writer/NormalMetadata.cs b/src/DotNet/Writer/NormalMetadata.cs index b714dc558..baf52ee3d 100644 --- a/src/DotNet/Writer/NormalMetadata.cs +++ b/src/DotNet/Writer/NormalMetadata.cs @@ -54,6 +54,7 @@ protected override void AllocateMemberDefRids() { uint fieldListRid = 1, methodListRid = 1; uint eventListRid = 1, propertyListRid = 1; uint paramListRid = 1; + int count; foreach (var type in allTypeDefs) { if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, (double)typeNum / numTypes); @@ -68,7 +69,10 @@ protected override void AllocateMemberDefRids() { typeRow = new RawTypeDefRow(typeRow.Flags, typeRow.Name, typeRow.Namespace, typeRow.Extends, fieldListRid, methodListRid); tablesHeap.TypeDefTable[typeRid] = typeRow; - foreach (var field in type.Fields) { + var fields = type.Fields; + count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (field == null) continue; uint rid = fieldListRid++; @@ -77,7 +81,10 @@ protected override void AllocateMemberDefRids() { fieldDefInfos.Add(field, rid); } - foreach (var method in type.Methods) { + var methods = type.Methods; + count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method == null) continue; uint rid = methodListRid++; @@ -98,7 +105,10 @@ protected override void AllocateMemberDefRids() { if (!IsEmpty(type.Events)) { uint eventMapRid = tablesHeap.EventMapTable.Create(new RawEventMapRow(typeRid, eventListRid)); eventMapInfos.Add(type, eventMapRid); - foreach (var evt in type.Events) { + var events = type.Events; + count = events.Count; + for (int i = 0; i < count; i++) { + var evt = events[i]; if (evt == null) continue; uint rid = eventListRid++; @@ -111,7 +121,10 @@ protected override void AllocateMemberDefRids() { if (!IsEmpty(type.Properties)) { uint propertyMapRid = tablesHeap.PropertyMapTable.Create(new RawPropertyMapRow(typeRid, propertyListRid)); propertyMapInfos.Add(type, propertyMapRid); - foreach (var prop in type.Properties) { + var properties = type.Properties; + count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (prop == null) continue; uint rid = propertyListRid++; diff --git a/src/DotNet/Writer/PreserveTokensMetadata.cs b/src/DotNet/Writer/PreserveTokensMetadata.cs index 6d46c5f6b..0970f7dd5 100644 --- a/src/DotNet/Writer/PreserveTokensMetadata.cs +++ b/src/DotNet/Writer/PreserveTokensMetadata.cs @@ -837,6 +837,7 @@ uint CreateDummyPtrTableType() { uint dummyPtrTableTypeRid; void FindMemberDefs() { + int count; var added = new Dictionary(); int pos; foreach (var type in allTypeDefs) { @@ -844,21 +845,30 @@ void FindMemberDefs() { continue; pos = 0; - foreach (var field in type.Fields) { + var fields = type.Fields; + count = fields.Count; + for (int i = 0; i < count; i++) { + var field = fields[i]; if (field == null) continue; fieldDefInfos.Add(field, pos++); } pos = 0; - foreach (var method in type.Methods) { + var methods = type.Methods; + count = methods.Count; + for (int i = 0; i < count; i++) { + var method = methods[i]; if (method == null) continue; methodDefInfos.Add(method, pos++); } pos = 0; - foreach (var evt in type.Events) { + var events = type.Events; + count = events.Count; + for (int i = 0; i < count; i++) { + var evt = events[i]; if (evt == null || added.ContainsKey(evt)) continue; added[evt] = true; @@ -866,7 +876,10 @@ void FindMemberDefs() { } pos = 0; - foreach (var prop in type.Properties) { + var properties = type.Properties; + count = properties.Count; + for (int i = 0; i < count; i++) { + var prop = properties[i]; if (prop == null || added.ContainsKey(prop)) continue; added[prop] = true; diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 82bdf1a34..89441b319 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -332,9 +332,14 @@ void FindDirectoryEntries(ResourceDirectory dir) { return; dirList.Add(dir); dirDict[dir] = 0; - foreach (var dir2 in dir.Directories) - FindDirectoryEntries(dir2); - foreach (var data in dir.Data) { + var dirs = dir.Directories; + int count = dirs.Count; + for (int i = 0; i < count; i++) + FindDirectoryEntries(dirs[i]); + var dirData = dir.Data; + count = dirData.Count; + for (int i = 0; i < count; i++) { + var data = dirData[i]; if (dataHeaderDict.ContainsKey(data)) continue; dataHeaderList.Add(data); @@ -439,13 +444,19 @@ uint GetDirectoryEntryOffset(ResourceDirectoryEntry e) { static void GetNamedAndIds(ResourceDirectory dir, out List named, out List ids) { named = new List(); ids = new List(); - foreach (var d in dir.Directories) { + var dirs = dir.Directories; + int count = dirs.Count; + for (int i = 0; i < count; i++) { + var d = dirs[i]; if (d.Name.HasId) ids.Add(d); else named.Add(d); } - foreach (var d in dir.Data) { + var dirData = dir.Data; + count = dirData.Count; + for (int i = 0; i < count; i++) { + var d = dirData[i]; if (d.Name.HasId) ids.Add(d); else From 59486b30ec6dd2e1708d0912bab89b23f72355eb Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:37:31 +0100 Subject: [PATCH 156/511] Throw if PDB stream is null --- src/DotNet/Writer/ModuleWriterBase.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index cbcf63a37..3fe865684 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -833,6 +833,8 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { } else pdbStream = GetStandalonePortablePdbStream(out ownsStream); + if (pdbStream == null) + throw new ModuleWriterException("Couldn't create a PDB stream"); var pdbFilename = TheOptions.PdbFileName ?? GetStreamName(pdbStream) ?? GetDefaultPdbFileName(); if (isEmbeddedPortablePdb) From eee13e935670d328dcf490abacf92ef75ab1fe9a Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:37:37 +0100 Subject: [PATCH 157/511] Add missing XML docs --- src/DotNet/Writer/DataWriter.cs | 79 ++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs index e8441c2f0..89d22da1f 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/DataWriter.cs @@ -4,7 +4,6 @@ using System.IO; namespace dnlib.DotNet.Writer { -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member /// /// Writes data /// @@ -15,11 +14,18 @@ public sealed class DataWriter { internal Stream InternalStream => stream; + /// + /// Gets/sets the position + /// public long Position { get => stream.Position; set => stream.Position = value; } + /// + /// Constructor + /// + /// Destination stream public DataWriter(Stream stream) { if (stream == null) ThrowArgumentNullException(nameof(stream)); @@ -30,10 +36,28 @@ public DataWriter(Stream stream) { static void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName); static void ThrowArgumentOutOfRangeException(string message) => throw new ArgumentOutOfRangeException(message); + /// + /// Writes a + /// + /// Value public void WriteBoolean(bool value) => stream.WriteByte(value ? (byte)1 : (byte)0); + + /// + /// Writes a + /// + /// Value public void WriteSByte(sbyte value) => stream.WriteByte((byte)value); + + /// + /// Writes a + /// + /// Value public void WriteByte(byte value) => stream.WriteByte(value); + /// + /// Writes a + /// + /// Value public void WriteInt16(short value) { var buffer = this.buffer; buffer[0] = (byte)value; @@ -41,6 +65,10 @@ public void WriteInt16(short value) { stream.Write(buffer, 0, 2); } + /// + /// Writes a + /// + /// Value public void WriteUInt16(ushort value) { var buffer = this.buffer; buffer[0] = (byte)value; @@ -48,6 +76,10 @@ public void WriteUInt16(ushort value) { stream.Write(buffer, 0, 2); } + /// + /// Writes a + /// + /// Value public void WriteInt32(int value) { var buffer = this.buffer; buffer[0] = (byte)value; @@ -57,6 +89,10 @@ public void WriteInt32(int value) { stream.Write(buffer, 0, 4); } + /// + /// Writes a + /// + /// Value public void WriteUInt32(uint value) { var buffer = this.buffer; buffer[0] = (byte)value; @@ -66,6 +102,10 @@ public void WriteUInt32(uint value) { stream.Write(buffer, 0, 4); } + /// + /// Writes a + /// + /// Value public void WriteInt64(long value) { var buffer = this.buffer; buffer[0] = (byte)value; @@ -79,6 +119,10 @@ public void WriteInt64(long value) { stream.Write(buffer, 0, 8); } + /// + /// Writes a + /// + /// Value public void WriteUInt64(ulong value) { var buffer = this.buffer; buffer[0] = (byte)value; @@ -92,6 +136,10 @@ public void WriteUInt64(ulong value) { stream.Write(buffer, 0, 8); } + /// + /// Writes a + /// + /// Value public unsafe void WriteSingle(float value) { uint tmp = *(uint*)&value; var buffer = this.buffer; @@ -102,6 +150,10 @@ public unsafe void WriteSingle(float value) { stream.Write(buffer, 0, 4); } + /// + /// Writes a + /// + /// Value public unsafe void WriteDouble(double value) { ulong tmp = *(ulong*)&value; var buffer = this.buffer; @@ -116,9 +168,24 @@ public unsafe void WriteDouble(double value) { stream.Write(buffer, 0, 8); } + /// + /// Writes bytes + /// + /// Bytes to write public void WriteBytes(byte[] source) => stream.Write(source, 0, source.Length); + + /// + /// Writes bytes + /// + /// Bytes to write + /// Index to start copying from + /// Number of bytes to copy public void WriteBytes(byte[] source, int index, int length) => stream.Write(source, index, length); + /// + /// Writes a compressed + /// + /// Value public void WriteCompressedUInt32(uint value) { if (value <= 0x7F) stream.WriteByte((byte)value); @@ -136,6 +203,10 @@ public void WriteCompressedUInt32(uint value) { ThrowArgumentOutOfRangeException("UInt32 value can't be compressed"); } + /// + /// Writes a compressed + /// + /// public void WriteCompressedInt32(int value) { // This is almost identical to compressing a UInt32, except that we first // recode value so the sign bit is in bit 0. Then we compress it the same @@ -161,6 +232,11 @@ public void WriteCompressedInt32(int value) { ThrowArgumentOutOfRangeException("Int32 value can't be compressed"); } + /// + /// Gets the size of a compressed , see + /// + /// Value + /// public static int GetCompressedUInt32Length(uint value) { if (value <= 0x7F) return 1; @@ -172,5 +248,4 @@ public static int GetCompressedUInt32Length(uint value) { return 0; } } -#pragma warning restore 1591 // Missing XML comment for publicly visible type or member } From 3a4b6aa7aa6f00026ec5a3457003709d007251c1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 20:50:31 +0100 Subject: [PATCH 158/511] Update examples --- Examples/Example1.cs | 8 ++++---- Examples/Example2.cs | 16 ++++++++-------- Examples/Example3.cs | 14 +++++++------- Examples/Example6.cs | 40 +++++++++------------------------------- 4 files changed, 28 insertions(+), 50 deletions(-) diff --git a/Examples/Example1.cs b/Examples/Example1.cs index c866bec13..d74762fd3 100644 --- a/Examples/Example1.cs +++ b/Examples/Example1.cs @@ -8,13 +8,13 @@ namespace dnlib.Examples { public class Example1 { public static void Run() { // Load mscorlib.dll - string filename = typeof(void).Module.FullyQualifiedName; - ModuleDefMD mod = ModuleDefMD.Load(filename); + var filename = typeof(void).Module.FullyQualifiedName; + var mod = ModuleDefMD.Load(filename); int totalNumTypes = 0; // mod.Types only returns non-nested types. // mod.GetTypes() returns all types, including nested types. - foreach (TypeDef type in mod.GetTypes()) { + foreach (var type in mod.GetTypes()) { totalNumTypes++; Console.WriteLine(); Console.WriteLine("Type: {0}", type.FullName); @@ -29,7 +29,7 @@ public static void Run() { if (type.Interfaces.Count > 0) { Console.WriteLine(" Interfaces:"); - foreach (InterfaceImpl iface in type.Interfaces) + foreach (var iface in type.Interfaces) Console.WriteLine(" {0}", iface.Interface.FullName); } } diff --git a/Examples/Example2.cs b/Examples/Example2.cs index 476cde7df..d73df4843 100644 --- a/Examples/Example2.cs +++ b/Examples/Example2.cs @@ -7,10 +7,10 @@ public class Example2 { // and then save the assembly to disk. public static void Run() { // Open the current module - ModuleDefMD mod = ModuleDefMD.Load(typeof(Example2).Module); + var mod = ModuleDefMD.Load(typeof(Example2).Module); // Create a new public class that derives from System.Object - TypeDef type1 = new TypeDefUser("My.Namespace", "MyType", + var type1 = new TypeDefUser("My.Namespace", "MyType", mod.CorLibTypes.Object.TypeDefOrRef); type1.Attributes = TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.AnsiClass; @@ -19,7 +19,7 @@ public static void Run() { mod.Types.Add(type1); // Create a public static System.Int32 field called MyField - FieldDef field1 = new FieldDefUser("MyField", + var field1 = new FieldDefUser("MyField", new FieldSig(mod.CorLibTypes.Int32), FieldAttributes.Public | FieldAttributes.Static); // Add it to the type we created earlier @@ -27,22 +27,22 @@ public static void Run() { // Add a static method that adds both inputs and the static field // and returns the result - MethodImplAttributes methImplFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; - MethodAttributes methFlags = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot; - MethodDef meth1 = new MethodDefUser("MyMethod", + var methImplFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; + var methFlags = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot; + var meth1 = new MethodDefUser("MyMethod", MethodSig.CreateStatic(mod.CorLibTypes.Int32, mod.CorLibTypes.Int32, mod.CorLibTypes.Int32), methImplFlags, methFlags); type1.Methods.Add(meth1); // Create the CIL method body - CilBody body = new CilBody(); + var body = new CilBody(); meth1.Body = body; // Name the 1st and 2nd args a and b, respectively meth1.ParamDefs.Add(new ParamDefUser("a", 1)); meth1.ParamDefs.Add(new ParamDefUser("b", 2)); // Create a local. We don't really need it but let's add one anyway - Local local1 = new Local(mod.CorLibTypes.Int32); + var local1 = new Local(mod.CorLibTypes.Int32); body.Variables.Add(local1); // Add the instructions, and use the useless local diff --git a/Examples/Example3.cs b/Examples/Example3.cs index 62688233c..741adb7bc 100644 --- a/Examples/Example3.cs +++ b/Examples/Example3.cs @@ -23,12 +23,12 @@ public class Example3 { public static void Run() { // Create a new module. The string passed in is the name of the module, // not the file name. - ModuleDef mod = new ModuleDefUser("MyModule.exe"); + var mod = new ModuleDefUser("MyModule.exe"); // It's a console application mod.Kind = ModuleKind.Console; // Add the module to an assembly - AssemblyDef asm = new AssemblyDefUser("MyAssembly", new Version(1, 2, 3, 4), null, null); + var asm = new AssemblyDefUser("MyAssembly", new Version(1, 2, 3, 4), null, null); asm.Modules.Add(mod); // Add a .NET resource @@ -37,14 +37,14 @@ public static void Run() { ManifestResourceAttributes.Private)); // Add the startup type. It derives from System.Object. - TypeDef startUpType = new TypeDefUser("My.Namespace", "Startup", mod.CorLibTypes.Object.TypeDefOrRef); + var startUpType = new TypeDefUser("My.Namespace", "Startup", mod.CorLibTypes.Object.TypeDefOrRef); startUpType.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.AnsiClass; // Add the type to the module mod.Types.Add(startUpType); // Create the entry point method - MethodDef entryPoint = new MethodDefUser("Main", + var entryPoint = new MethodDefUser("Main", MethodSig.CreateStatic(mod.CorLibTypes.Int32, new SZArraySig(mod.CorLibTypes.String))); entryPoint.Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot; @@ -57,14 +57,14 @@ public static void Run() { mod.EntryPoint = entryPoint; // Create a TypeRef to System.Console - TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef); + var consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef); // Create a method ref to 'System.Void System.Console::WriteLine(System.String)' - MemberRef consoleWrite1 = new MemberRefUser(mod, "WriteLine", + var consoleWrite1 = new MemberRefUser(mod, "WriteLine", MethodSig.CreateStatic(mod.CorLibTypes.Void, mod.CorLibTypes.String), consoleRef); // Add a CIL method body to the entry point method - CilBody epBody = new CilBody(); + var epBody = new CilBody(); entryPoint.Body = epBody; epBody.Instructions.Add(OpCodes.Ldstr.ToInstruction("Hello World!")); epBody.Instructions.Add(OpCodes.Call.ToInstruction(consoleWrite1)); diff --git a/Examples/Example6.cs b/Examples/Example6.cs index 2843b2981..b74f8e386 100644 --- a/Examples/Example6.cs +++ b/Examples/Example6.cs @@ -14,9 +14,7 @@ namespace dnlib.Examples { /// most libraries that open .NET assemblies. /// public class Example6 { - public static void Run() { - new Example6().DoIt(); - } + public static void Run() => new Example6().DoIt(); void DoIt() { string destFileName = @"c:\output.dll"; @@ -59,47 +57,27 @@ class MyHeap : IHeap { // This is the data. I chose 10 bytes, but any non-zero value can be used byte[] heapData = new byte[10]; - public MyHeap(string name) { - this.name = name; - } + public MyHeap(string name) => this.name = name; // The rest of the code is just for implementing the required interface - public string Name { - get { return name; } - } - - public bool IsEmpty { - get { return false; } - } + public string Name => name; + public bool IsEmpty => false; public void SetReadOnly() { } - public FileOffset FileOffset { - get { return offset; } - } - - public RVA RVA { - get { return rva; } - } + public FileOffset FileOffset => offset; + public RVA RVA => rva; public void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; } - public uint GetFileLength() { - return (uint)heapData.Length; - } - - public uint GetVirtualSize() { - return GetFileLength(); - } - - public void WriteTo(BinaryWriter writer) { - writer.Write(heapData); - } + public uint GetFileLength() => (uint)heapData.Length; + public uint GetVirtualSize() => GetFileLength(); + public void WriteTo(DataWriter writer) => writer.WriteBytes(heapData); } // Gets notified during module writing From ba6d5cf9dd109d1a253d6cae9b4124ca235daa32 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 19 Mar 2018 21:21:34 +0100 Subject: [PATCH 159/511] Use less stream calls --- src/DotNet/Writer/DataWriter.cs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs index 89d22da1f..9cef1aba7 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/DataWriter.cs @@ -187,6 +187,7 @@ public unsafe void WriteDouble(double value) { /// /// Value public void WriteCompressedUInt32(uint value) { + var stream = this.stream; if (value <= 0x7F) stream.WriteByte((byte)value); else if (value <= 0x3FFF) { @@ -194,10 +195,12 @@ public void WriteCompressedUInt32(uint value) { stream.WriteByte((byte)value); } else if (value <= 0x1FFFFFFF) { - stream.WriteByte((byte)((value >> 24) | 0xC0)); - stream.WriteByte((byte)(value >> 16)); - stream.WriteByte((byte)(value >> 8)); - stream.WriteByte((byte)value); + var buffer = this.buffer; + buffer[0] = (byte)((value >> 24) | 0xC0); + buffer[1] = (byte)(value >> 16); + buffer[2] = (byte)(value >> 8); + buffer[3] = (byte)value; + stream.Write(buffer, 0, 4); } else ThrowArgumentOutOfRangeException("UInt32 value can't be compressed"); @@ -208,6 +211,7 @@ public void WriteCompressedUInt32(uint value) { /// /// public void WriteCompressedInt32(int value) { + var stream = this.stream; // This is almost identical to compressing a UInt32, except that we first // recode value so the sign bit is in bit 0. Then we compress it the same // way a UInt32 is compressed. @@ -223,10 +227,12 @@ public void WriteCompressedInt32(int value) { } else if (-0x10000000 <= value && value <= 0x0FFFFFFF) { uint v = ((uint)(value & 0x0FFFFFFF) << 1) | sign; - stream.WriteByte((byte)((v >> 24) | 0xC0)); - stream.WriteByte((byte)(v >> 16)); - stream.WriteByte((byte)(v >> 8)); - stream.WriteByte((byte)v); + var buffer = this.buffer; + buffer[0] = (byte)((v >> 24) | 0xC0); + buffer[1] = (byte)(v >> 16); + buffer[2] = (byte)(v >> 8); + buffer[3] = (byte)v; + stream.Write(buffer, 0, 4); } else ThrowArgumentOutOfRangeException("Int32 value can't be compressed"); From b9c8678ae7fa666295e952b389b9c57f30c5b599 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:55:57 +0100 Subject: [PATCH 160/511] Add more debug dir method overloads --- src/DotNet/Writer/DebugDirectory.cs | 30 +++++++++++++++++++++++++++ src/DotNet/Writer/ModuleWriterBase.cs | 20 +++++++++--------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index ad4489908..e56539ebc 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -75,6 +75,36 @@ public DebugDirectoryEntry Add(IChunk chunk) { return entry; } + /// + /// Adds data + /// + /// Data + /// Debug type + /// Major version + /// Minor version + /// Timestamp + /// + public DebugDirectoryEntry Add(byte[] data, ImageDebugType type, ushort majorVersion, ushort minorVersion, uint timeDateStamp) => + Add(new ByteArrayChunk(data), type, majorVersion, minorVersion, timeDateStamp); + + /// + /// Adds data + /// + /// Data + /// Debug type + /// Major version + /// Minor version + /// Timestamp + /// + public DebugDirectoryEntry Add(IChunk chunk, ImageDebugType type, ushort majorVersion, ushort minorVersion, uint timeDateStamp) { + var entry = Add(chunk); + entry.DebugDirectory.Type = type; + entry.DebugDirectory.MajorVersion = majorVersion; + entry.DebugDirectory.MinorVersion = minorVersion; + entry.DebugDirectory.TimeDateStamp = timeDateStamp; + return entry; + } + bool IReuseChunk.CanReuse(RVA origRva, uint origSize) { uint newLength = GetLength(entries, (FileOffset)origRva, origRva); if (newLength > origSize) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 3fe865684..7308a6c55 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -856,19 +856,19 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { metadata.WritePortablePdb(pdbStream, entryPointToken, pdbId); const uint age = 1; - var cvEntry = debugDirectory.Add(GetCodeViewData(pdbGuid, age, pdbFilename)); - cvEntry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); - cvEntry.DebugDirectory.MajorVersion = PortablePdbConstants.FormatVersion; - cvEntry.DebugDirectory.MinorVersion = PortablePdbConstants.PortableCodeViewVersionMagic; - cvEntry.DebugDirectory.Type = ImageDebugType.CodeView; + debugDirectory.Add(GetCodeViewData(pdbGuid, age, pdbFilename), + type: ImageDebugType.CodeView, + majorVersion: PortablePdbConstants.FormatVersion, + minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, + timeDateStamp: GetTimeDateStamp()); if (isEmbeddedPortablePdb) { Debug.Assert(embeddedMemoryStream != null); - var embedEntry = debugDirectory.Add(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream)); - embedEntry.DebugDirectory.TimeDateStamp = 0; - embedEntry.DebugDirectory.MajorVersion = PortablePdbConstants.FormatVersion; - embedEntry.DebugDirectory.MinorVersion = PortablePdbConstants.EmbeddedVersion; - embedEntry.DebugDirectory.Type = ImageDebugType.EmbeddedPortablePdb; + debugDirectory.Add(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream), + type: ImageDebugType.EmbeddedPortablePdb, + majorVersion: PortablePdbConstants.FormatVersion, + minorVersion: PortablePdbConstants.EmbeddedVersion, + timeDateStamp: 0); } } finally { From cbb03dea0c84fd955cc018b0237a31283f3afdc4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:56:05 +0100 Subject: [PATCH 161/511] Rename --- src/DotNet/FullNameCreator.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/DotNet/FullNameCreator.cs b/src/DotNet/FullNameCreator.cs index 82eeaaed4..4c192d8c3 100644 --- a/src/DotNet/FullNameCreator.cs +++ b/src/DotNet/FullNameCreator.cs @@ -1529,14 +1529,14 @@ static string GetAssemblyName(IAssembly assembly) { return Utils.GetAssemblyNameString(EscapeAssemblyName(assembly.Name), assembly.Version, assembly.Culture, pk, assembly.Attributes); } - static string EscapeAssemblyName(UTF8String asmSimplName) => - EscapeAssemblyName(UTF8String.ToSystemString(asmSimplName)); - - static string EscapeAssemblyName(string asmSimplName) { - if (asmSimplName.IndexOf(']') < 0) - return asmSimplName; - var sb = new StringBuilder(asmSimplName.Length); - foreach (var c in asmSimplName) { + static string EscapeAssemblyName(UTF8String asmSimpleName) => + EscapeAssemblyName(UTF8String.ToSystemString(asmSimpleName)); + + static string EscapeAssemblyName(string asmSimpleName) { + if (asmSimpleName.IndexOf(']') < 0) + return asmSimpleName; + var sb = new StringBuilder(asmSimpleName.Length); + foreach (var c in asmSimpleName) { if (c == ']') sb.Append('\\'); sb.Append(c); From f15b1bafa33afde5c940d0a7bb90fb973d0627ab Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:56:16 +0100 Subject: [PATCH 162/511] Add missing XML docs --- src/DotNet/Writer/ArrayWriter.cs | 50 ++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/ArrayWriter.cs b/src/DotNet/Writer/ArrayWriter.cs index 60358e69a..a4c12b333 100644 --- a/src/DotNet/Writer/ArrayWriter.cs +++ b/src/DotNet/Writer/ArrayWriter.cs @@ -3,34 +3,61 @@ using System.Diagnostics; namespace dnlib.DotNet.Writer { -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member /// /// Writes data /// public unsafe struct ArrayWriter { + /// + /// Gets the current position + /// public int Position => position; readonly byte[] data; int position; + /// + /// Constructor + /// + /// Destination array public ArrayWriter(byte[] data) { this.data = data; position = 0; } + /// + /// Writes a + /// + /// Value public void WriteSByte(sbyte value) => data[position++] = (byte)value; + + /// + /// Writes a + /// + /// Value public void WriteByte(byte value) => data[position++] = value; + /// + /// Writes a + /// + /// Value public void WriteInt16(short value) { data[position++] = (byte)value; data[position++] = (byte)(value >> 8); } + /// + /// Writes a + /// + /// Value public void WriteUInt16(ushort value) { data[position++] = (byte)value; data[position++] = (byte)(value >> 8); } + /// + /// Writes a + /// + /// Value public void WriteInt32(int value) { Debug.Assert(this.position + 4 <= data.Length); var position = this.position; @@ -39,6 +66,10 @@ public void WriteInt32(int value) { this.position = position + 4; } + /// + /// Writes a + /// + /// Value public void WriteUInt32(uint value) { Debug.Assert(this.position + 4 <= data.Length); var position = this.position; @@ -47,6 +78,10 @@ public void WriteUInt32(uint value) { this.position = position + 4; } + /// + /// Writes a + /// + /// Value public void WriteInt64(long value) { Debug.Assert(this.position + 8 <= data.Length); var position = this.position; @@ -55,6 +90,10 @@ public void WriteInt64(long value) { this.position = position + 8; } + /// + /// Writes a + /// + /// Value public void WriteUInt64(ulong value) { Debug.Assert(this.position + 8 <= data.Length); var position = this.position; @@ -63,6 +102,10 @@ public void WriteUInt64(ulong value) { this.position = position + 8; } + /// + /// Writes a + /// + /// Value public void WriteSingle(float value) { Debug.Assert(this.position + 4 <= data.Length); var position = this.position; @@ -71,6 +114,10 @@ public void WriteSingle(float value) { this.position = position + 4; } + /// + /// Writes a + /// + /// Value public void WriteDouble(double value) { Debug.Assert(this.position + 8 <= data.Length); var position = this.position; @@ -79,5 +126,4 @@ public void WriteDouble(double value) { this.position = position + 8; } } -#pragma warning restore 1591 // Missing XML comment for publicly visible type or member } From e18ff3ac2ac8f170d305ad6defd7028d4ffcbbd7 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:56:24 +0100 Subject: [PATCH 163/511] Skip 4 bytes not 2 --- src/PE/PEExtensions.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/PE/PEExtensions.cs b/src/PE/PEExtensions.cs index db0de7d60..eeef50d94 100644 --- a/src/PE/PEExtensions.cs +++ b/src/PE/PEExtensions.cs @@ -21,8 +21,9 @@ internal static uint CalculatePECheckSum(this Stream stream, long length, long c var buffer = new byte[(int)Math.Min(length, 0x2000)]; uint checkSum = 0; checkSum = CalculatePECheckSum(stream, checkSumOffset, checkSum, buffer); - stream.Position += 2; - checkSum = CalculatePECheckSum(stream, length - checkSumOffset - 2, checkSum, buffer); + const int ChecksumFieldSize = 4; + stream.Position += ChecksumFieldSize; + checkSum = CalculatePECheckSum(stream, length - checkSumOffset - ChecksumFieldSize, checkSum, buffer); ulong cks = (ulong)checkSum + (ulong)length; return (uint)cks + (uint)(cks >> 32); } From c31cbff5c2808b5b7cd2c7e51a48575f87219e13 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:56:32 +0100 Subject: [PATCH 164/511] Add Machine.Is64Bit() extension method --- src/DotNet/ModuleDef.cs | 2 +- src/DotNet/Writer/ManagedExportsWriter.cs | 2 +- src/DotNet/Writer/ModuleWriter.cs | 4 ++-- src/DotNet/Writer/ModuleWriterBase.cs | 5 ++--- src/DotNet/Writer/PEHeaders.cs | 5 +---- src/DotNet/Writer/RelocDirectory.cs | 2 +- src/PE/Machine.cs | 13 +++++++++++++ 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 50798ae56..8f9bafcbc 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1117,7 +1117,7 @@ uint GetCor20RuntimeVersion() { /// public int GetPointerSize(int defaultPointerSize, int prefer32bitPointerSize) { var machine = Machine; - if (machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64) + if (machine.Is64Bit()) return 8; if (machine != Machine.I386) return 4; diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index e432eca88..2293df148 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -30,7 +30,7 @@ sealed class ManagedExportsWriter { readonly CpuArch cpuArch; uint exportDirOffset; - bool Is64Bit => machine == Machine.IA64 || machine == Machine.AMD64 || machine == Machine.ARM64; + bool Is64Bit => machine.Is64Bit(); FileOffset ExportDirOffset => sdataChunk.FileOffset + exportDirOffset; RVA ExportDirRVA => sdataChunk.RVA + exportDirOffset; uint ExportDirSize => 0x28; diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 122de3b51..c847ab363 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -174,7 +174,7 @@ void CreateChunks() { peHeaders = new PEHeaders(Options.PEHeadersOptions); var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; - bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + bool is64bit = machine.Is64Bit(); relocDirectory = new RelocDirectory(machine); if (machine == Machine.I386) needStartupStub = true; @@ -197,7 +197,7 @@ void CreateChunks() { void AddChunksToSections() { var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; - bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + bool is64bit = machine.Is64Bit(); uint pointerAlignment = is64bit ? 8U : 4; if (mvidSection != null) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 7308a6c55..6341f8bb2 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -196,6 +196,7 @@ public StrongNamePublicKey StrongNamePublicKey { /// true if method bodies can be shared (two or more method bodies can share the /// same RVA), false if method bodies can't be shared. Don't enable it if there /// must be a 1:1 relationship with method bodies and their RVAs. + /// This is enabled by default and results in smaller files. /// public bool ShareMethodBodies { get; set; } @@ -212,9 +213,7 @@ public bool Is64Bit { get { if (!PEHeadersOptions.Machine.HasValue) return false; - return PEHeadersOptions.Machine == Machine.IA64 || - PEHeadersOptions.Machine == Machine.AMD64 || - PEHeadersOptions.Machine == Machine.ARM64; + return PEHeadersOptions.Machine.Value.Is64Bit(); } } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 148bc11ed..0c476fa28 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -467,10 +467,7 @@ public void WriteCheckSum(DataWriter writer, long length) { Machine GetMachine() => options.Machine ?? Machine.I386; - bool Use32BitOptionalHeader() { - var mach = GetMachine(); - return mach != Machine.IA64 && mach != Machine.AMD64 && mach != Machine.ARM64; - } + bool Use32BitOptionalHeader() => !GetMachine().Is64Bit(); Characteristics GetCharacteristics() { var chr = options.Characteristics ?? GetDefaultCharacteristics(); diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index 03c911a33..64ad033d7 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -83,7 +83,7 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public void WriteTo(DataWriter writer) { - bool is64bit = machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + bool is64bit = machine.Is64Bit(); // 3 = IMAGE_REL_BASED_HIGHLOW, A = IMAGE_REL_BASED_DIR64 uint relocType = is64bit ? 0xA000U : 0x3000; foreach (var pageList in relocSections) { diff --git a/src/PE/Machine.cs b/src/PE/Machine.cs index 439e8213f..0b563d46f 100644 --- a/src/PE/Machine.cs +++ b/src/PE/Machine.cs @@ -66,4 +66,17 @@ public enum Machine : ushort { /// CEE = 0xC0EE, } + + /// + /// Extensions + /// + public static class MachineExtensions { + /// + /// Checks if is a 64-bit machine + /// + /// Machine + /// + public static bool Is64Bit(this Machine machine) => + machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + } } From 7c4f05cdc851c3091e2116ec21f4976228e8bc71 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:56:40 +0100 Subject: [PATCH 165/511] Reuse bodies if the bodies are still identical --- src/DotNet/Writer/MethodBodyChunks.cs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index db692eb32..3b30f0e6e 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -17,6 +17,7 @@ public sealed class MethodBodyChunks : IChunk { readonly List tinyMethods; readonly List fatMethods; readonly List reusedMethods; + Dictionary rvaToReusedMethod; readonly bool shareBodies; FileOffset offset; RVA rva; @@ -63,6 +64,7 @@ public MethodBodyChunks(bool shareBodies) { tinyMethods = new List(); fatMethods = new List(); reusedMethods = new List(); + rvaToReusedMethod = new Dictionary(); } /// @@ -75,6 +77,17 @@ public MethodBodyChunks(bool shareBodies) { internal MethodBody Add(MethodBody methodBody, RVA origRva, uint origSize) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); + if (CanReuseOldBodyLocation && origRva != 0 && origSize != 0 && methodBody.CanReuse(origRva, origSize)) { + if (rvaToReusedMethod.TryGetValue((uint)origRva, out var reusedMethod)) { + if (methodBody.Equals(reusedMethod)) + return reusedMethod; + } + else { + rvaToReusedMethod.Add((uint)origRva, methodBody); + reusedMethods.Add(new ReusedMethodInfo(methodBody, origRva)); + return methodBody; + } + } if (shareBodies) { var dict = methodBody.IsFat ? fatMethodsDict : tinyMethodsDict; if (dict.TryGetValue(methodBody, out var cached)) { @@ -83,16 +96,9 @@ internal MethodBody Add(MethodBody methodBody, RVA origRva, uint origSize) { } dict[methodBody] = methodBody; } - bool reuseLoc = CanReuseOldBodyLocation && origRva != 0 && origSize != 0 && methodBody.CanReuse(origRva, origSize); - if (reuseLoc) { - reusedMethods.Add(new ReusedMethodInfo(methodBody, origRva)); - return methodBody; - } - else { - var list = methodBody.IsFat ? fatMethods : tinyMethods; - list.Add(methodBody); - return methodBody; - } + var list = methodBody.IsFat ? fatMethods : tinyMethods; + list.Add(methodBody); + return methodBody; } internal void InitializeReusedMethodBodies(IPEImage peImage, uint fileOffsetDelta) { From e3daff24c1ad2623122f36a583414609864a5ce9 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:56:51 +0100 Subject: [PATCH 166/511] Ignore empty debug dir entries --- src/DotNet/Writer/NativeModuleWriter.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index c604253f1..09d11bcce 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -498,16 +498,18 @@ static bool TryGetRealDebugDirectorySize(IPEImage peImage, out uint realSize) { var dirs = new List(peImage.ImageDebugDirectories); dirs.Sort((a, b) => a.AddressOfRawData.CompareTo(b.AddressOfRawData)); var debugDataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[6]; - if (dirs[0].AddressOfRawData != debugDataDir.VirtualAddress + debugDataDir.Size) - return false; - for (int i = 1; i < dirs.Count; i++) { - uint prevEnd = (uint)dirs[i - 1].AddressOfRawData + dirs[i - 1].SizeOfData; + var prevEnd = (uint)debugDataDir.VirtualAddress + debugDataDir.Size; + for (int i = 0; i < dirs.Count; i++) { uint prevEndAligned = (prevEnd + 3) & ~3U; - if (!(prevEnd <= (uint)dirs[i].AddressOfRawData && (uint)dirs[i].AddressOfRawData <= prevEndAligned)) + var dir = dirs[i]; + if (dir.AddressOfRawData == 0 || dir.SizeOfData == 0) + continue; + if (!(prevEnd <= (uint)dir.AddressOfRawData && (uint)dir.AddressOfRawData <= prevEndAligned)) return false; + prevEnd = (uint)dir.AddressOfRawData + dir.SizeOfData; } - realSize = dirs[dirs.Count - 1].AddressOfRawData + dirs[dirs.Count - 1].SizeOfData - debugDataDir.VirtualAddress; + realSize = prevEnd - (uint)debugDataDir.VirtualAddress; return true; } From 2d77cf04eb931b75574a8550cc714ec4c76eedf1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:57:01 +0100 Subject: [PATCH 167/511] Create reproducible PDBs with reproducible PDB IDs --- src/DotNet/MD/TableInfo.cs | 1 - src/DotNet/Writer/ArrayWriter.cs | 18 +++++ src/DotNet/Writer/ChecksumAlgorithm.cs | 28 ++++++++ src/DotNet/Writer/DebugDirectory.cs | 7 +- src/DotNet/Writer/Hasher.cs | 35 ++++++++++ src/DotNet/Writer/Metadata.cs | 9 +-- src/DotNet/Writer/ModuleWriter.cs | 6 -- src/DotNet/Writer/ModuleWriterBase.cs | 73 +++++++++++++++----- src/DotNet/Writer/PdbHeap.cs | 6 ++ src/DotNet/Writer/RoslynContentIdProvider.cs | 18 +++++ src/PE/ImageDebugType.cs | 2 +- src/dnlib.csproj | 3 + 12 files changed, 173 insertions(+), 33 deletions(-) create mode 100644 src/DotNet/Writer/ChecksumAlgorithm.cs create mode 100644 src/DotNet/Writer/Hasher.cs create mode 100644 src/DotNet/Writer/RoslynContentIdProvider.cs diff --git a/src/DotNet/MD/TableInfo.cs b/src/DotNet/MD/TableInfo.cs index 999e10824..1f15b5d0d 100644 --- a/src/DotNet/MD/TableInfo.cs +++ b/src/DotNet/MD/TableInfo.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; using System.Diagnostics; namespace dnlib.DotNet.MD { diff --git a/src/DotNet/Writer/ArrayWriter.cs b/src/DotNet/Writer/ArrayWriter.cs index a4c12b333..1e717accb 100644 --- a/src/DotNet/Writer/ArrayWriter.cs +++ b/src/DotNet/Writer/ArrayWriter.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System; using System.Diagnostics; namespace dnlib.DotNet.Writer { @@ -125,5 +126,22 @@ public void WriteDouble(double value) { *(double*)(p + position) = value; this.position = position + 8; } + + /// + /// Writes bytes + /// + /// Bytes + public void WriteBytes(byte[] source) => WriteBytes(source, 0, source.Length); + + /// + /// Writes bytes + /// + /// Bytes + /// Source index + /// Number of bytes to write + public void WriteBytes(byte[] source, int index, int length) { + Array.Copy(source, index, data, position, length); + position += length; + } } } diff --git a/src/DotNet/Writer/ChecksumAlgorithm.cs b/src/DotNet/Writer/ChecksumAlgorithm.cs new file mode 100644 index 000000000..c247797e0 --- /dev/null +++ b/src/DotNet/Writer/ChecksumAlgorithm.cs @@ -0,0 +1,28 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Writer { + /// + /// Checksum algorithm + /// + public enum ChecksumAlgorithm { + /// + /// SHA-1 + /// + SHA1, + + /// + /// SHA-256 + /// + SHA256, + + /// + /// SHA-384 + /// + SHA384, + + /// + /// SHA-512 + /// + SHA512, + } +} diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index e56539ebc..9cb5128df 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -148,9 +148,10 @@ public void WriteTo(DataWriter writer) { writer.WriteUInt16(entry.DebugDirectory.MajorVersion); writer.WriteUInt16(entry.DebugDirectory.MinorVersion); writer.WriteUInt32((uint)entry.DebugDirectory.Type); - writer.WriteUInt32(entry.Chunk.GetFileLength()); - writer.WriteUInt32((uint)entry.Chunk.RVA); - writer.WriteUInt32((uint)entry.Chunk.FileOffset); + uint length = entry.Chunk.GetFileLength(); + writer.WriteUInt32(length); + writer.WriteUInt32(length == 0 ? 0 : (uint)entry.Chunk.RVA); + writer.WriteUInt32(length == 0 ? 0 : (uint)entry.Chunk.FileOffset); offset += HEADER_SIZE; } diff --git a/src/DotNet/Writer/Hasher.cs b/src/DotNet/Writer/Hasher.cs new file mode 100644 index 000000000..ebe8fd533 --- /dev/null +++ b/src/DotNet/Writer/Hasher.cs @@ -0,0 +1,35 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; +using System.Security.Cryptography; + +namespace dnlib.DotNet.Writer { + static class Hasher { + static HashAlgorithm CreateHasher(ChecksumAlgorithm checksumAlgorithm) { + switch (checksumAlgorithm) { + case ChecksumAlgorithm.SHA1: return SHA1.Create(); + case ChecksumAlgorithm.SHA256: return SHA256.Create(); + case ChecksumAlgorithm.SHA384: return SHA384.Create(); + case ChecksumAlgorithm.SHA512: return SHA512.Create(); + default: throw new ArgumentOutOfRangeException(nameof(checksumAlgorithm)); + } + } + + public static byte[] Hash(ChecksumAlgorithm checksumAlgorithm, Stream stream, long length) { + var buffer = new byte[(int)Math.Min(0x2000, length)]; + using (var hasher = CreateHasher(checksumAlgorithm)) { + while (length > 0) { + int len = (int)Math.Min(length, buffer.Length); + int read = stream.Read(buffer, 0, len); + if (read == 0) + throw new InvalidOperationException("Couldn't read all bytes"); + hasher.TransformBlock(buffer, 0, read, buffer, 0); + length -= read; + } + hasher.TransformFinalBlock(Array2.Empty(), 0, 0); + return hasher.Hash; + } + } + } +} diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 9c49d657d..037829e64 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3363,16 +3363,12 @@ void AddLocalConstant(PdbConstant constant) { /// /// Output stream /// Entry point token - /// PDB ID, exactly 20 bytes - internal void WritePortablePdb(Stream output, uint entryPointToken, byte[] pdbId) { + /// Updated with the offset of the 20-byte PDB ID. The caller is responsible for initializing it with the PDB ID + internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdbIdOffset) { if (debugMetadata == null) throw new InvalidOperationException(); - if (pdbId.Length != 20) - throw new InvalidOperationException(); var pdbHeap = debugMetadata.PdbHeap; pdbHeap.EntryPoint = entryPointToken; - for (int i = 0; i < pdbId.Length; i++) - pdbHeap.PdbId[i] = pdbId[i]; tablesHeap.GetSystemTableRows(out ulong systemTablesMask, pdbHeap.TypeSystemTableRows); debugMetadata.tablesHeap.SetSystemTableRows(pdbHeap.TypeSystemTableRows); @@ -3383,6 +3379,7 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, byte[] pdbId debugMetadata.SetOffset(0, 0); debugMetadata.GetFileLength(); debugMetadata.VerifyWriteTo(writer); + pdbIdOffset = (long)pdbHeap.PdbIdOffset; } /// diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index c847ab363..bf20cf454 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -11,12 +11,6 @@ namespace dnlib.DotNet.Writer { /// options /// public sealed class ModuleWriterOptions : ModuleWriterOptionsBase { - /// - /// Default constructor - /// - public ModuleWriterOptions() { - } - /// /// Constructor /// diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 6341f8bb2..b1f8af56c 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -249,30 +249,32 @@ public bool Is64Bit { public Stream PdbStream { get; set; } /// - /// GUID used by some PDB writers, eg. portable PDB writer. It's initialized to a random GUID. + /// GUID used by some PDB writers, eg. portable PDB writer. If it's null, a deterministic PDB GUID is used. + /// This property is ignored if is true. /// - public Guid PdbGuid { get; set; } + public Guid? PdbGuid { get; set; } /// - /// true if an .mvid section should be added to the assembly. Not used by native module writer. + /// Create a reproducible PDB, if the PDB writer supports it. + /// If true, is ignored and a debug directory entry is added to the EXE/DLL file. /// - public bool AddMvidSection { get; set; } + public bool ReproduciblePdb { get; set; } /// - /// Default constructor + /// PDB checksum algorithm /// - protected ModuleWriterOptionsBase() { - ShareMethodBodies = true; - ModuleKind = ModuleKind.Windows; - PdbGuid = Guid.NewGuid(); - } + public ChecksumAlgorithm PdbChecksumAlgorithm { get; set; } = ChecksumAlgorithm.SHA256; + + /// + /// true if an .mvid section should be added to the assembly. Not used by native module writer. + /// + public bool AddMvidSection { get; set; } /// /// Constructor /// /// The module protected ModuleWriterOptionsBase(ModuleDef module) { - PdbGuid = Guid.NewGuid(); ShareMethodBodies = true; MetadataOptions.MetadataHeaderOptions.VersionString = module.RuntimeVersion; ModuleKind = module.Kind; @@ -336,6 +338,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PEHeadersOptions.Win32VersionValue = ntHeaders.OptionalHeader.Win32VersionValue; AddCheckSum = ntHeaders.OptionalHeader.CheckSum != 0; AddMvidSection = HasMvidSection(modDefMD.Metadata.PEImage.ImageSectionHeaders); + ReproduciblePdb = HasReproduciblePdb(modDefMD.Metadata.PEImage.ImageDebugDirectories); } if (Is64Bit) { @@ -360,6 +363,15 @@ static bool HasMvidSection(IList sections) { return false; } + static bool HasReproduciblePdb(IList debugDirs) { + int count = debugDirs.Count; + for (int i = 0; i < count; i++) { + if (debugDirs[i].Type == ImageDebugType.Reproducible) + return true; + } + return false; + } + /// /// Initializes and /// for normal strong name signing. @@ -751,7 +763,12 @@ protected void WritePdbFile() { } } + void AddReproduciblePdbDebugDirectoryEntry() => + debugDirectory.Add(Array2.Empty(), type: ImageDebugType.Reproducible, majorVersion: 0, minorVersion: 0, timeDateStamp: 0); + void WriteWindowsPdb(PdbState pdbState) { + bool reproduciblePdb = TheOptions.ReproduciblePdb; + reproduciblePdb = false;//TODO: If this is true, create a reproducible PDB writer var symWriter = GetWindowsPdbSymbolWriter(); if (symWriter == null) { Error("Could not create a PDB symbol writer. A Windows OS might be required."); @@ -766,6 +783,8 @@ void WriteWindowsPdb(PdbState pdbState) { var entry = debugDirectory.Add(data); entry.DebugDirectory = idd; entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); + if (reproduciblePdb) + AddReproduciblePdbDebugDirectoryEntry(); } } @@ -845,21 +864,43 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { else entryPointToken = new MDToken(Table.Method, metadata.GetRid(pdbState.UserEntryPoint)).Raw; + metadata.WritePortablePdb(pdbStream, entryPointToken, out var pdbIdOffset); + + Guid pdbGuid; var pdbId = new byte[20]; - var pdbIdWriter = new DataWriter(new MemoryStream(pdbId)); - var pdbGuid = TheOptions.PdbGuid; + var pdbIdWriter = new ArrayWriter(pdbId); + uint codeViewTimestamp; + if (TheOptions.ReproduciblePdb || TheOptions.PdbGuid == null) { + pdbStream.Position = 0; + var checksumBytes = Hasher.Hash(TheOptions.PdbChecksumAlgorithm, pdbStream, pdbStream.Length); + if (checksumBytes.Length < 20) + throw new ModuleWriterException("Checksum bytes length < 20"); + RoslynContentIdProvider.GetContentId(checksumBytes, out pdbGuid, out codeViewTimestamp); + } + else { + codeViewTimestamp = GetTimeDateStamp(); + pdbGuid = TheOptions.PdbGuid.Value; + } pdbIdWriter.WriteBytes(pdbGuid.ToByteArray()); - pdbIdWriter.WriteUInt32(GetTimeDateStamp()); + pdbIdWriter.WriteUInt32(codeViewTimestamp); Debug.Assert(pdbIdWriter.Position == pdbId.Length); + pdbStream.Position = pdbIdOffset; + pdbStream.Write(pdbId, 0, pdbId.Length); - metadata.WritePortablePdb(pdbStream, entryPointToken, pdbId); + // NOTE: We add these directory entries in the same order as Roslyn seems to do: + // - CodeView + // - Reproducible + // - EmbeddedPortablePdb const uint age = 1; debugDirectory.Add(GetCodeViewData(pdbGuid, age, pdbFilename), type: ImageDebugType.CodeView, majorVersion: PortablePdbConstants.FormatVersion, minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, - timeDateStamp: GetTimeDateStamp()); + timeDateStamp: codeViewTimestamp); + + if (TheOptions.ReproduciblePdb) + AddReproduciblePdbDebugDirectoryEntry(); if (isEmbeddedPortablePdb) { Debug.Assert(embeddedMemoryStream != null); diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs index a668410e3..f24aea426 100644 --- a/src/DotNet/Writer/PdbHeap.cs +++ b/src/DotNet/Writer/PdbHeap.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using dnlib.IO; namespace dnlib.DotNet.Writer { /// @@ -25,6 +26,11 @@ public uint EntryPoint { } uint entryPoint; + /// + /// Gets the offset of the 20-byte PDB ID + /// + public FileOffset PdbIdOffset => FileOffset; + /// /// Gets/sets the referenced type system tables /// diff --git a/src/DotNet/Writer/RoslynContentIdProvider.cs b/src/DotNet/Writer/RoslynContentIdProvider.cs new file mode 100644 index 000000000..68ca4b946 --- /dev/null +++ b/src/DotNet/Writer/RoslynContentIdProvider.cs @@ -0,0 +1,18 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Writer { + static class RoslynContentIdProvider { + public static void GetContentId(byte[] hash, out Guid guid, out uint timestamp) { + if (hash.Length < 20) + throw new InvalidOperationException(); + var guidBytes = new byte[16]; + Array.Copy(hash, 0, guidBytes, 0, guidBytes.Length); + guidBytes[7] = (byte)((guidBytes[7] & 0x0F) | 0x40); + guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80); + guid = new Guid(guidBytes); + timestamp = 0x80000000 | (uint)((hash[19] << 24) | (hash[18] << 16) | (hash[17] << 8) | hash[16]); + } + } +} diff --git a/src/PE/ImageDebugType.cs b/src/PE/ImageDebugType.cs index 0e2e82b45..11ca7396f 100644 --- a/src/PE/ImageDebugType.cs +++ b/src/PE/ImageDebugType.cs @@ -31,7 +31,7 @@ public enum ImageDebugType : uint { /// /// It's a deterministic (reproducible) PE file /// - Repro = 16, + Reproducible = 16, /// /// Embedded portable PDB data diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 618864cb6..fab3cec9b 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -305,6 +305,7 @@ + @@ -314,6 +315,7 @@ + @@ -348,6 +350,7 @@ + From 64ec15eff20611dee136974a3c2d27f28be3e871 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:57:10 +0100 Subject: [PATCH 168/511] Support the new PDB checksum debug dir entry, fixes #169 --- src/DotNet/Writer/Hasher.cs | 11 ++++++++ src/DotNet/Writer/ModuleWriterBase.cs | 37 +++++++++++++++++++++++---- src/PE/ImageDebugType.cs | 5 ++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Writer/Hasher.cs b/src/DotNet/Writer/Hasher.cs index ebe8fd533..49d40023f 100644 --- a/src/DotNet/Writer/Hasher.cs +++ b/src/DotNet/Writer/Hasher.cs @@ -16,6 +16,17 @@ static HashAlgorithm CreateHasher(ChecksumAlgorithm checksumAlgorithm) { } } + public static string GetChecksumName(ChecksumAlgorithm checksumAlgorithm) { + // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#pdb-checksum-debug-directory-entry-type-19 + switch (checksumAlgorithm) { + case ChecksumAlgorithm.SHA1: return "SHA1"; + case ChecksumAlgorithm.SHA256: return "SHA256"; + case ChecksumAlgorithm.SHA384: return "SHA384"; + case ChecksumAlgorithm.SHA512: return "SHA512"; + default: throw new ArgumentOutOfRangeException(nameof(checksumAlgorithm)); + } + } + public static byte[] Hash(ChecksumAlgorithm checksumAlgorithm, Stream stream, long length) { var buffer = new byte[(int)Math.Min(0x2000, length)]; using (var hasher = CreateHasher(checksumAlgorithm)) { diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index b1f8af56c..e8d7c3d8d 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -260,6 +260,11 @@ public bool Is64Bit { /// public bool ReproduciblePdb { get; set; } + /// + /// true to add a PDB checksum debug directory entry to the PE file + /// + public bool AddPdbChecksumDebugDirectoryEntry { get; set; } + /// /// PDB checksum algorithm /// @@ -338,7 +343,8 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PEHeadersOptions.Win32VersionValue = ntHeaders.OptionalHeader.Win32VersionValue; AddCheckSum = ntHeaders.OptionalHeader.CheckSum != 0; AddMvidSection = HasMvidSection(modDefMD.Metadata.PEImage.ImageSectionHeaders); - ReproduciblePdb = HasReproduciblePdb(modDefMD.Metadata.PEImage.ImageDebugDirectories); + ReproduciblePdb = HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.Reproducible); + AddPdbChecksumDebugDirectoryEntry = HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.PdbChecksum); } if (Is64Bit) { @@ -363,10 +369,10 @@ static bool HasMvidSection(IList sections) { return false; } - static bool HasReproduciblePdb(IList debugDirs) { + static bool HasDebugDirectoryEntry(IList debugDirs, ImageDebugType type) { int count = debugDirs.Count; for (int i = 0; i < count; i++) { - if (debugDirs[i].Type == ImageDebugType.Reproducible) + if (debugDirs[i].Type == type) return true; } return false; @@ -766,9 +772,22 @@ protected void WritePdbFile() { void AddReproduciblePdbDebugDirectoryEntry() => debugDirectory.Add(Array2.Empty(), type: ImageDebugType.Reproducible, majorVersion: 0, minorVersion: 0, timeDateStamp: 0); + void AddPdbChecksumDebugDirectoryEntry(byte[] checksumBytes, ChecksumAlgorithm checksumAlgorithm) { + var stream = new MemoryStream(); + var writer = new DataWriter(stream); + var checksumName = Hasher.GetChecksumName(checksumAlgorithm); + writer.WriteBytes(Encoding.UTF8.GetBytes(checksumName)); + writer.WriteByte(0); + writer.WriteBytes(checksumBytes); + var blob = stream.ToArray(); + debugDirectory.Add(blob, ImageDebugType.PdbChecksum, majorVersion: 1, minorVersion: 0, timeDateStamp: 0); + } + void WriteWindowsPdb(PdbState pdbState) { bool reproduciblePdb = TheOptions.ReproduciblePdb; reproduciblePdb = false;//TODO: If this is true, create a reproducible PDB writer + bool addPdbChecksumDebugDirectoryEntry = TheOptions.AddPdbChecksumDebugDirectoryEntry; + addPdbChecksumDebugDirectoryEntry = false;//TODO: If this is true, get the checksum from the PDB writer var symWriter = GetWindowsPdbSymbolWriter(); if (symWriter == null) { Error("Could not create a PDB symbol writer. A Windows OS might be required."); @@ -783,6 +802,8 @@ void WriteWindowsPdb(PdbState pdbState) { var entry = debugDirectory.Add(data); entry.DebugDirectory = idd; entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); + if (addPdbChecksumDebugDirectoryEntry) + {}//TODO: AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm);, and verify that the order of the debug dir entries is the same as Roslyn created binaries if (reproduciblePdb) AddReproduciblePdbDebugDirectoryEntry(); } @@ -870,9 +891,10 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { var pdbId = new byte[20]; var pdbIdWriter = new ArrayWriter(pdbId); uint codeViewTimestamp; - if (TheOptions.ReproduciblePdb || TheOptions.PdbGuid == null) { + byte[] checksumBytes; + if (TheOptions.ReproduciblePdb || TheOptions.AddPdbChecksumDebugDirectoryEntry || TheOptions.PdbGuid == null) { pdbStream.Position = 0; - var checksumBytes = Hasher.Hash(TheOptions.PdbChecksumAlgorithm, pdbStream, pdbStream.Length); + checksumBytes = Hasher.Hash(TheOptions.PdbChecksumAlgorithm, pdbStream, pdbStream.Length); if (checksumBytes.Length < 20) throw new ModuleWriterException("Checksum bytes length < 20"); RoslynContentIdProvider.GetContentId(checksumBytes, out pdbGuid, out codeViewTimestamp); @@ -880,6 +902,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { else { codeViewTimestamp = GetTimeDateStamp(); pdbGuid = TheOptions.PdbGuid.Value; + checksumBytes = null; } pdbIdWriter.WriteBytes(pdbGuid.ToByteArray()); pdbIdWriter.WriteUInt32(codeViewTimestamp); @@ -889,6 +912,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { // NOTE: We add these directory entries in the same order as Roslyn seems to do: // - CodeView + // - PdbChecksum // - Reproducible // - EmbeddedPortablePdb @@ -899,6 +923,9 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, timeDateStamp: codeViewTimestamp); + if (checksumBytes != null) + AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm); + if (TheOptions.ReproduciblePdb) AddReproduciblePdbDebugDirectoryEntry(); diff --git a/src/PE/ImageDebugType.cs b/src/PE/ImageDebugType.cs index 11ca7396f..33eaa2dbf 100644 --- a/src/PE/ImageDebugType.cs +++ b/src/PE/ImageDebugType.cs @@ -37,6 +37,11 @@ public enum ImageDebugType : uint { /// Embedded portable PDB data /// EmbeddedPortablePdb = 17, + + /// + /// Checksum of the PDB file. 0 or more entries allowed. + /// + PdbChecksum = 19, #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } } From 5b1492779aa27288668ade8874ecab883a5ee854 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 13:57:17 +0100 Subject: [PATCH 169/511] Remove CreateSymbolReader --- src/DotNet/ModuleCreationOptions.cs | 24 +++++------------------- src/DotNet/ModuleDefMD.cs | 6 ------ 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index a4c4e88c0..8a24db27f 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -17,31 +17,24 @@ public sealed class ModuleCreationOptions { /// public ModuleContext Context { get; set; } - /// - /// Set this if you want to decide how to create the PDB symbol reader. You don't need to - /// initialize or . - /// - public Func CreateSymbolReader { get; set; } - /// /// Which PDB reader to use. Default is . /// - public PdbImplType PdbImplementation { get; set; } + public PdbImplType PdbImplementation { get; set; } = PdbImplType.Default; /// /// Set it to A) the path (string) of the PDB file, B) the data (byte[]) of the PDB file or /// C) to an of the PDB data. The will /// be owned by the module. You don't need to initialize - /// or /// public object PdbFileOrData { get; set; } /// /// If true, will load the PDB file from disk if present, or an embedded portable PDB file /// stored in the PE file. The default value is true. - /// You don't need to initialize or . + /// You don't need to initialize . /// - public bool TryToLoadPdbFromDisk { get; set; } + public bool TryToLoadPdbFromDisk { get; set; } = true; /// /// corlib assembly reference to use or null if the default one from the opened @@ -52,19 +45,12 @@ public sealed class ModuleCreationOptions { /// /// Default constructor /// - public ModuleCreationOptions() { - PdbImplementation = PdbImplType.Default; - TryToLoadPdbFromDisk = true; - } + public ModuleCreationOptions() { } /// /// Constructor /// /// Module context - public ModuleCreationOptions(ModuleContext context) { - Context = context; - PdbImplementation = PdbImplType.Default; - TryToLoadPdbFromDisk = true; - } + public ModuleCreationOptions(ModuleContext context) => Context = context; } } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 9ec208fe8..ff3939d81 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -389,12 +389,6 @@ void InitializePdb(ModuleCreationOptions options) { } SymbolReader CreateSymbolReader(ModuleCreationOptions options) { - if (options.CreateSymbolReader != null) { - var symReader = options.CreateSymbolReader(this); - if (symReader != null) - return symReader; - } - if (options.PdbFileOrData != null) { var pdbFileName = options.PdbFileOrData as string; if (!string.IsNullOrEmpty(pdbFileName)) { From 2c763fc90765de0013d7499cd3f180f1903b7dfe Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 16:56:45 +0100 Subject: [PATCH 170/511] Remove PdbGuid and add a delegate to return the PDB content ID --- src/DotNet/Writer/ModuleWriterBase.cs | 39 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index e8d7c3d8d..c9a702af4 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -66,6 +66,31 @@ public ModuleWriterProgressEventArgs(ModuleWriterBase writer, double progress) { } } + /// + /// Content ID + /// + public readonly struct ContentId { + /// + /// Gets the GUID + /// + public readonly Guid Guid; + + /// + /// Gets the timestamp + /// + public readonly uint Timestamp; + + /// + /// Constructor + /// + /// Guid + /// Timestamp + public ContentId(Guid guid, uint timestamp) { + Guid = guid; + Timestamp = timestamp; + } + } + /// /// Common module writer options base class /// @@ -249,14 +274,15 @@ public bool Is64Bit { public Stream PdbStream { get; set; } /// - /// GUID used by some PDB writers, eg. portable PDB writer. If it's null, a deterministic PDB GUID is used. + /// Gets the PDB content id. The argument is the PDB stream with the PDB ID zeroed out, + /// and the 2nd argument is the default timestamp. /// This property is ignored if is true. /// - public Guid? PdbGuid { get; set; } + public Func GetPdbContentId { get; set; } /// /// Create a reproducible PDB, if the PDB writer supports it. - /// If true, is ignored and a debug directory entry is added to the EXE/DLL file. + /// If true, is ignored and a debug directory entry is added to the EXE/DLL file. /// public bool ReproduciblePdb { get; set; } @@ -892,7 +918,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { var pdbIdWriter = new ArrayWriter(pdbId); uint codeViewTimestamp; byte[] checksumBytes; - if (TheOptions.ReproduciblePdb || TheOptions.AddPdbChecksumDebugDirectoryEntry || TheOptions.PdbGuid == null) { + if (TheOptions.ReproduciblePdb || TheOptions.AddPdbChecksumDebugDirectoryEntry || TheOptions.GetPdbContentId == null) { pdbStream.Position = 0; checksumBytes = Hasher.Hash(TheOptions.PdbChecksumAlgorithm, pdbStream, pdbStream.Length); if (checksumBytes.Length < 20) @@ -900,8 +926,9 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { RoslynContentIdProvider.GetContentId(checksumBytes, out pdbGuid, out codeViewTimestamp); } else { - codeViewTimestamp = GetTimeDateStamp(); - pdbGuid = TheOptions.PdbGuid.Value; + var contentId = TheOptions.GetPdbContentId(pdbStream, GetTimeDateStamp()); + codeViewTimestamp = contentId.Timestamp; + pdbGuid = contentId.Guid; checksumBytes = null; } pdbIdWriter.WriteBytes(pdbGuid.ToByteArray()); From d512f4f32eb64f51d71ab0db7c1df354b847fe3b Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 16:56:54 +0100 Subject: [PATCH 171/511] Use the original PDB checksum algorithm by default --- src/DotNet/Writer/Hasher.cs | 29 +++++++++++++++++++++ src/DotNet/Writer/ModuleWriterBase.cs | 36 ++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Writer/Hasher.cs b/src/DotNet/Writer/Hasher.cs index 49d40023f..01749aa06 100644 --- a/src/DotNet/Writer/Hasher.cs +++ b/src/DotNet/Writer/Hasher.cs @@ -27,6 +27,35 @@ public static string GetChecksumName(ChecksumAlgorithm checksumAlgorithm) { } } + public static bool TryGetChecksumAlgorithm(string checksumName, out ChecksumAlgorithm pdbChecksumAlgorithm, out int checksumSize) { + switch (checksumName) { + case "SHA1": + pdbChecksumAlgorithm = ChecksumAlgorithm.SHA1; + checksumSize = 20; + return true; + + case "SHA256": + pdbChecksumAlgorithm = ChecksumAlgorithm.SHA256; + checksumSize = 32; + return true; + + case "SHA384": + pdbChecksumAlgorithm = ChecksumAlgorithm.SHA384; + checksumSize = 48; + return true; + + case "SHA512": + pdbChecksumAlgorithm = ChecksumAlgorithm.SHA512; + checksumSize = 64; + return true; + + default: + pdbChecksumAlgorithm = 0; + checksumSize = -1; + return false; + } + } + public static byte[] Hash(ChecksumAlgorithm checksumAlgorithm, Stream stream, long length) { var buffer = new byte[(int)Math.Min(0x2000, length)]; using (var hasher = CreateHasher(checksumAlgorithm)) { diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index c9a702af4..fd69c77ff 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -291,10 +291,12 @@ public bool Is64Bit { /// public bool AddPdbChecksumDebugDirectoryEntry { get; set; } + const ChecksumAlgorithm DefaultPdbChecksumAlgorithm = ChecksumAlgorithm.SHA256; + /// /// PDB checksum algorithm /// - public ChecksumAlgorithm PdbChecksumAlgorithm { get; set; } = ChecksumAlgorithm.SHA256; + public ChecksumAlgorithm PdbChecksumAlgorithm { get; set; } = DefaultPdbChecksumAlgorithm; /// /// true if an .mvid section should be added to the assembly. Not used by native module writer. @@ -371,6 +373,8 @@ protected ModuleWriterOptionsBase(ModuleDef module) { AddMvidSection = HasMvidSection(modDefMD.Metadata.PEImage.ImageSectionHeaders); ReproduciblePdb = HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.Reproducible); AddPdbChecksumDebugDirectoryEntry = HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.PdbChecksum); + if (TryGetPdbChecksumAlgorithm(modDefMD.Metadata.PEImage, modDefMD.Metadata.PEImage.ImageDebugDirectories, out var pdbChecksumAlgorithm)) + PdbChecksumAlgorithm = pdbChecksumAlgorithm; } if (Is64Bit) { @@ -404,6 +408,36 @@ static bool HasDebugDirectoryEntry(IList debugDirs, ImageDe return false; } + static bool TryGetPdbChecksumAlgorithm(IPEImage peImage, IList debugDirs, out ChecksumAlgorithm pdbChecksumAlgorithm) { + int count = debugDirs.Count; + for (int i = 0; i < count; i++) { + var dir = debugDirs[i]; + if (dir.Type == ImageDebugType.PdbChecksum) { + var reader = peImage.CreateReader(dir.AddressOfRawData, dir.SizeOfData); + if (TryGetPdbChecksumAlgorithm2(ref reader, out pdbChecksumAlgorithm)) + return true; + } + } + + pdbChecksumAlgorithm = DefaultPdbChecksumAlgorithm; + return false; + } + + static bool TryGetPdbChecksumAlgorithm2(ref DataReader reader, out ChecksumAlgorithm pdbChecksumAlgorithm) { + try { + var checksumName = reader.TryReadZeroTerminatedString(Encoding.UTF8); + if (Hasher.TryGetChecksumAlgorithm(checksumName, out pdbChecksumAlgorithm, out int checksumSize) && (uint)checksumSize == reader.BytesLeft) + return true; + } + catch (IOException) { + } + catch (ArgumentException) { + } + + pdbChecksumAlgorithm = DefaultPdbChecksumAlgorithm; + return false; + } + /// /// Initializes and /// for normal strong name signing. From d865c24eafa332bb3165866826864a89dcc9e355 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 16:57:01 +0100 Subject: [PATCH 172/511] Add UTF8 string reader methods --- src/DotNet/MethodExportInfoProvider.cs | 3 +-- src/DotNet/ModuleCreationOptions.cs | 2 -- src/DotNet/Pdb/Managed/NumericReader.cs | 3 +-- src/DotNet/Pdb/Managed/PdbReader.cs | 2 +- src/DotNet/Pdb/Portable/DocumentNameReader.cs | 2 +- src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs | 3 +-- .../Portable/PortablePdbCustomDebugInfoReader.cs | 5 ++--- .../Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 2 +- src/IO/DataReader.cs | 14 ++++++++++++++ 10 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/DotNet/MethodExportInfoProvider.cs b/src/DotNet/MethodExportInfoProvider.cs index cbcf4df1a..f56d86c0b 100644 --- a/src/DotNet/MethodExportInfoProvider.cs +++ b/src/DotNet/MethodExportInfoProvider.cs @@ -6,7 +6,6 @@ using dnlib.PE; using dnlib.IO; using System.Diagnostics; -using System.Text; namespace dnlib.DotNet { sealed class MethodExportInfoProvider { @@ -144,7 +143,7 @@ struct NameAndIndex { // If this method gets updated, also update the writer (ManagedExportsWriter) static string ReadMethodNameASCIIZ(ref DataReader reader, uint offset) { reader.Position = offset; - return reader.TryReadZeroTerminatedString(Encoding.UTF8) ?? string.Empty; + return reader.TryReadZeroTerminatedUtf8String() ?? string.Empty; } public MethodExportInfo GetMethodExportInfo(uint token) { diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 8a24db27f..964854a0d 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -2,8 +2,6 @@ using dnlib.IO; using dnlib.DotNet.Pdb; -using dnlib.DotNet.Pdb.Symbols; -using System; namespace dnlib.DotNet { /// diff --git a/src/DotNet/Pdb/Managed/NumericReader.cs b/src/DotNet/Pdb/Managed/NumericReader.cs index cf428f2ce..959a63f0b 100644 --- a/src/DotNet/Pdb/Managed/NumericReader.cs +++ b/src/DotNet/Pdb/Managed/NumericReader.cs @@ -1,6 +1,5 @@ // dnlib: See LICENSE.txt for more info -using System.Text; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { @@ -77,7 +76,7 @@ public static bool TryReadNumeric(ref DataReader reader, ulong end, out object v int varStrLen = reader.ReadUInt16(); if (position + (uint)varStrLen > end) return false; - value = reader.ReadString(varStrLen, Encoding.UTF8); + value = reader.ReadUtf8String(varStrLen); return true; case NumericLeaf.LF_VARIANT: diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 2519b8eac..2efae661f 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -294,7 +294,7 @@ void ApplyRidMap(ref DataReader reader) { } } - internal static string ReadCString(ref DataReader reader) => reader.TryReadZeroTerminatedString(Encoding.UTF8) ?? string.Empty; + internal static string ReadCString(ref DataReader reader) => reader.TryReadZeroTerminatedUtf8String() ?? string.Empty; public override SymbolMethod GetMethod(MethodDef method, int version) { if (functions.TryGetValue(method.MDToken.ToInt32(), out var symMethod)) diff --git a/src/DotNet/Pdb/Portable/DocumentNameReader.cs b/src/DotNet/Pdb/Portable/DocumentNameReader.cs index c80bac348..ae03645a5 100644 --- a/src/DotNet/Pdb/Portable/DocumentNameReader.cs +++ b/src/DotNet/Pdb/Portable/DocumentNameReader.cs @@ -53,7 +53,7 @@ string ReadDocumentNamePart(uint offset) { return name; if (!blobStream.TryCreateReader(offset, out var reader)) return string.Empty; - name = reader.ReadString((int)reader.BytesLeft, Encoding.UTF8); + name = reader.ReadUtf8String((int)reader.BytesLeft); docNamePartDict.Add(offset, name); return name; } diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index 1ed413a07..7ce632f24 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Text; using dnlib.DotNet.MD; namespace dnlib.DotNet.Pdb.Portable { @@ -128,7 +127,7 @@ AssemblyRef TryReadAssemblyRef(uint rid) { string ReadUTF8(uint offset) { if (!blobStream.TryCreateReader(offset, out var reader)) return string.Empty; - return reader.ReadString((int)reader.BytesLeft, Encoding.UTF8); + return reader.ReadUtf8String((int)reader.BytesLeft); } } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index 970a298fb..beb02a7cb 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; using System.IO; -using System.Text; using dnlib.DotNet.Emit; using dnlib.DotNet.MD; using dnlib.IO; @@ -110,7 +109,7 @@ PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { } PdbCustomDebugInfo ReadDefaultNamespace() { - var defaultNs = reader.ReadString((int)reader.BytesLeft, Encoding.UTF8); + var defaultNs = reader.ReadUtf8String((int)reader.BytesLeft); return new PdbDefaultNamespaceCustomDebugInfo(defaultNs); } @@ -173,7 +172,7 @@ PdbCustomDebugInfo ReadTupleElementNames() { string ReadUTF8Z(long recPosEnd) { if (reader.Position > recPosEnd) return null; - return reader.TryReadZeroTerminatedString(Encoding.UTF8); + return reader.TryReadZeroTerminatedUtf8String(); } Instruction GetInstruction(uint offset) { diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index dbbb8cf37..f11fa6c66 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -317,7 +317,7 @@ string ReadUnicodeZ(ulong recPosEnd, bool needZeroChar) { string ReadUTF8Z(ulong recPosEnd) { if (reader.Position > recPosEnd) return null; - return reader.TryReadZeroTerminatedString(Encoding.UTF8); + return reader.TryReadZeroTerminatedUtf8String(); } Instruction GetInstruction(uint offset) { diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index fd69c77ff..b1fe4ba3f 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -425,7 +425,7 @@ static bool TryGetPdbChecksumAlgorithm(IPEImage peImage, IList + /// Reads a zero-terminated UTF-8 string or returns null if the string couldn't be read. + /// If successful, the current offset is incremented past the terminating zero. + /// + /// + public string TryReadZeroTerminatedUtf8String() => TryReadZeroTerminatedString(Encoding.UTF8); + /// /// Reads a zero-terminated string or returns null if the string couldn't be read. /// If successful, the current offset is incremented past the terminating zero. @@ -749,6 +756,13 @@ public string TryReadZeroTerminatedString(Encoding encoding) { return value; } + /// + /// Reads a UTF-8 encoded string + /// + /// Number of bytes to read (not characters) + /// + public string ReadUtf8String(int byteCount) => ReadString(byteCount, Encoding.UTF8); + /// /// Reads a string /// From 217d621ac275d2e32adedec2f5a3a3af185d6b9f Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 21:14:40 +0100 Subject: [PATCH 173/511] Update RVAs --- src/DotNet/Writer/NativeModuleWriter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 09d11bcce..60ac5ff2d 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -448,6 +448,7 @@ long WriteFile() { metadata.UpdateMethodAndFieldRvas(); } CalculateRvasAndFileOffsets(chunks, 0, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); + metadata.UpdateMethodAndFieldRvas(); foreach (var section in origSections) { if (section.Chunk.RVA != section.PESection.VirtualAddress) throw new ModuleWriterException("Invalid section RVA"); From 70edda79c46ed88d0c71bbaf84de944f2fe69638 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 21 Mar 2018 22:53:21 +0100 Subject: [PATCH 174/511] Call other overload --- src/IO/DataReader.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index be72f3c23..48c08e5c9 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -802,6 +802,8 @@ public string ReadString(int byteCount, Encoding encoding) { public void CopyTo(DataWriter destination) { if (destination == null) ThrowArgumentNullException(nameof(destination)); + if (Position >= Length) + return; CopyTo(destination.InternalStream, AllocTempBuffer()); } @@ -827,7 +829,7 @@ public void CopyTo(BinaryWriter destination) { ThrowArgumentNullException(nameof(destination)); if (Position >= Length) return; - CopyTo(destination, AllocTempBuffer()); + CopyTo(destination.BaseStream, AllocTempBuffer()); } /// @@ -839,17 +841,7 @@ public void CopyTo(BinaryWriter destination) { public void CopyTo(BinaryWriter destination, byte[] dataBuffer) { if (destination == null) ThrowArgumentNullException(nameof(destination)); - if (dataBuffer == null) - ThrowArgumentNullException(nameof(dataBuffer)); - if (Position >= Length) - return; - uint lenLeft = BytesLeft; - while (lenLeft > 0) { - int num = (int)Math.Min((uint)dataBuffer.Length, lenLeft); - lenLeft -= (uint)num; - ReadBytes(dataBuffer, 0, num); - destination.Write(dataBuffer, 0, num); - } + CopyTo(destination.BaseStream, dataBuffer); } /// From 0ef4448e173dfca8814c9c515942640e558bd046 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 22 Mar 2018 19:22:58 +0100 Subject: [PATCH 175/511] Make fields readonly --- src/DotNet/AssemblyNameComparer.cs | 6 +++--- src/DotNet/Writer/ModuleWriterBase.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DotNet/AssemblyNameComparer.cs b/src/DotNet/AssemblyNameComparer.cs index 65224c2c3..60088cb89 100644 --- a/src/DotNet/AssemblyNameComparer.cs +++ b/src/DotNet/AssemblyNameComparer.cs @@ -47,17 +47,17 @@ public enum AssemblyNameComparerFlags { /// /// Compares the name, version, public key token, culture and content type /// - public static AssemblyNameComparer CompareAll = new AssemblyNameComparer(AssemblyNameComparerFlags.All); + public static readonly AssemblyNameComparer CompareAll = new AssemblyNameComparer(AssemblyNameComparerFlags.All); /// /// Compares only the name and the public key token /// - public static AssemblyNameComparer NameAndPublicKeyTokenOnly = new AssemblyNameComparer(AssemblyNameComparerFlags.Name | AssemblyNameComparerFlags.PublicKeyToken); + public static readonly AssemblyNameComparer NameAndPublicKeyTokenOnly = new AssemblyNameComparer(AssemblyNameComparerFlags.Name | AssemblyNameComparerFlags.PublicKeyToken); /// /// Compares only the name /// - public static AssemblyNameComparer NameOnly = new AssemblyNameComparer(AssemblyNameComparerFlags.Name); + public static readonly AssemblyNameComparer NameOnly = new AssemblyNameComparer(AssemblyNameComparerFlags.Name); readonly AssemblyNameComparerFlags flags; diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index b1fe4ba3f..668954d4a 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -414,7 +414,7 @@ static bool TryGetPdbChecksumAlgorithm(IPEImage peImage, IList Date: Fri, 23 Mar 2018 18:07:20 +0100 Subject: [PATCH 176/511] Scope end is only inclusive if it's a Windows PDB and compiler is VB --- src/DotNet/Pdb/PdbState.cs | 5 ++++- src/DotNet/Pdb/PdbUtils.cs | 8 ++++++++ src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 2 +- src/dnlib.csproj | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/DotNet/Pdb/PdbUtils.cs diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 787ba2a19..19842612b 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -17,6 +17,7 @@ public sealed class PdbState { readonly Dictionary docDict = new Dictionary(); MethodDef userEntryPoint; readonly Compiler compiler; + readonly PdbFileKind originalPdbFileKind; #if THREAD_SAFE readonly Lock theLock = Lock.Create(); @@ -77,6 +78,7 @@ public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { throw new ArgumentNullException(nameof(module)); compiler = CalculateCompiler(module); PdbFileKind = pdbFileKind; + originalPdbFileKind = pdbFileKind; } /// @@ -90,6 +92,7 @@ public PdbState(SymbolReader reader, ModuleDefMD module) { this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); reader.Initialize(module); PdbFileKind = reader.PdbFileKind; + originalPdbFileKind = reader.PdbFileKind; compiler = CalculateCompiler(module); userEntryPoint = module.ResolveToken(reader.UserEntryPoint) as MethodDef; @@ -257,9 +260,9 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody // Don't use recursive calls var stack = new Stack(); var state = new CreateScopeState() { SymScope = symScope }; + int endIsInclusiveValue = PdbUtils.IsEndInclusive(originalPdbFileKind, Compiler) ? 1 : 0; recursive_call: int instrIndex = 0; - int endIsInclusiveValue = Compiler == Compiler.VisualBasic ? 1 : 0; state.PdbScope = new PdbScope() { Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), diff --git a/src/DotNet/Pdb/PdbUtils.cs b/src/DotNet/Pdb/PdbUtils.cs new file mode 100644 index 000000000..777485300 --- /dev/null +++ b/src/DotNet/Pdb/PdbUtils.cs @@ -0,0 +1,8 @@ +// dnlib: See LICENSE.txt for more info + +namespace dnlib.DotNet.Pdb { + static class PdbUtils { + public static bool IsEndInclusive(PdbFileKind pdbFileKind, Compiler compiler) => + pdbFileKind == PdbFileKind.WindowsPDB && compiler == Compiler.VisualBasic; + } +} diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index b4d7d8184..6b364bbdf 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -50,7 +50,7 @@ public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, Metadata metad module = metadata.Module; instrToOffset = new Dictionary(); customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); - localsEndScopeIncValue = pdbState.Compiler == Compiler.VisualBasic ? 1 : 0; + localsEndScopeIncValue = PdbUtils.IsEndInclusive(PdbFileKind.WindowsPDB, pdbState.Compiler) ? 1 : 0; } /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index fab3cec9b..551788c58 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -191,6 +191,7 @@ + From 67c6358e8fc65b3e6c020d6363c870209428ebce Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 24 Mar 2018 20:48:28 +0100 Subject: [PATCH 177/511] Use struct EventArgs --- src/DotNet/Writer/Metadata.cs | 8 ++++---- src/DotNet/Writer/ModuleWriterBase.cs | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 037829e64..77e81d292 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -276,7 +276,7 @@ public enum DebugMetadataKind { /// /// Metadata writer event args /// - public sealed class MetadataWriterEventArgs : EventArgs { + public readonly struct MetadataWriterEventArgs { /// /// Gets the metadata writer /// @@ -301,7 +301,7 @@ public MetadataWriterEventArgs(Metadata metadata, MetadataEvent @event) { /// /// Metadata writer progress event args /// - public sealed class MetadataProgressEventArgs : EventArgs { + public readonly struct MetadataProgressEventArgs { /// /// Gets the metadata writer /// @@ -390,12 +390,12 @@ public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenCrea /// /// Raised at various times when writing the metadata /// - public event EventHandler MetadataEvent; + public event EventHandler2 MetadataEvent; /// /// Raised when the progress is updated /// - public event EventHandler ProgressUpdated; + public event EventHandler2 ProgressUpdated; /// /// Gets/sets the logger diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 668954d4a..7ca7c782c 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -17,7 +17,7 @@ namespace dnlib.DotNet.Writer { /// /// Module writer event args /// - public sealed class ModuleWriterEventArgs : EventArgs { + public readonly struct ModuleWriterEventArgs { /// /// Gets the writer ( or ) /// @@ -42,7 +42,7 @@ public ModuleWriterEventArgs(ModuleWriterBase writer, ModuleWriterEvent @event) /// /// Module writer progress event args /// - public sealed class ModuleWriterProgressEventArgs : EventArgs { + public readonly struct ModuleWriterProgressEventArgs { /// /// Gets the writer ( or ) /// @@ -91,6 +91,14 @@ public ContentId(Guid guid, uint timestamp) { } } + /// + /// Event handler + /// + /// Event args type + /// Sender + /// Event args + public delegate void EventHandler2(object sender, TEventArgs e); + /// /// Common module writer options base class /// @@ -119,13 +127,13 @@ public IModuleWriterListener Listener { /// Raised at various times when writing the file. The listener has a chance to modify /// the file, eg. add extra metadata, encrypt methods, etc. /// - public event EventHandler WriterEvent; + public event EventHandler2 WriterEvent; internal void RaiseEvent(object sender, ModuleWriterEventArgs e) => WriterEvent?.Invoke(sender, e); /// /// Raised when the progress is updated /// - public event EventHandler ProgressUpdated; + public event EventHandler2 ProgressUpdated; internal void RaiseEvent(object sender, ModuleWriterProgressEventArgs e) => ProgressUpdated?.Invoke(sender, e); /// From d907fcce7801592b1406fd5720a1145cc3799ddd Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 24 Mar 2018 20:48:45 +0100 Subject: [PATCH 178/511] Add an option to ignore a MD array's lower bounds and sizes --- src/DotNet/SigComparer.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 3d2547a67..34a7d2e59 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -486,6 +486,11 @@ public enum SigComparerOptions : uint { /// types can be considered equivalent if eg. a TypeIdentifierAttribute is used. /// DontCheckTypeEquivalence = 0x400000, + + /// + /// When comparing types, don't compare a multi-dimensional array's lower bounds and sizes + /// + IgnoreMultiDimensionalArrayLowerBoundsAndSizes = 0x800000, } /// @@ -533,6 +538,7 @@ public struct SigComparer { bool MscorlibIsNotSpecial => (options & SigComparerOptions.MscorlibIsNotSpecial) != 0; bool DontProjectWinMDRefs => (options & SigComparerOptions.DontProjectWinMDRefs) != 0; bool DontCheckTypeEquivalence => (options & SigComparerOptions.DontCheckTypeEquivalence) != 0; + bool IgnoreMultiDimensionalArrayLowerBoundsAndSizes => (options & SigComparerOptions.IgnoreMultiDimensionalArrayLowerBoundsAndSizes) != 0; /// /// Constructor @@ -1911,8 +1917,9 @@ public bool Equals(TypeSig a, TypeSig b) { case ElementType.Array: ArraySig ara = a as ArraySig, arb = b as ArraySig; result = ara.Rank == arb.Rank && - Equals(ara.Sizes, arb.Sizes) && - Equals(ara.LowerBounds, arb.LowerBounds) && + (IgnoreMultiDimensionalArrayLowerBoundsAndSizes || + (Equals(ara.Sizes, arb.Sizes) && + Equals(ara.LowerBounds, arb.LowerBounds))) && Equals(a.Next, b.Next); break; @@ -2057,6 +2064,7 @@ public int GetHashCode(TypeSig a) { case ElementType.Array: // Don't include sizes and lower bounds since GetHashCode(Type) doesn't (and can't). + // Also, if IgnoreMultiDimensionArrayLowerBoundsAndSizes is set, we shouldn't include them either. var ara = (ArraySig)a; hash = HASHCODE_MAGIC_ET_ARRAY + (int)ara.Rank + GetHashCode(ara.Next); break; From 303c26093979ef40b7e0fd5a058b84818013d8ee Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 27 Mar 2018 15:25:56 +0200 Subject: [PATCH 179/511] Ignore sealed when checking for value types and enums --- src/DotNet/TypeDef.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 867aabda2..da371d725 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -580,7 +580,8 @@ public uint ClassSize { public bool IsValueType { get { // Don't include abstract since value types can be abstract without throwing at runtime - if ((Attributes & (TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + // Also don't check for sealed, since the CLR doesn't throw at runtime + if ((Attributes & TypeAttributes.ClassSemanticsMask) != TypeAttributes.Class) return false; var baseType = BaseType; if (baseType == null) @@ -623,7 +624,8 @@ public bool IsValueType { public bool IsEnum { get { // Don't include abstract since value types can be abstract without throwing at runtime - if ((Attributes & (TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + // Also don't check for sealed, since the CLR doesn't throw at runtime + if ((Attributes & TypeAttributes.ClassSemanticsMask) != TypeAttributes.Class) return false; var baseType = BaseType; if (baseType == null) @@ -645,7 +647,7 @@ public bool IsEnum { /// public bool IsDelegate { get { - if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.ClassSemanticsMask)) != (TypeAttributes.Sealed | TypeAttributes.Class)) + if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.ClassSemanticsMask)) != TypeAttributes.Class) return false; var baseType = BaseType; if (baseType == null) From 26f35f0ec30b506a7393eba1992416baffae7366 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 11:21:00 +0200 Subject: [PATCH 180/511] Add MD writer method that preserves order of original custom heaps --- README.md | 1 + src/DotNet/Writer/DataReaderHeap.cs | 48 +++++++++++++++ src/DotNet/Writer/Metadata.cs | 91 +++++++++++++++++++++++++---- src/dnlib.csproj | 1 + 4 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 src/DotNet/Writer/DataReaderHeap.cs diff --git a/README.md b/README.md index b243f3706..dcf57e25f 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ v3.0 breaking changes - `MethodBodyWriterBase` uses `ArrayWriter` instead of `BinaryWriter` (all virtual methods) - `ModuleWriter` and `NativeModuleWriter` use `DataWriter` instead of `BinaryWriter` - The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` +- `MetadataOptions`'s `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded`, and `PreserveHeapOrder()` instead. Examples -------- diff --git a/src/DotNet/Writer/DataReaderHeap.cs b/src/DotNet/Writer/DataReaderHeap.cs new file mode 100644 index 000000000..684d76bcf --- /dev/null +++ b/src/DotNet/Writer/DataReaderHeap.cs @@ -0,0 +1,48 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using dnlib.DotNet.MD; +using dnlib.IO; + +namespace dnlib.DotNet.Writer { + /// + /// Copies existing data to a new metadata heap + /// + public sealed class DataReaderHeap : HeapBase { + /// + /// Gets the name of the heap + /// + public override string Name { get; } + + internal DotNetStream OptionalOriginalStream { get; } + + readonly DataReader heapReader; + + /// + /// Constructor + /// + /// The stream whose data will be copied to the new metadata file + public DataReaderHeap(DotNetStream stream) { + OptionalOriginalStream = stream ?? throw new ArgumentNullException(nameof(stream)); + heapReader = stream.GetReader(); + Name = stream.Name; + } + + /// + /// Constructor + /// + /// Heap name + /// Heap content + public DataReaderHeap(string name, DataReader heapReader) { + this.heapReader = heapReader; + this.heapReader.Position = 0; + Name = name; + } + + /// + public override uint GetRawLength() => heapReader.Length; + + /// + protected override void WriteToImpl(DataWriter writer) => heapReader.CopyTo(writer); + } +} diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 77e81d292..2f429ef91 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -11,6 +11,7 @@ using System.Diagnostics; using dnlib.DotNet.Pdb; using dnlib.DotNet.Pdb.Portable; +using System.Linq; namespace dnlib.DotNet.Writer { /// @@ -163,6 +164,31 @@ public enum MetadataFlags : uint { RoslynSortInterfaceImpl = 0x100000, } + /// + /// Metadata heaps event args + /// + public readonly struct MetadataHeapsAddedEventArgs { + /// + /// Gets the metadata writer + /// + public Metadata Metadata { get; } + + /// + /// Gets all heaps + /// + public List Heaps { get; } + + /// + /// Constructor + /// + /// Metadata writer + /// All heaps + public MetadataHeapsAddedEventArgs(Metadata metadata, List heaps) { + Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); + Heaps = heaps ?? throw new ArgumentNullException(nameof(heaps)); + } + } + /// /// options /// @@ -170,8 +196,7 @@ public sealed class MetadataOptions { MetadataHeaderOptions metadataHeaderOptions; MetadataHeaderOptions debugMetadataHeaderOptions; TablesHeapOptions tablesHeapOptions; - List otherHeaps; - List otherHeapsEnd; + List customHeaps; /// /// Gets/sets the options. This is never null. @@ -211,14 +236,61 @@ public TablesHeapOptions DebugTablesHeapOptions { public MetadataFlags Flags; /// - /// Any additional heaps that should be added to the beginning of the heaps list + /// Extra heaps to add to the metadata. Also see and /// - public List OtherHeaps => otherHeaps ?? (otherHeaps = new List()); + public List CustomHeaps => customHeaps ?? (customHeaps = new List()); /// - /// Any additional heaps that should be added to end of the heaps list + /// Raised after all heaps have been added. The caller can sort the list if needed /// - public List OtherHeapsEnd => otherHeapsEnd ?? (otherHeapsEnd = new List()); + public event EventHandler2 MetadataHeapsAdded; + internal void RaiseMetadataHeapsAdded(MetadataHeapsAddedEventArgs e) => MetadataHeapsAdded?.Invoke(e.Metadata, e); + + /// + /// Preserves the original order of heaps, and optionally adds all custom heaps to . + /// + /// Original module with the heaps + /// If true, all custom streams are added to + public void PreserveHeapOrder(ModuleDef module, bool addCustomHeaps) { + if (module == null) + throw new ArgumentNullException(nameof(module)); + if (module is ModuleDefMD mod) { + if (addCustomHeaps) { + var otherStreams = mod.Metadata.AllStreams.Where(a => a.GetType() == typeof(DotNetStream)).Select(a => new DataReaderHeap(a)); + CustomHeaps.AddRange(otherStreams.OfType()); + } + var streamToOrder = new Dictionary(mod.Metadata.AllStreams.Count); + for (int i = 0; i < mod.Metadata.AllStreams.Count; i++) + streamToOrder.Add(mod.Metadata.AllStreams[i], i); + var nameToOrder = new Dictionary(mod.Metadata.AllStreams.Count, StringComparer.Ordinal); + for (int i = 0; i < mod.Metadata.AllStreams.Count; i++) { + var stream = mod.Metadata.AllStreams[i]; + bool isKnownStream = stream is BlobStream || stream is GuidStream || + stream is PdbStream || stream is StringsStream || stream is TablesStream || stream is USStream; + if (!nameToOrder.ContainsKey(stream.Name) || isKnownStream) + nameToOrder[stream.Name] = i; + } + MetadataHeapsAdded += (s, e) => { + e.Heaps.Sort((a, b) => { + int oa = GetOrder(streamToOrder, nameToOrder, a); + int ob = GetOrder(streamToOrder, nameToOrder, b); + int c = oa - ob; + if (c != 0) + return c; + return StringComparer.Ordinal.Compare(a.Name, b.Name); + }); + }; + } + } + + static int GetOrder(Dictionary streamToOrder, Dictionary nameToOrder, IHeap heap) { + if (heap is DataReaderHeap drHeap && drHeap.OptionalOriginalStream is DotNetStream dnHeap && streamToOrder.TryGetValue(dnHeap, out int order)) + return order; + if (nameToOrder.TryGetValue(heap.Name, out order)) + return order; + + return int.MaxValue; + } /// /// Default constructor @@ -3543,9 +3615,6 @@ IList GetHeaps() { heaps.Add(blobHeap); } else { - if (options.OtherHeaps != null) - heaps.AddRange(options.OtherHeaps); - heaps.Add(tablesHeap); if (!stringsHeap.IsEmpty || AlwaysCreateStringsHeap) heaps.Add(stringsHeap); @@ -3556,8 +3625,8 @@ IList GetHeaps() { if (!blobHeap.IsEmpty || AlwaysCreateBlobHeap) heaps.Add(blobHeap); - if (options.OtherHeapsEnd != null) - heaps.AddRange(options.OtherHeapsEnd); + heaps.AddRange(options.CustomHeaps); + options.RaiseMetadataHeapsAdded(new MetadataHeapsAddedEventArgs(this, heaps)); } return heaps; diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 551788c58..2c6b15e2e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -311,6 +311,7 @@ + From 54a987ebb1fbd30af4ee25b1f850521ec9108459 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 11:31:33 +0200 Subject: [PATCH 181/511] Update examples --- Examples/Example6.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Examples/Example6.cs b/Examples/Example6.cs index b74f8e386..35677f8f5 100644 --- a/Examples/Example6.cs +++ b/Examples/Example6.cs @@ -37,12 +37,15 @@ void DoIt() { opts.MetadataOptions.TablesHeapOptions.ExtraData = 0x12345678; // Add a few dummy heaps - opts.MetadataOptions.OtherHeaps.Add(new MyHeap("#US ")); - opts.MetadataOptions.OtherHeaps.Add(new MyHeap("#Strings ")); - opts.MetadataOptions.OtherHeaps.Add(new MyHeap("#Strimgs")); - opts.MetadataOptions.OtherHeaps.Add(new MyHeap("#GU1D")); - opts.MetadataOptions.OtherHeapsEnd.Add(new MyHeap("#US ")); - opts.MetadataOptions.OtherHeapsEnd.Add(new MyHeap("#Strings ")); + opts.MetadataOptions.CustomHeaps.Add(new MyHeap("#US ")); + opts.MetadataOptions.CustomHeaps.Add(new MyHeap("#Strings ")); + opts.MetadataOptions.CustomHeaps.Add(new MyHeap("#Strimgs")); + opts.MetadataOptions.CustomHeaps.Add(new MyHeap("#GU1D")); + opts.MetadataOptions.CustomHeaps.Add(new MyHeap("#US ")); + opts.MetadataOptions.CustomHeaps.Add(new MyHeap("#Strings ")); + opts.MetadataOptions.MetadataHeapsAdded += (s, e) => { + // You could sort the heaps here + }; // Write the module. The listener will get notified, see OnWriterEvent() below mod.Write(destFileName, opts); From a7bb549f27405d396b3639d56905c5f0ad2593f1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 12:28:56 +0200 Subject: [PATCH 182/511] Rename --- src/DotNet/CustomAttributeReader.cs | 2 +- src/DotNet/MD/BlobStream.cs | 2 +- src/DotNet/MD/USStream.cs | 2 +- .../Portable/LocalConstantSigBlobReader.cs | 4 +-- src/DotNet/SignatureReader.cs | 30 +++++++++---------- src/DotNet/Writer/BlobHeap.cs | 2 +- src/DotNet/Writer/USHeap.cs | 2 +- src/IO/DataReader.cs | 8 ++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 813cc0099..5a1e8c238 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -586,7 +586,7 @@ UTF8String ReadUTF8String() { if (reader.ReadByte() == 0xFF) return null; reader.Position--; - if (!reader.ReadCompressedUInt32(out uint len)) + if (!reader.TryReadCompressedUInt32(out uint len)) throw new CABlobParserException("Could not read compressed UInt32"); if (len == 0) return UTF8String.Empty; diff --git a/src/DotNet/MD/BlobStream.cs b/src/DotNet/MD/BlobStream.cs index 7f3a86fcc..51019276a 100644 --- a/src/DotNet/MD/BlobStream.cs +++ b/src/DotNet/MD/BlobStream.cs @@ -61,7 +61,7 @@ public bool TryCreateReader(uint offset, out DataReader reader) { if (!IsValidOffset(offset)) return false; reader.Position = offset; - if (!reader.ReadCompressedUInt32(out uint length)) + if (!reader.TryReadCompressedUInt32(out uint length)) return false; if (!reader.CanRead(length)) return false; diff --git a/src/DotNet/MD/USStream.cs b/src/DotNet/MD/USStream.cs index 67fefa2ab..9a3189843 100644 --- a/src/DotNet/MD/USStream.cs +++ b/src/DotNet/MD/USStream.cs @@ -29,7 +29,7 @@ public string Read(uint offset) { return null; var reader = dataReader; reader.Position = offset; - if (!reader.ReadCompressedUInt32(out uint length)) + if (!reader.TryReadCompressedUInt32(out uint length)) return null; if (!reader.CanRead(length)) return null; diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index 438c9b848..df4e879fb 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -267,7 +267,7 @@ static bool GetName(ITypeDefOrRef tdr, out UTF8String @namespace, out UTF8String TypeSig ReadTypeDefOrRefSig() { uint codedToken; - if (!reader.ReadCompressedUInt32(out codedToken)) + if (!reader.TryReadCompressedUInt32(out codedToken)) return null; ISignatureReaderHelper helper = module; var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); @@ -276,7 +276,7 @@ TypeSig ReadTypeDefOrRefSig() { ITypeDefOrRef ReadTypeDefOrRef() { uint codedToken; - if (!reader.ReadCompressedUInt32(out codedToken)) + if (!reader.TryReadCompressedUInt32(out codedToken)) return null; ISignatureReaderHelper helper = module; var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 3ceecc648..f8acbbc5c 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -477,12 +477,12 @@ CallingConventionSig ReadSig() { T ReadSig(T methodSig) where T : MethodBaseSig { if (methodSig.Generic) { - if (!reader.ReadCompressedUInt32(out uint count)) + if (!reader.TryReadCompressedUInt32(out uint count)) return null; methodSig.GenParamCount = count; } - if (!reader.ReadCompressedUInt32(out uint numParams)) + if (!reader.TryReadCompressedUInt32(out uint numParams)) return null; methodSig.RetType = ReadType(); @@ -508,7 +508,7 @@ T ReadSig(T methodSig) where T : MethodBaseSig { /// First byte of signature /// A new instance LocalSig ReadLocalSig(CallingConvention callingConvention) { - if (!reader.ReadCompressedUInt32(out uint count)) + if (!reader.TryReadCompressedUInt32(out uint count)) return null; var sig = new LocalSig(callingConvention, count); var locals = sig.Locals; @@ -523,7 +523,7 @@ LocalSig ReadLocalSig(CallingConvention callingConvention) { /// First byte of signature /// A new instance GenericInstMethodSig ReadGenericInstMethod(CallingConvention callingConvention) { - if (!reader.ReadCompressedUInt32(out uint count)) + if (!reader.TryReadCompressedUInt32(out uint count)) return null; var sig = new GenericInstMethodSig(callingConvention, count); var args = sig.GenericArguments; @@ -574,33 +574,33 @@ TypeSig ReadType() { case ElementType.Pinned: result = new PinnedSig(ReadType()); break; case ElementType.Var: - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; result = new GenericVar(num, gpContext.Type); break; case ElementType.MVar: - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; result = new GenericMVar(num, gpContext.Method); break; case ElementType.ValueArray: nextType = ReadType(); - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; result = new ValueArraySig(nextType, num); break; case ElementType.Module: - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; result = new ModuleSig(num, ReadType()); break; case ElementType.GenericInst: nextType = ReadType(); - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); var args = genericInstSig.GenericArguments; @@ -612,25 +612,25 @@ TypeSig ReadType() { case ElementType.Array: nextType = ReadType(); uint rank; - if (!reader.ReadCompressedUInt32(out rank)) + if (!reader.TryReadCompressedUInt32(out rank)) break; if (rank == 0) { result = new ArraySig(nextType, rank); break; } - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; var sizes = new List((int)num); for (uint i = 0; i < num; i++) { - if (!reader.ReadCompressedUInt32(out uint size)) + if (!reader.TryReadCompressedUInt32(out uint size)) goto exit; sizes.Add(size); } - if (!reader.ReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num)) break; var lowerBounds = new List((int)num); for (uint i = 0; i < num; i++) { - if (!reader.ReadCompressedInt32(out int size)) + if (!reader.TryReadCompressedInt32(out int size)) goto exit; lowerBounds.Add(size); } @@ -662,7 +662,7 @@ TypeSig ReadType() { /// /// A instance ITypeDefOrRef ReadTypeDefOrRef() { - if (!reader.ReadCompressedUInt32(out uint codedToken)) + if (!reader.TryReadCompressedUInt32(out uint codedToken)) return null; return helper.ResolveTypeDefOrRef(codedToken, gpContext); } diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index 952d0eca7..aaf0da33e 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -45,7 +45,7 @@ void Populate(ref DataReader reader) { reader.Position = 1; while (reader.Position < reader.Length) { uint offset = reader.Position; - if (!reader.ReadCompressedUInt32(out uint len)) { + if (!reader.TryReadCompressedUInt32(out uint len)) { if (offset == reader.Position) reader.Position++; continue; diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index 44d8e4087..935e73034 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -43,7 +43,7 @@ void Populate(ref DataReader reader) { reader.Position = 1; while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; - if (!reader.ReadCompressedUInt32(out uint len)) { + if (!reader.TryReadCompressedUInt32(out uint len)) { if (offset == reader.Position) reader.Position++; continue; diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 48c08e5c9..115d5cbe9 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -499,7 +499,7 @@ public byte[] ReadBytes(int length) { /// /// Uncompressed /// - public bool ReadCompressedUInt32(out uint value) { + public bool TryReadCompressedUInt32(out uint value) { VerifyState(); var currentOffset = this.currentOffset; var bytesLeft = endOffset - currentOffset; @@ -550,7 +550,7 @@ public bool ReadCompressedUInt32(out uint value) { /// /// public uint ReadCompressedUInt32() { - if (!ReadCompressedUInt32(out uint value)) + if (!TryReadCompressedUInt32(out uint value)) ThrowNoMoreBytesLeft(); return value; } @@ -560,7 +560,7 @@ public uint ReadCompressedUInt32() { /// /// Uncompressed /// - public bool ReadCompressedInt32(out int value) { + public bool TryReadCompressedInt32(out int value) { VerifyState(); var currentOffset = this.currentOffset; var bytesLeft = endOffset - currentOffset; @@ -625,7 +625,7 @@ public bool ReadCompressedInt32(out int value) { /// /// public int ReadCompressedInt32() { - if (!ReadCompressedInt32(out int value)) + if (!TryReadCompressedInt32(out int value)) ThrowNoMoreBytesLeft(); return value; } From 94a0c39fa1583c8011cab62d7c802ed6a941904b Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 12:33:05 +0200 Subject: [PATCH 183/511] Remove some methods from DataStream --- src/IO/AlignedByteArrayDataStream.cs | 20 ---------- src/IO/AlignedNativeMemoryDataStream.cs | 17 -------- src/IO/DataReader.cs | 48 ++--------------------- src/IO/DataStream.cs | 28 ------------- src/IO/EmptyDataStream.cs | 4 -- src/IO/UnalignedByteArrayDataStream.cs | 17 -------- src/IO/UnalignedNativeMemoryDataStream.cs | 4 -- 7 files changed, 4 insertions(+), 134 deletions(-) diff --git a/src/IO/AlignedByteArrayDataStream.cs b/src/IO/AlignedByteArrayDataStream.cs index 4e0ea7db7..ae707157c 100644 --- a/src/IO/AlignedByteArrayDataStream.cs +++ b/src/IO/AlignedByteArrayDataStream.cs @@ -16,40 +16,20 @@ public override void ReadBytes(uint offset, void* destination, int length) => public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => Array.Copy(data, (int)offset, destination, destinationIndex, length); - public override sbyte ReadSByte(uint offset) => (sbyte)data[(int)offset]; public override byte ReadByte(uint offset) => data[(int)offset]; - public override short ReadInt16(uint offset) { - int i = (int)offset; - var data = this.data; - return (short)(data[i++] | (data[i] << 8)); - } - public override ushort ReadUInt16(uint offset) { int i = (int)offset; var data = this.data; return (ushort)(data[i++] | (data[i] << 8)); } - public override int ReadInt32(uint offset) { - int i = (int)offset; - var data = this.data; - return (int)(data[i++] | ((uint)data[i++] << 8) | ((uint)data[i++] << 16) | ((uint)data[i] << 24)); - } - public override uint ReadUInt32(uint offset) { int i = (int)offset; var data = this.data; return data[i++] | ((uint)data[i++] << 8) | ((uint)data[i++] << 16) | ((uint)data[i] << 24); } - public override long ReadInt64(uint offset) { - int i = (int)offset; - var data = this.data; - return (long)(data[i++] | ((ulong)data[i++] << 8) | ((ulong)data[i++] << 16) | ((ulong)data[i++] << 24) | - ((ulong)data[i++] << 32) | ((ulong)data[i++] << 40) | ((ulong)data[i++] << 48) | ((ulong)data[i] << 56)); - } - public override ulong ReadUInt64(uint offset) { int i = (int)offset; var data = this.data; diff --git a/src/IO/AlignedNativeMemoryDataStream.cs b/src/IO/AlignedNativeMemoryDataStream.cs index f1f89c651..12d500c06 100644 --- a/src/IO/AlignedNativeMemoryDataStream.cs +++ b/src/IO/AlignedNativeMemoryDataStream.cs @@ -39,35 +39,18 @@ public override void ReadBytes(uint offset, void* destination, int length) { public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => Marshal.Copy((IntPtr)(data + offset), destination, destinationIndex, length); - public override sbyte ReadSByte(uint offset) => *(sbyte*)(data + offset); public override byte ReadByte(uint offset) => *(data + offset); - public override short ReadInt16(uint offset) { - var p = data + offset; - return (short)(*p++ | (*p << 8)); - } - public override ushort ReadUInt16(uint offset) { var p = data + offset; return (ushort)(*p++ | (*p << 8)); } - public override int ReadInt32(uint offset) { - var p = data + offset; - return *p++ | (*p++ << 8) | (*p++ << 16) | (*p << 24); - } - public override uint ReadUInt32(uint offset) { var p = data + offset; return *p++ | ((uint)*p++ << 8) | ((uint)*p++ << 16) | ((uint)*p << 24); } - public override long ReadInt64(uint offset) { - var p = data + offset; - return (long)(*p++ | ((ulong)*p++ << 8) | ((ulong)*p++ << 16) | ((ulong)*p++ << 24) | - ((ulong)*p++ << 32) | ((ulong)*p++ << 40) | ((ulong)*p++ << 48) | ((ulong)*p << 56)); - } - public override ulong ReadUInt64(uint offset) { var p = data + offset; return *p++ | ((ulong)*p++ << 8) | ((ulong)*p++ << 16) | ((ulong)*p++ << 24) | diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 115d5cbe9..350ea43fb 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -192,17 +192,7 @@ public DataReader Slice(int start) { /// Reads a /// /// - public sbyte ReadSByte() { - VerifyState(); - const uint SIZE = 1; - var currentOffset = this.currentOffset; - if (currentOffset == endOffset) - ThrowNoMoreBytesLeft(); - var value = stream.ReadSByte(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } + public sbyte ReadSByte() => (sbyte)ReadByte(); /// /// Reads a @@ -224,17 +214,7 @@ public byte ReadByte() { /// Reads a /// /// - public short ReadInt16() { - VerifyState(); - const uint SIZE = 2; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadInt16(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } + public short ReadInt16() => (short)ReadUInt16(); /// /// Reads a @@ -256,17 +236,7 @@ public ushort ReadUInt16() { /// Reads a /// /// - public int ReadInt32() { - VerifyState(); - const uint SIZE = 4; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadInt32(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } + public int ReadInt32() => (int)ReadUInt32(); /// /// Reads a @@ -321,17 +291,7 @@ internal uint Unsafe_ReadUInt32() { /// Reads a /// /// - public long ReadInt64() { - VerifyState(); - const uint SIZE = 8; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadInt64(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } + public long ReadInt64() => (long)ReadUInt64(); /// /// Reads a diff --git a/src/IO/DataStream.cs b/src/IO/DataStream.cs index 0f62d1501..8775cd5ba 100644 --- a/src/IO/DataStream.cs +++ b/src/IO/DataStream.cs @@ -27,13 +27,6 @@ public abstract class DataStream { /// Number of bytes to read public abstract void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length); - /// - /// Reads a - /// - /// Offset of data - /// - public abstract sbyte ReadSByte(uint offset); - /// /// Reads a /// @@ -41,13 +34,6 @@ public abstract class DataStream { /// public abstract byte ReadByte(uint offset); - /// - /// Reads a - /// - /// Offset of data - /// - public abstract short ReadInt16(uint offset); - /// /// Reads a /// @@ -55,13 +41,6 @@ public abstract class DataStream { /// public abstract ushort ReadUInt16(uint offset); - /// - /// Reads a - /// - /// Offset of data - /// - public abstract int ReadInt32(uint offset); - /// /// Reads a /// @@ -69,13 +48,6 @@ public abstract class DataStream { /// public abstract uint ReadUInt32(uint offset); - /// - /// Reads a - /// - /// Offset of data - /// - public abstract long ReadInt64(uint offset); - /// /// Reads a /// diff --git a/src/IO/EmptyDataStream.cs b/src/IO/EmptyDataStream.cs index 7ac85942f..55fa44dba 100644 --- a/src/IO/EmptyDataStream.cs +++ b/src/IO/EmptyDataStream.cs @@ -17,13 +17,9 @@ public override void ReadBytes(uint offset, byte[] destination, int destinationI for (int i = 0; i < length; i++) destination[destinationIndex + i] = 0; } - public override sbyte ReadSByte(uint offset) => 0; public override byte ReadByte(uint offset) => 0; - public override short ReadInt16(uint offset) => 0; public override ushort ReadUInt16(uint offset) => 0; - public override int ReadInt32(uint offset) => 0; public override uint ReadUInt32(uint offset) => 0; - public override long ReadInt64(uint offset) => 0; public override ulong ReadUInt64(uint offset) => 0; public override float ReadSingle(uint offset) => 0; public override double ReadDouble(uint offset) => 0; diff --git a/src/IO/UnalignedByteArrayDataStream.cs b/src/IO/UnalignedByteArrayDataStream.cs index d510e945f..5a05e8127 100644 --- a/src/IO/UnalignedByteArrayDataStream.cs +++ b/src/IO/UnalignedByteArrayDataStream.cs @@ -16,36 +16,19 @@ public override void ReadBytes(uint offset, void* destination, int length) => public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => Array.Copy(data, (int)offset, destination, destinationIndex, length); - public override sbyte ReadSByte(uint offset) => (sbyte)data[(int)offset]; public override byte ReadByte(uint offset) => data[(int)offset]; - public override short ReadInt16(uint offset) { - int i = (int)offset; - var data = this.data; - return (short)(data[i++] | (data[i] << 8)); - } - public override ushort ReadUInt16(uint offset) { int i = (int)offset; var data = this.data; return (ushort)(data[i++] | (data[i] << 8)); } - public override int ReadInt32(uint offset) { - fixed (byte* p = data) - return *(int*)(p + offset); - } - public override uint ReadUInt32(uint offset) { fixed (byte* p = data) return *(uint*)(p + offset); } - public override long ReadInt64(uint offset) { - fixed (byte* p = data) - return *(long*)(p + offset); - } - public override ulong ReadUInt64(uint offset) { fixed (byte* p = data) return *(ulong*)(p + offset); diff --git a/src/IO/UnalignedNativeMemoryDataStream.cs b/src/IO/UnalignedNativeMemoryDataStream.cs index 9228fb86b..fed08f046 100644 --- a/src/IO/UnalignedNativeMemoryDataStream.cs +++ b/src/IO/UnalignedNativeMemoryDataStream.cs @@ -28,13 +28,9 @@ public override void ReadBytes(uint offset, void* destination, int length) { public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => Marshal.Copy((IntPtr)(data + offset), destination, destinationIndex, length); - public override sbyte ReadSByte(uint offset) => *(sbyte*)(data + offset); public override byte ReadByte(uint offset) => *(data + offset); - public override short ReadInt16(uint offset) => *(short*)(data + offset); public override ushort ReadUInt16(uint offset) => *(ushort*)(data + offset); - public override int ReadInt32(uint offset) => *(int*)(data + offset); public override uint ReadUInt32(uint offset) => *(uint*)(data + offset); - public override long ReadInt64(uint offset) => *(long*)(data + offset); public override ulong ReadUInt64(uint offset) => *(ulong*)(data + offset); public override float ReadSingle(uint offset) => *(float*)(data + offset); public override double ReadDouble(uint offset) => *(double*)(data + offset); From ff00f1d7954ec78e2964716cd714f25623e56a66 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 16:29:17 +0200 Subject: [PATCH 184/511] Ignore streams not in MD --- src/DotNet/Writer/DataReaderHeap.cs | 2 +- src/DotNet/Writer/Metadata.cs | 15 +++++++++++---- src/IO/DataReader.cs | 2 ++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Writer/DataReaderHeap.cs b/src/DotNet/Writer/DataReaderHeap.cs index 684d76bcf..dbf682abe 100644 --- a/src/DotNet/Writer/DataReaderHeap.cs +++ b/src/DotNet/Writer/DataReaderHeap.cs @@ -36,7 +36,7 @@ public DataReaderHeap(DotNetStream stream) { public DataReaderHeap(string name, DataReader heapReader) { this.heapReader = heapReader; this.heapReader.Position = 0; - Name = name; + Name = name ?? throw new ArgumentNullException(nameof(name)); } /// diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 2f429ef91..976725033 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -260,15 +260,22 @@ public void PreserveHeapOrder(ModuleDef module, bool addCustomHeaps) { CustomHeaps.AddRange(otherStreams.OfType()); } var streamToOrder = new Dictionary(mod.Metadata.AllStreams.Count); - for (int i = 0; i < mod.Metadata.AllStreams.Count; i++) - streamToOrder.Add(mod.Metadata.AllStreams[i], i); + for (int i = 0, order = 0; i < mod.Metadata.AllStreams.Count; i++) { + var stream = mod.Metadata.AllStreams[i]; + if (stream.StartOffset == 0) + continue; + streamToOrder.Add(stream, order++); + } var nameToOrder = new Dictionary(mod.Metadata.AllStreams.Count, StringComparer.Ordinal); - for (int i = 0; i < mod.Metadata.AllStreams.Count; i++) { + for (int i = 0, order = 0; i < mod.Metadata.AllStreams.Count; i++) { var stream = mod.Metadata.AllStreams[i]; + if (stream.StartOffset == 0) + continue; bool isKnownStream = stream is BlobStream || stream is GuidStream || stream is PdbStream || stream is StringsStream || stream is TablesStream || stream is USStream; if (!nameToOrder.ContainsKey(stream.Name) || isKnownStream) - nameToOrder[stream.Name] = i; + nameToOrder[stream.Name] = order; + order++; } MetadataHeapsAdded += (s, e) => { e.Heaps.Sort((a, b) => { diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 350ea43fb..9847c3986 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -830,6 +830,8 @@ public void CopyTo(Stream destination, byte[] dataBuffer) { ThrowArgumentNullException(nameof(dataBuffer)); if (Position >= Length) return; + if (dataBuffer.Length == 0) + ThrowInvalidArgument(nameof(dataBuffer)); uint lenLeft = BytesLeft; while (lenLeft > 0) { int num = (int)Math.Min((uint)dataBuffer.Length, lenLeft); From c20a869fe27528173f30e83767a8e2636c645fb2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 16:32:55 +0200 Subject: [PATCH 185/511] Return a local if it's a ldloca instruction --- README.md | 1 + src/DotNet/Emit/Instruction.cs | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dcf57e25f..39ff125d9 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ v3.0 breaking changes - `ModuleWriter` and `NativeModuleWriter` use `DataWriter` instead of `BinaryWriter` - The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` - `MetadataOptions`'s `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded`, and `PreserveHeapOrder()` instead. +- `Instruction.GetLocal()` returns a local if the instruction is a `ldloca` or `ldloca.s` instruction (it used to return null) Examples -------- diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index dcdb567b3..89694f00a 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -658,11 +658,10 @@ public bool IsStloc() { } /// - /// Returns the local if it's a ldloc or stloc instruction. It does not - /// return the local if it's a ldloca instruction. + /// Returns the local if it's a ldloc, stloc or ldloca instruction /// /// The locals - /// The local or null if it's not a ldloc or stloc + /// The local or null if it's not a ldloc, stloc or ldloca /// instruction or if the local doesn't exist. public Local GetLocal(IList locals) { int index; @@ -672,6 +671,8 @@ public Local GetLocal(IList locals) { case Code.Ldloc_S: case Code.Stloc: case Code.Stloc_S: + case Code.Ldloca: + case Code.Ldloca_S: return Operand as Local; case Code.Ldloc_0: From 157f91e0549bd00d58c719d0f211c6504a1465eb Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Mar 2018 22:10:09 +0200 Subject: [PATCH 186/511] Update README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39ff125d9..ce583f4c9 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ v3.0 breaking changes - `MethodBodyWriterBase` uses `ArrayWriter` instead of `BinaryWriter` (all virtual methods) - `ModuleWriter` and `NativeModuleWriter` use `DataWriter` instead of `BinaryWriter` - The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` -- `MetadataOptions`'s `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded`, and `PreserveHeapOrder()` instead. +- `MetadataOptions`' `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded` and `PreserveHeapOrder()` instead. - `Instruction.GetLocal()` returns a local if the instruction is a `ldloca` or `ldloca.s` instruction (it used to return null) Examples @@ -265,6 +265,7 @@ method.MethodSig.RetType = type; Requirements: - The assembly platform must be x86, x64, IA-64 or ARM (ARM64 isn't supported at the moment). AnyCPU assemblies are not supported. This is as simple as changing (if needed) `ModuleWriterOptions.PEHeadersOptions.Machine` when saving the file. x86 files should set `32-bit required` flag and clear `32-bit preferred` flag in the COR20 header. +- `ModuleWriterOptions.Cor20HeaderOptions.Flags`: The `IL Only` bit must be cleared. - It must be a DLL file (see `ModuleWriterOptions.PEHeadersOptions.Characteristics`). The file will fail to load at runtime if it's an EXE file. Type classes From 5f4628f099c9ee3b2fa4dfb25f0b30eb9bb842d2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 31 Mar 2018 13:51:38 +0200 Subject: [PATCH 187/511] Verify PDB ID after loading the PDB file --- src/DotNet/Pdb/Managed/PdbReader.cs | 6 ++ src/DotNet/Pdb/Managed/SymbolReaderCreator.cs | 40 +++++------- src/DotNet/Pdb/ManagedSymbolReaderCreator.cs | 34 +++++----- src/DotNet/Pdb/PdbReaderContext.cs | 63 +++++++++++++++++++ src/DotNet/Pdb/Portable/PortablePdbReader.cs | 14 +++++ .../Pdb/Portable/SymbolReaderCreator.cs | 62 +++++++++++------- src/DotNet/Pdb/SymbolReaderCreator.cs | 35 ++++++++--- src/dnlib.csproj | 1 + 8 files changed, 182 insertions(+), 73 deletions(-) create mode 100644 src/DotNet/Pdb/PdbReaderContext.cs diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 2efae661f..afd324551 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -41,6 +41,10 @@ sealed class PdbReader : SymbolReader { /// public Guid Guid { get; private set; } + readonly Guid expectedGuid; + + public PdbReader(Guid expectedGuid) => this.expectedGuid = expectedGuid; + public override void Initialize(ModuleDef module) => this.module = module; /// @@ -101,6 +105,8 @@ void ReadInternal(ref DataReader reader) { ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); ReadNames(); + if (Guid != expectedGuid) + return; ReadStringTable(); var tokenMapStream = ReadModules(); diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs index 4d7e7ca4a..bc783c72d 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs @@ -12,38 +12,26 @@ static class SymbolReaderCreator { /// /// Creates a new instance /// - /// Path to assembly - /// A new instance or null if there's no PDB - /// file. - public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) => Create(Path.ChangeExtension(assemblyFileName, "pdb")); - - /// - /// Creates a new instance - /// - /// Path to PDB file - /// A new instance or null if there's no PDB - /// file on disk. - public static SymbolReader Create(string pdbFileName) => Create(DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); - - /// - /// Creates a new instance - /// - /// PDB file data - /// A new instance or null. - public static SymbolReader Create(byte[] pdbData) => Create(ByteArrayDataReaderFactory.Create(pdbData, filename: null)); - - /// - /// Creates a new instance - /// + /// PDB context /// PDB file stream which is now owned by this method /// A new instance or null. - public static SymbolReader Create(DataReaderFactory pdbStream) { + public static SymbolReader Create(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { if (pdbStream == null) return null; try { - var pdbReader = new PdbReader(); + var debugDir = pdbContext.CodeViewDebugDirectory; + if (debugDir == null) + return null; + if (debugDir.MajorVersion != 0 || debugDir.MinorVersion != 0) + return null; + if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) + return null; + + var pdbReader = new PdbReader(pdbGuid); pdbReader.Read(pdbStream.CreateReader()); - return pdbReader; + if (pdbReader.Guid == pdbGuid) + return pdbReader; + return null; } catch (PdbException) { } diff --git a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs index e979c3834..f10926191 100644 --- a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs +++ b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs @@ -7,25 +7,25 @@ namespace dnlib.DotNet.Pdb { static class ManagedSymbolReaderCreator { - public static SymbolReader CreateFromAssemblyFile(Metadata metadata, string assemblyFileName) => - Create(metadata, Path.ChangeExtension(assemblyFileName, "pdb")); + public static SymbolReader CreateFromAssemblyFile(PdbReaderContext pdbContext, Metadata metadata, string assemblyFileName) => + Create(pdbContext, metadata, Path.ChangeExtension(assemblyFileName, "pdb")); - public static SymbolReader Create(Metadata metadata, string pdbFileName) => - Create(metadata, DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); + public static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata, string pdbFileName) => + Create(pdbContext, metadata, DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); - public static SymbolReader Create(Metadata metadata, byte[] pdbData) => - Create(metadata, ByteArrayDataReaderFactory.Create(pdbData, filename: null)); + public static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata, byte[] pdbData) => + Create(pdbContext, metadata, ByteArrayDataReaderFactory.Create(pdbData, filename: null)); - public static SymbolReader Create(Metadata metadata, DataReaderFactory pdbStream) { + public static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream) { try { // Embedded pdbs have priority - var res = Create(metadata); + var res = Create(pdbContext, metadata); if (res != null) { pdbStream?.Dispose(); return res; } - return CreateCore(pdbStream); + return CreateCore(pdbContext, pdbStream); } catch { pdbStream?.Dispose(); @@ -33,14 +33,17 @@ public static SymbolReader Create(Metadata metadata, DataReaderFactory pdbStream } } - static SymbolReader CreateCore(DataReaderFactory pdbStream) { + static SymbolReader CreateCore(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { if (pdbStream == null) return null; try { - uint sig = pdbStream.CreateReader().ReadUInt32(); - if (sig == 0x424A5342) - return Portable.SymbolReaderCreator.TryCreate(pdbStream, false); - return Managed.SymbolReaderCreator.Create(pdbStream); + var reader = pdbStream.CreateReader(); + if (reader.Length >= 4) { + uint sig = reader.ReadUInt32(); + if (sig == 0x424A5342) + return Portable.SymbolReaderCreator.TryCreate(pdbContext, pdbStream, isEmbeddedPortablePdb: false); + return Managed.SymbolReaderCreator.Create(pdbContext, pdbStream); + } } catch (IOException) { } @@ -48,6 +51,7 @@ static SymbolReader CreateCore(DataReaderFactory pdbStream) { return null; } - internal static SymbolReader Create(Metadata metadata) => Portable.SymbolReaderCreator.TryCreate(metadata); + internal static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata) => + Portable.SymbolReaderCreator.TryCreate(pdbContext, metadata); } } diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs new file mode 100644 index 000000000..3a67c9f0d --- /dev/null +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -0,0 +1,63 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using dnlib.IO; +using dnlib.PE; + +namespace dnlib.DotNet.Pdb { + readonly struct PdbReaderContext { + readonly IPEImage peImage; + readonly ImageDebugDirectory codeViewDebugDir; + + public bool HasDebugInfo => codeViewDebugDir != null; + public ImageDebugDirectory CodeViewDebugDirectory => codeViewDebugDir; + + public PdbReaderContext(IPEImage peImage) { + this.peImage = peImage; + codeViewDebugDir = TryGetDebugDirectoryEntry(peImage, ImageDebugType.CodeView); + } + + public ImageDebugDirectory TryGetDebugDirectoryEntry(ImageDebugType imageDebugType) => + TryGetDebugDirectoryEntry(peImage, imageDebugType); + + static ImageDebugDirectory TryGetDebugDirectoryEntry(IPEImage peImage, ImageDebugType imageDebugType) { + var list = peImage.ImageDebugDirectories; + int count = list.Count; + for (int i = 0; i < count; i++) { + var entry = list[i]; + if (entry.Type == imageDebugType) + return entry; + } + return null; + } + + public bool TryGetCodeViewData(out Guid guid, out uint age) { + guid = Guid.Empty; + age = 0; + var reader = GetCodeViewDataReader(); + // magic, guid, age, zero-terminated string + if (reader.Length < 4 + 16 + 4 + 1) + return false; + if (reader.ReadUInt32() != 0x53445352) + return false; + guid = reader.ReadGuid(); + age = reader.ReadUInt32(); + return true; + } + + DataReader GetCodeViewDataReader() { + if (codeViewDebugDir == null) + return default; + return CreateReader(codeViewDebugDir.PointerToRawData, codeViewDebugDir.SizeOfData); + } + + public DataReader CreateReader(FileOffset offset, uint size) { + if (offset == 0 || size == 0) + return default; + var reader = peImage.CreateReader(offset, size); + if (reader.Length != size) + return default; + return reader; + } + } +} diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index fd5a9d347..b2f0049ab 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -26,6 +26,20 @@ public PortablePdbReader(DataReaderFactory pdbStream, PdbFileKind pdbFileKind) { pdbMetadata = MetadataCreator.CreateStandalonePortablePDB(pdbStream, true); } + internal bool CheckVersion(Guid pdbGuid, uint timestamp) { + if (pdbMetadata.PdbStream is PdbStream pdbStream) { + var pdbGuidArray = pdbStream.Id; + Array.Resize(ref pdbGuidArray, 16); + if (new Guid(pdbGuidArray) != pdbGuid) + return false; + if (BitConverter.ToUInt32(pdbStream.Id, 16) != timestamp) + return false; + + return true; + } + return false; + } + public override void Initialize(ModuleDef module) { this.module = module; documents = ReadDocuments(); diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index 38a93c8e8..62e88729f 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -7,35 +7,60 @@ using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; using dnlib.PE; +using DDW = dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Portable { static class SymbolReaderCreator { - public static SymbolReader TryCreate(DataReaderFactory pdbStream, bool isEmbeddedPortablePdb) { + public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFactory pdbStream, bool isEmbeddedPortablePdb) { + bool disposePdbStream = true; try { - if (pdbStream != null && pdbStream.Length >= 4 && pdbStream.CreateReader().ReadUInt32() == 0x424A5342) - return new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB); + if (!pdbContext.HasDebugInfo) + return null; + if (pdbStream == null) + return null; + if (pdbStream.Length < 4) + return null; + if (pdbStream.CreateReader().ReadUInt32() != 0x424A5342) + return null; + + var debugDir = pdbContext.CodeViewDebugDirectory; + if (debugDir == null) + return null; + if (debugDir.MinorVersion != DDW.PortablePdbConstants.PortableCodeViewVersionMagic) + return null; + Debug.Assert(debugDir.MajorVersion == DDW.PortablePdbConstants.FormatVersion, $"New Portable PDB version: 0x{debugDir.MajorVersion:X4}"); + if (debugDir.MajorVersion != DDW.PortablePdbConstants.FormatVersion) + return null; + if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) + return null; + + var reader = new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB); + if (!reader.CheckVersion(pdbGuid, debugDir.TimeDateStamp)) + return null; + disposePdbStream = false; + return reader; } catch (IOException) { } - catch { - pdbStream?.Dispose(); - throw; + finally { + if (disposePdbStream) + pdbStream?.Dispose(); } - pdbStream?.Dispose(); return null; } - public static SymbolReader TryCreate(Metadata metadata) { + public static SymbolReader TryCreate(PdbReaderContext pdbContext, Metadata metadata) { if (metadata == null) return null; try { - var peImage = metadata.PEImage; - if (peImage == null) + if (!pdbContext.HasDebugInfo) return null; - var embeddedDir = TryGetEmbeddedDebugDirectory(peImage); + var embeddedDir = pdbContext.TryGetDebugDirectoryEntry(ImageDebugType.EmbeddedPortablePdb); if (embeddedDir == null) return null; - var reader = peImage.CreateReader(embeddedDir.PointerToRawData, embeddedDir.SizeOfData); + var reader = pdbContext.CreateReader(embeddedDir.PointerToRawData, embeddedDir.SizeOfData); + if (reader.Length < 8) + return null; // "MPDB" = 0x4244504D if (reader.ReadUInt32() != 0x4244504D) return null; @@ -58,23 +83,12 @@ public static SymbolReader TryCreate(Metadata metadata) { if (pos != decompressedBytes.Length) return null; var stream = ByteArrayDataReaderFactory.Create(decompressedBytes, filename: null); - return TryCreate(stream, true); + return TryCreate(pdbContext, stream, isEmbeddedPortablePdb: true); } } catch (IOException) { } return null; } - - static ImageDebugDirectory TryGetEmbeddedDebugDirectory(IPEImage peImage) { - var dirs = peImage.ImageDebugDirectories; - int count = dirs.Count; - for (int i = 0; i < count; i++) { - var idd = dirs[i]; - if (idd.Type == ImageDebugType.EmbeddedPortablePdb) - return idd; - } - return null; - } } } diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderCreator.cs index 88d8b2d96..57acedff7 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderCreator.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.Pdb { /// /// Creates a instance /// - public static class SymbolReaderCreator { + static class SymbolReaderCreator { /// /// Creates a new instance /// @@ -19,12 +19,16 @@ public static class SymbolReaderCreator { /// A new instance or null if there's no PDB /// file on disk or if it's not possible to create a . public static SymbolReader CreateFromAssemblyFile(PdbImplType pdbImpl, Metadata metadata, string assemblyFileName) { + var pdbContext = new PdbReaderContext(metadata.PEImage); + if (!pdbContext.HasDebugInfo) + return null; + switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.CreateFromAssemblyFile(assemblyFileName); case PdbImplType.Managed: - return ManagedSymbolReaderCreator.CreateFromAssemblyFile(metadata, assemblyFileName); + return ManagedSymbolReaderCreator.CreateFromAssemblyFile(pdbContext, metadata, assemblyFileName); default: throw new InvalidOperationException(); } @@ -39,12 +43,16 @@ public static SymbolReader CreateFromAssemblyFile(PdbImplType pdbImpl, Metadata /// A new instance or null if there's no PDB /// file on disk or if it's not possible to create a . public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, string pdbFileName) { + var pdbContext = new PdbReaderContext(metadata.PEImage); + if (!pdbContext.HasDebugInfo) + return null; + switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(metadata, pdbFileName); case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(metadata, pdbFileName); + return ManagedSymbolReaderCreator.Create(pdbContext, metadata, pdbFileName); default: throw new InvalidOperationException(); } @@ -59,12 +67,16 @@ public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, string /// A new instance or null if it's not possible /// to create a . public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, byte[] pdbData) { + var pdbContext = new PdbReaderContext(metadata.PEImage); + if (!pdbContext.HasDebugInfo) + return null; + switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(metadata, pdbData); case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(metadata, pdbData); + return ManagedSymbolReaderCreator.Create(pdbContext, metadata, pdbData); default: throw new InvalidOperationException(); } @@ -79,12 +91,16 @@ public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, byte[] /// A new instance or null if it's not possible /// to create a . public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, DataReaderFactory pdbStream) { + var pdbContext = new PdbReaderContext(metadata.PEImage); + if (!pdbContext.HasDebugInfo) + return null; + switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return Dss.SymbolReaderCreator.Create(metadata, pdbStream); case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(metadata, pdbStream); + return ManagedSymbolReaderCreator.Create(pdbContext, metadata, pdbStream); default: pdbStream?.Dispose(); @@ -93,15 +109,18 @@ public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, DataRe } internal static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata) { + var pdbContext = new PdbReaderContext(metadata.PEImage); + if (!pdbContext.HasDebugInfo) + return null; + switch (pdbImpl) { case PdbImplType.MicrosoftCOM: return null; case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(metadata); + return ManagedSymbolReaderCreator.Create(pdbContext, metadata); - default: - throw new InvalidOperationException(); + default: throw new InvalidOperationException(); } } } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 2c6b15e2e..b67be29a4 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -191,6 +191,7 @@ + From 3d7cf5778ae92b3e3d30bdc7c8265cf3529cf52d Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 31 Mar 2018 22:48:16 +0200 Subject: [PATCH 188/511] Use a local --- src/DotNet/Pdb/Portable/SymbolReaderCreator.cs | 5 +++-- src/DotNet/Pdb/SymbolReaderCreator.cs | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index 62e88729f..3c16a9e6a 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -28,8 +28,9 @@ public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFact return null; if (debugDir.MinorVersion != DDW.PortablePdbConstants.PortableCodeViewVersionMagic) return null; - Debug.Assert(debugDir.MajorVersion == DDW.PortablePdbConstants.FormatVersion, $"New Portable PDB version: 0x{debugDir.MajorVersion:X4}"); - if (debugDir.MajorVersion != DDW.PortablePdbConstants.FormatVersion) + bool validFormatVersion = debugDir.MajorVersion == DDW.PortablePdbConstants.FormatVersion; + Debug.Assert(validFormatVersion, $"New Portable PDB version: 0x{debugDir.MajorVersion:X4}"); + if (!validFormatVersion) return null; if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderCreator.cs index 57acedff7..96f4789e7 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderCreator.cs @@ -92,8 +92,10 @@ public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, byte[] /// to create a . public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, DataReaderFactory pdbStream) { var pdbContext = new PdbReaderContext(metadata.PEImage); - if (!pdbContext.HasDebugInfo) + if (!pdbContext.HasDebugInfo) { + pdbStream?.Dispose(); return null; + } switch (pdbImpl) { case PdbImplType.MicrosoftCOM: From de9bb51cefe07534f1219034c1f46ea3dc86bad4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 1 Apr 2018 12:00:02 +0200 Subject: [PATCH 189/511] Make class internal --- src/DotNet/GenericArguments.cs | 2 +- src/DotNet/SigComparer.cs | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/DotNet/GenericArguments.cs b/src/DotNet/GenericArguments.cs index d71295095..ccd908fb4 100644 --- a/src/DotNet/GenericArguments.cs +++ b/src/DotNet/GenericArguments.cs @@ -58,7 +58,7 @@ public TypeSig Resolve(uint number) { /// /// Replaces generic type/method var with its generic argument /// - public sealed class GenericArguments { + sealed class GenericArguments { GenericArgumentsStack typeArgsStack = new GenericArgumentsStack(true); GenericArgumentsStack methodArgsStack = new GenericArgumentsStack(false); diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 34a7d2e59..bbd37e680 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -390,14 +390,8 @@ public enum SigComparerOptions : uint { /// DontCompareReturnType = 0x200, - /// - /// If set, all generic parameters are replaced with their generic arguments prior - /// to comparing types. You should enable this when comparing a method, field, property - /// or an event to a , , - /// or an if the owner type could - /// be a generic instance type. - /// - SubstituteGenericParameters = 0x400, + // Internal only + //SubstituteGenericParameters = 0x400, /// /// Type namespaces are case insensitive @@ -497,6 +491,8 @@ public enum SigComparerOptions : uint { /// Compares types, signatures, methods, fields, properties, events /// public struct SigComparer { + const SigComparerOptions SigComparerOptions_SubstituteGenericParameters = (SigComparerOptions)0x400; + const int HASHCODE_MAGIC_GLOBAL_TYPE = 1654396648; const int HASHCODE_MAGIC_NESTED_TYPE = -1049070942; const int HASHCODE_MAGIC_ET_MODULE = -299744851; @@ -525,7 +521,7 @@ public struct SigComparer { bool CompareAssemblyLocale => (options & SigComparerOptions.CompareAssemblyLocale) != 0; bool TypeRefCanReferenceGlobalType => (options & SigComparerOptions.TypeRefCanReferenceGlobalType) != 0; bool DontCompareReturnType => (options & SigComparerOptions.DontCompareReturnType) != 0; - bool SubstituteGenericParameters => (options & SigComparerOptions.SubstituteGenericParameters) != 0; + bool SubstituteGenericParameters => (options & SigComparerOptions_SubstituteGenericParameters) != 0; bool CaseInsensitiveTypeNamespaces => (options & SigComparerOptions.CaseInsensitiveTypeNamespaces) != 0; bool CaseInsensitiveTypeNames => (options & SigComparerOptions.CaseInsensitiveTypeNames) != 0; bool CaseInsensitiveMethodFieldNames => (options & SigComparerOptions.CaseInsensitiveMethodFieldNames) != 0; @@ -2754,7 +2750,7 @@ public int GetHashCode(MethodSpec a) { return 0; // We must do this or it won't get the same hash code as some MethodInfos - var oldOptions = SetOptions(SigComparerOptions.SubstituteGenericParameters); + var oldOptions = SetOptions(SigComparerOptions_SubstituteGenericParameters); var gim = a.GenericInstMethodSig; if (gim != null) { InitializeGenericArguments(); From b441f63424b98ded27a4dcabb6cd85ca195430ca Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 2 Apr 2018 16:12:18 +0200 Subject: [PATCH 190/511] Use Microsoft.DiaSymReader.Native if it's available, fixes #173 --- README.md | 12 ++ src/DefaultDllImportSearchPathsAttribute.cs | 21 ++ src/DotNet/MD/DotNetStream.cs | 4 +- src/DotNet/MD/PdbStream.cs | 2 +- src/DotNet/ModuleCreationOptions.cs | 6 +- src/DotNet/ModuleDef.cs | 4 +- src/DotNet/ModuleDefMD.cs | 43 ++-- src/DotNet/Pdb/Dss/ComInterfaces.cs | 153 ++++++++++++-- src/DotNet/Pdb/Dss/DataReaderIStream.cs | 33 +-- src/DotNet/Pdb/Dss/MDEmitter.cs | 89 +------- src/DotNet/Pdb/Dss/MetaDataImport.cs | 106 ++++++++++ src/DotNet/Pdb/Dss/PinnedMetadata.cs | 75 ------- src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs | 84 ++++++++ src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs | 5 +- src/DotNet/Pdb/Dss/SymbolReaderCreator.cs | 136 ------------ src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 35 +++- .../Pdb/Dss/SymbolReaderWriterFactory.cs | 196 ++++++++++++++++++ src/DotNet/Pdb/Dss/SymbolWriter.cs | 82 +++++--- src/DotNet/Pdb/Dss/SymbolWriterCreator.cs | 41 ---- src/DotNet/Pdb/Managed/PdbReader.cs | 8 +- src/DotNet/Pdb/Managed/SymbolReaderCreator.cs | 4 +- src/DotNet/Pdb/ManagedSymbolReaderCreator.cs | 57 ----- src/DotNet/Pdb/PdbImplType.cs | 25 --- src/DotNet/Pdb/PdbReaderContext.cs | 4 +- src/DotNet/Pdb/PdbReaderOptions.cs | 44 ++++ src/DotNet/Pdb/PdbState.cs | 8 +- .../Pdb/Portable/SymbolReaderCreator.cs | 2 +- src/DotNet/Pdb/SymbolReaderCreator.cs | 176 +++++++--------- src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs | 77 +------ .../Pdb/WindowsPdb/SymbolWriterCreator.cs | 25 --- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 37 +--- src/DotNet/Writer/BlobHeap.cs | 2 +- src/DotNet/Writer/DataReaderHeap.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 120 ++++++++--- src/DotNet/Writer/StringsHeap.cs | 2 +- src/DotNet/Writer/USHeap.cs | 2 +- ...rocessCorruptedStateExceptionsAttribute.cs | 2 - src/IO/DataStreamFactory.cs | 20 +- src/IO/MemoryMappedDataReaderFactory.cs | 8 - src/IO/NativeMemoryDataReaderFactory.cs | 5 - src/PE/ProcessorArchUtils.cs | 78 +++++++ src/dnlib.csproj | 12 +- src/dnlib.netstandard.csproj | 1 + 43 files changed, 1024 insertions(+), 824 deletions(-) create mode 100644 src/DefaultDllImportSearchPathsAttribute.cs create mode 100644 src/DotNet/Pdb/Dss/MetaDataImport.cs delete mode 100644 src/DotNet/Pdb/Dss/PinnedMetadata.cs create mode 100644 src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolReaderCreator.cs create mode 100644 src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs delete mode 100644 src/DotNet/Pdb/Dss/SymbolWriterCreator.cs delete mode 100644 src/DotNet/Pdb/ManagedSymbolReaderCreator.cs delete mode 100644 src/DotNet/Pdb/PdbImplType.cs create mode 100644 src/DotNet/Pdb/PdbReaderOptions.cs delete mode 100644 src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs create mode 100644 src/PE/ProcessorArchUtils.cs diff --git a/README.md b/README.md index ce583f4c9..1b76dab92 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ v3.0 breaking changes - The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` - `MetadataOptions`' `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded` and `PreserveHeapOrder()` instead. - `Instruction.GetLocal()` returns a local if the instruction is a `ldloca` or `ldloca.s` instruction (it used to return null) +- `ModuleCreationOptions.PdbImplementation` has been removed and replaced with `PdbOptions` Examples -------- @@ -168,6 +169,17 @@ the name of the PDB file will be written to the PE file. dnlib supports Windows PDBs, portable PDBs and embedded portable PDBs. +Windows PDBs +------------ + +It's only possible to write Windows PDBs on Windows (portable PDBs can be written on any OS). dnlib has a managed Windows PDB reader that supports all OSes. + +There are two *native* Windows PDB reader and writer implementations, the old `diasymreader.dll` that ships with .NET Framework and `Microsoft.DiaSymReader.Native` which has been updated with more features and bug fixes. + +dnlib will use `Microsoft.DiaSymReader.Native` if it exists and fall back to `diasymreader.dll` if needed. `PdbReaderOptions` and `PdbWriterOptions` can be used to disable one of them. + +`Microsoft.DiaSymReader.Native` is a NuGet package with 32-bit and 64-bit native DLLs. You have to add a reference to this NuGet package if you want dnlib to use it. dnlib doesn't add a reference to it. + Strong name sign an assembly ---------------------------- diff --git a/src/DefaultDllImportSearchPathsAttribute.cs b/src/DefaultDllImportSearchPathsAttribute.cs new file mode 100644 index 000000000..0c0d17266 --- /dev/null +++ b/src/DefaultDllImportSearchPathsAttribute.cs @@ -0,0 +1,21 @@ +// dnlib: See LICENSE.txt for more info + +namespace System.Runtime.InteropServices { + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method, AllowMultiple = false)] + sealed class DefaultDllImportSearchPathsAttribute : Attribute { + public DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths) => _paths = paths; + public DllImportSearchPath Paths => _paths; + internal DllImportSearchPath _paths; + } + + [Flags] + enum DllImportSearchPath { + LegacyBehavior = 0, + AssemblyDirectory = 2, + UseDllDirectoryForDependencies = 0x100, + ApplicationDirectory = 0x200, + UserDirectories = 0x400, + System32 = 0x800, + SafeDirectories = 0x1000, + } +} diff --git a/src/DotNet/MD/DotNetStream.cs b/src/DotNet/MD/DotNetStream.cs index 8b6fa8f77..892d18ff7 100644 --- a/src/DotNet/MD/DotNetStream.cs +++ b/src/DotNet/MD/DotNetStream.cs @@ -47,10 +47,10 @@ public class DotNetStream : IFileSection, IDisposable { public string Name => streamHeader == null ? string.Empty : streamHeader.Name; /// - /// Gets data reader + /// Gets a data reader that can read the full stream /// /// - public DataReader GetReader() => dataReader; + public DataReader CreateReader() => dataReader; /// /// Default constructor diff --git a/src/DotNet/MD/PdbStream.cs b/src/DotNet/MD/PdbStream.cs index 80e29457e..9efa40d9d 100644 --- a/src/DotNet/MD/PdbStream.cs +++ b/src/DotNet/MD/PdbStream.cs @@ -30,7 +30,7 @@ public sealed class PdbStream : HeapStream { /// public PdbStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - var reader = GetReader(); + var reader = CreateReader(); Id = reader.ReadBytes(20); EntryPoint = new MDToken(reader.ReadUInt32()); var tables = reader.ReadUInt64(); diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 964854a0d..550506f18 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -15,10 +15,12 @@ public sealed class ModuleCreationOptions { /// public ModuleContext Context { get; set; } + internal const PdbReaderOptions DefaultPdbReaderOptions = PdbReaderOptions.None; + /// - /// Which PDB reader to use. Default is . + /// PDB reader options /// - public PdbImplType PdbImplementation { get; set; } = PdbImplType.Default; + public PdbReaderOptions PdbOptions { get; set; } = DefaultPdbReaderOptions; /// /// Set it to A) the path (string) of the PDB file, B) the data (byte[]) of the PDB file or diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 8f9bafcbc..c8ace7fed 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -858,9 +858,7 @@ protected virtual void Dispose(bool disposing) { tdf.Dispose(); typeDefFinder = null; } - var ps = pdbState; - if (ps != null) - ps.Dispose(); + pdbState?.Dispose(); pdbState = null; } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index ff3939d81..4f66a1b51 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -392,23 +392,23 @@ SymbolReader CreateSymbolReader(ModuleCreationOptions options) { if (options.PdbFileOrData != null) { var pdbFileName = options.PdbFileOrData as string; if (!string.IsNullOrEmpty(pdbFileName)) { - var symReader = SymbolReaderCreator.Create(options.PdbImplementation, metadata, pdbFileName); + var symReader = SymbolReaderCreator.Create(options.PdbOptions, metadata, pdbFileName); if (symReader != null) return symReader; } if (options.PdbFileOrData is byte[] pdbData) - return SymbolReaderCreator.Create(options.PdbImplementation, metadata, pdbData); + return SymbolReaderCreator.Create(options.PdbOptions, metadata, pdbData); if (options.PdbFileOrData is DataReaderFactory pdbStream) - return SymbolReaderCreator.Create(options.PdbImplementation, metadata, pdbStream); + return SymbolReaderCreator.Create(options.PdbOptions, metadata, pdbStream); } if (options.TryToLoadPdbFromDisk) { if (!string.IsNullOrEmpty(location)) - return SymbolReaderCreator.CreateFromAssemblyFile(options.PdbImplementation, metadata, location); + return SymbolReaderCreator.CreateFromAssemblyFile(options.PdbOptions, metadata, location); else - return SymbolReaderCreator.Create(options.PdbImplementation, metadata); + return SymbolReaderCreator.TryCreateEmbeddedPdbReader(options.PdbOptions, metadata); } return null; @@ -433,55 +433,62 @@ public void LoadPdb(SymbolReader symbolReader) { /// Loads symbols from a PDB file /// /// PDB file name - public void LoadPdb(string pdbFileName) => LoadPdb(PdbImplType.Default, pdbFileName); + public void LoadPdb(string pdbFileName) => + LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions, pdbFileName); /// /// Loads symbols from a PDB file /// - /// PDB implementation to use + /// PDB reader options /// PDB file name - public void LoadPdb(PdbImplType pdbImpl, string pdbFileName) => LoadPdb(SymbolReaderCreator.Create(pdbImpl, metadata, pdbFileName)); + public void LoadPdb(PdbReaderOptions options, string pdbFileName) => + LoadPdb(SymbolReaderCreator.Create(options, metadata, pdbFileName)); /// /// Loads symbols from a byte array /// /// PDB data - public void LoadPdb(byte[] pdbData) => LoadPdb(PdbImplType.Default, pdbData); + public void LoadPdb(byte[] pdbData) => + LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions, pdbData); /// /// Loads symbols from a byte array /// - /// PDB implementation to use + /// PDB reader options /// PDB data - public void LoadPdb(PdbImplType pdbImpl, byte[] pdbData) => LoadPdb(SymbolReaderCreator.Create(pdbImpl, metadata, pdbData)); + public void LoadPdb(PdbReaderOptions options, byte[] pdbData) => + LoadPdb(SymbolReaderCreator.Create(options, metadata, pdbData)); /// /// Loads symbols from a stream /// /// PDB file stream which is now owned by us - public void LoadPdb(DataReaderFactory pdbStream) => LoadPdb(PdbImplType.Default, pdbStream); + public void LoadPdb(DataReaderFactory pdbStream) => + LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions, pdbStream); /// /// Loads symbols from a stream /// - /// PDB implementation to use + /// PDB reader options /// PDB file stream which is now owned by us - public void LoadPdb(PdbImplType pdbImpl, DataReaderFactory pdbStream) => LoadPdb(SymbolReaderCreator.Create(pdbImpl, metadata, pdbStream)); + public void LoadPdb(PdbReaderOptions options, DataReaderFactory pdbStream) => + LoadPdb(SymbolReaderCreator.Create(options, metadata, pdbStream)); /// /// Loads symbols if a PDB file is available /// - public void LoadPdb() => LoadPdb(PdbImplType.Default); + public void LoadPdb() => + LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions); /// /// Loads symbols if a PDB file is available /// - /// PDB implementation to use - public void LoadPdb(PdbImplType pdbImpl) { + /// PDB reader options + public void LoadPdb(PdbReaderOptions options) { var loc = location; if (string.IsNullOrEmpty(loc)) return; - LoadPdb(SymbolReaderCreator.Create(pdbImpl, metadata, loc)); + LoadPdb(SymbolReaderCreator.Create(options, metadata, loc)); } internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { diff --git a/src/DotNet/Pdb/Dss/ComInterfaces.cs b/src/DotNet/Pdb/Dss/ComInterfaces.cs index adcae3ba8..6d996ee71 100644 --- a/src/DotNet/Pdb/Dss/ComInterfaces.cs +++ b/src/DotNet/Pdb/Dss/ComInterfaces.cs @@ -6,6 +6,15 @@ // Dss = Diagnostics Symbol Store = http://msdn.microsoft.com/en-us/library/ms404519.aspx namespace dnlib.DotNet.Pdb.Dss { + [ComVisible(true), + ComImport, + Guid("969708D2-05E5-4861-A3B0-96E473CDF63F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedDispose { + [PreserveSig] + int Destroy(); + } + [ComVisible(true), ComImport, Guid("809C652E-7396-11D2-9771-00A0C9B4D50C"), @@ -36,17 +45,16 @@ interface ISymUnmanagedReader { void GetDocuments([In] uint cDocs, [Out] out uint pcDocs, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedDocument[] pDocs); [PreserveSig] int GetUserEntryPoint([Out] out uint pToken); - [PreserveSig] - int GetMethod([In] uint token, [Out] out ISymUnmanagedMethod retVal); + void GetMethod([In] uint token, [Out] out ISymUnmanagedMethod retVal); [PreserveSig] int GetMethodByVersion([In] uint token, [In] int version, [Out] out ISymUnmanagedMethod pRetVal); void GetVariables([In] uint parent, [In] uint cVars, [Out] out uint pcVars, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ISymUnmanagedVariable[] pVars); void GetGlobalVariables([In] uint cVars, [Out] out uint pcVars, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] pVars); - [PreserveSig] - int GetMethodFromDocumentPosition([In] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [Out] out ISymUnmanagedMethod pRetVal); + void GetMethodFromDocumentPosition([In] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [Out] out ISymUnmanagedMethod pRetVal); void GetSymAttribute([In] uint parent, [In, MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint cBuffer, [Out] out uint pcBuffer, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer); void GetNamespaces([In] uint cNameSpaces, [Out] out uint pcNameSpaces, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedNamespace[] namespaces); - void Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.LPWStr)] string filename, [In, MarshalAs(UnmanagedType.LPWStr)] string searchPath, [In] IStream pIStream); + [PreserveSig] + int Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.LPWStr)] string filename, [In, MarshalAs(UnmanagedType.LPWStr)] string searchPath, [In] IStream pIStream); void UpdateSymbolStore([In, MarshalAs(UnmanagedType.LPWStr)] string filename, [In] IStream pIStream); void ReplaceSymbolStore([In, MarshalAs(UnmanagedType.LPWStr)] string filename, [In] IStream pIStream); void GetSymbolStoreFileName([In] uint cchName, [Out] out uint pcchName, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] szName); @@ -55,6 +63,48 @@ interface ISymUnmanagedReader { void GetMethodVersion([In] ISymUnmanagedMethod pMethod, [Out] out int version); } + [ComVisible(true), + ComImport, + Guid("A09E53B2-2A57-4cca-8F63-B84F7C35D4AA"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedReader2 : ISymUnmanagedReader { + void _VtblGap1_17(); + void GetMethodByVersionPreRemap(uint token, uint version, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedMethod pRetVal); + void GetSymAttributePreRemap(uint parent, [In, MarshalAs(UnmanagedType.LPWStr)] string name, uint cBuffer, out uint pcBuffer, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer); + void GetMethodsInDocument(ISymUnmanagedDocument document, uint bufferLength, out uint count, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] [In] [Out] ISymUnmanagedMethod[] methods); + } + + [ComVisible(true), + ComImport, + Guid("6151CAD9-E1EE-437A-A808-F64838C0D046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedReader3 : ISymUnmanagedReader2 { + void _VtblGap1_20(); + void GetSymAttributeByVersion(uint token, uint version, [MarshalAs(UnmanagedType.LPWStr)] string name, uint cBuffer, out uint pcBuffer, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] buffer); + void GetSymAttributeByVersionPreRemap(int methodToken, int version, [MarshalAs(UnmanagedType.LPWStr)] string name, int cBuffer, out int pcBuffer, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] buffer); + } + + [ComVisible(true), + ComImport, + Guid("E65C58B7-2948-434D-8A6D-481740A00C16"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedReader4 : ISymUnmanagedReader3 { + void _VtblGap1_22(); + [PreserveSig] + int MatchesModule(Guid guid, uint stamp, uint age, [MarshalAs(UnmanagedType.Bool)] out bool result); + void GetPortableDebugMetadata(out IntPtr pMetadata, out uint pcMetadata); + void GetSourceServerData(out IntPtr data, out uint pcData); + } + + [ComVisible(true), + ComImport, + Guid("6576C987-7E8D-4298-A6E1-6F9783165F07"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedReader5 : ISymUnmanagedReader4 { + void _VtblGap1_25(); + void GetPortableDebugMetadataByVersion(uint version, out IntPtr pMetadata, out uint pcMetadata); + } + [ComVisible(true), ComImport, Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08"), @@ -89,6 +139,15 @@ interface ISymUnmanagedMethod { void GetSequencePoints([In] uint cPoints, [Out] out uint pcPoints, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] offsets, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedDocument[] documents, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] lines, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] columns, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] endLines, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] endColumns); } + [ComVisible(true), + ComImport, + Guid("5DA320C8-9C2C-4E5A-B823-027E0677B359"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedMethod2 : ISymUnmanagedMethod { + void _VtblGap1_10(); + void GetLocalSignatureToken(out uint token); + } + [ComVisible(true), ComImport, Guid("B20D55B3-532E-4906-87E7-25BD5734ABD2"), @@ -178,7 +237,7 @@ interface ISymUnmanagedConstant { ComImport, Guid("7DAC8207-D3AE-4C75-9B67-92801A497D44"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface IMetaDataImport { + unsafe interface IMetaDataImport { void CloseEnum(IntPtr hEnum); void CountEnum(IntPtr hEnum, ref uint pulCount); void ResetEnum(IntPtr hEnum, uint ulPos); @@ -188,9 +247,9 @@ interface IMetaDataImport { void FindTypeDefByName([In, MarshalAs(UnmanagedType.LPWStr)] string szTypeDef, [In] uint tkEnclosingClass, [Out] out uint ptd); void GetScopeProps([Out] IntPtr szName, [In] uint cchName, [Out] out uint pchName, [Out] out Guid pmvid); void GetModuleFromScope([Out] out uint pmd); - unsafe void GetTypeDefProps([In] uint td, [In] ushort* szTypeDef, [In] uint cchTypeDef, [Out] uint* pchTypeDef, [Out] uint* pdwTypeDefFlags, [Out] uint* ptkExtends); + void GetTypeDefProps([In] uint td, [In] ushort* szTypeDef, [In] uint cchTypeDef, [Out] uint* pchTypeDef, [Out] uint* pdwTypeDefFlags, [Out] uint* ptkExtends); void GetInterfaceImplProps([In] uint iiImpl, [Out] out uint pClass, [Out] out uint ptkIface); - void GetTypeRefProps([In] uint tr, [Out] out uint ptkResolutionScope, [Out] IntPtr szName, [In] uint cchName, [Out] out uint pchName); + void GetTypeRefProps([In] uint tr, [Out] uint* ptkResolutionScope, [Out] ushort* szName, [In] uint cchName, [Out] uint* pchName); void ResolveTypeRef(uint tr, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppIScope, out uint ptd); void EnumMembers([In, Out] ref IntPtr phEnum, [In] uint cl, [Out] uint[] rMembers, [In] uint cMax, [Out] out uint pcTokens); void EnumMembersWithName([In, Out] ref IntPtr phEnum, [In] uint cl, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [Out] uint[] rMembers, [In] uint cMax, [Out] out uint pcTokens); @@ -206,7 +265,7 @@ interface IMetaDataImport { void FindMethod([In] uint td, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, [Out] out uint pmb); void FindField([In] uint td, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, [Out] out uint pmb); void FindMemberRef([In] uint td, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, [Out] out uint pmr); - unsafe void GetMethodProps(uint mb, uint* pClass, [In] ushort* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, [Out] IntPtr* ppvSigBlob, [Out] uint* pcbSigBlob, [Out] uint* pulCodeRVA, [Out] uint* pdwImplFlags); + void GetMethodProps(uint mb, uint* pClass, [In] ushort* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, [Out] IntPtr* ppvSigBlob, [Out] uint* pcbSigBlob, [Out] uint* pulCodeRVA, [Out] uint* pdwImplFlags); void GetMemberRefProps([In] uint mr, [Out] out uint ptk, [Out] IntPtr szMember, [In] uint cchMember, [Out] out uint pchMember, [Out] out IntPtr ppvSigBlob, [Out] out uint pbSig); void EnumProperties([In, Out] ref IntPtr phEnum, [In] uint td, [Out] uint[] rProperties, [In] uint cMax, [Out] out uint pcProperties); void EnumEvents([In, Out] ref IntPtr phEnum, [In] uint td, [Out] uint[] rEvents, [In] uint cMax, [Out] out uint pcEvents); @@ -217,7 +276,7 @@ interface IMetaDataImport { void GetFieldMarshal([In] uint tk, [Out] out IntPtr ppvNativeType, [Out] out uint pcbNativeType); void GetRVA(uint tk, out uint pulCodeRVA, out uint pdwImplFlags); void GetPermissionSetProps([In] uint pm, [Out] out uint pdwAction, [Out] out IntPtr ppvPermission, [Out] out uint pcbPermission); - void GetSigFromToken([In] uint mdSig, [Out] out IntPtr ppvSig, [Out] out uint pcbSig); + void GetSigFromToken([In] uint mdSig, [Out] byte** ppvSig, [Out] uint* pcbSig); void GetModuleRefProps([In] uint mur, [Out] IntPtr szName, [In] uint cchName, [Out] out uint pchName); void EnumModuleRefs([In, Out] ref IntPtr phEnum, [Out] uint[] rModuleRefs, [In] uint cmax, [Out] out uint pcModuleRefs); void GetTypeSpecFromToken([In] uint typespec, [Out] out IntPtr ppvSig, [Out] out uint pcbSig); @@ -238,7 +297,7 @@ interface IMetaDataImport { void GetParamProps([In] uint tk, [Out] out uint pmd, [Out] out uint pulSequence, [Out] IntPtr szName, [Out] uint cchName, [Out] out uint pchName, [Out] out uint pdwAttr, [Out] out uint pdwCPlusTypeFlag, [Out] out IntPtr ppValue, [Out] out uint pcchValue); void GetCustomAttributeByName([In] uint tkObj, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [Out] out IntPtr ppData, [Out] out uint pcbData); bool IsValidToken([In] uint tk); - unsafe void GetNestedClassProps([In] uint tdNestedClass, [Out] uint* ptdEnclosingClass); + void GetNestedClassProps([In] uint tdNestedClass, [Out] uint* ptdEnclosingClass); void GetNativeCallConvFromSig([In] IntPtr pvSig, [In] uint cbSig, [Out] out uint pCallConv); void IsGlobal([In] uint pd, [Out] out int pbGlobal); } @@ -330,7 +389,6 @@ interface ISymUnmanagedWriter { void Abort(); } -#pragma warning disable 1591 [ComVisible(true), ComImport, Guid("0B97726E-9E6D-4F05-9A26-424022093CAA"), @@ -364,9 +422,75 @@ interface ISymUnmanagedWriter2 { void DefineGlobalVariable2([In, MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint sigToken, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); void DefineConstant2([In, MarshalAs(UnmanagedType.LPWStr)] string name, [In] object value, [In] uint sigToken); } -#pragma warning restore 1591 -#pragma warning disable 1591 + [ComVisible(true), + ComImport, + Guid("12F1E02C-1E05-4B0E-9468-EBC9D1BB040F"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedWriter3 : ISymUnmanagedWriter2 { + void _VtblGap1_27(); + void OpenMethod2(uint method, uint isect, uint offset); + void Commit(); + } + + [ComVisible(true), + ComImport, + Guid("BC7E3F53-F458-4C23-9DBD-A189E6E96594"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedWriter4 : ISymUnmanagedWriter3 { + void _VtblGap1_29(); + void GetDebugInfoWithPadding([In] [Out] ref IMAGE_DEBUG_DIRECTORY pIDD, uint cData, out uint pcData, IntPtr data); + } + + [ComVisible(true), + ComImport, + Guid("DCF7780D-BDE9-45DF-ACFE-21731A32000C"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedWriter5 : ISymUnmanagedWriter4 { + void _VtblGap1_30(); + void OpenMapTokensToSourceSpans(); + void CloseMapTokensToSourceSpans(); + void MapTokenToSourceSpan(uint token, ISymUnmanagedDocumentWriter document, uint line, uint column, uint endLine, uint endColumn); + } + + [ComVisible(true), + ComImport, + Guid("CA6C2ED9-103D-46A9-B03B-05446485848B"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedWriter6 : ISymUnmanagedWriter5 { + void _VtblGap1_33(); + void InitializeDeterministic([MarshalAs(UnmanagedType.IUnknown)] object emitter, [MarshalAs(UnmanagedType.IUnknown)] object stream); + } + + [ComVisible(true), + ComImport, + Guid("22DAEAF2-70F6-4EF1-B0C3-984F0BF27BFD"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedWriter7 : ISymUnmanagedWriter6 { + void _VtblGap1_34(); + void UpdateSignatureByHashingContent(IntPtr buffer, uint cData); + } + + [ComVisible(true), + ComImport, + Guid("5BA52F3B-6BF8-40FC-B476-D39C529B331E"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ISymUnmanagedWriter8 : ISymUnmanagedWriter7 { + void _VtblGap1_35(); + void UpdateSignature(Guid pdbId, uint stamp, uint age); + void SetSourceServerData(IntPtr data, uint cData); + void SetSourceLinkData(IntPtr data, uint cData); + } + + [ComVisible(true), + ComImport, + Guid("98ECEE1E-752D-11d3-8D56-00C04F680B2B"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface IPdbWriter { + void _VtblGap1_4(); + void GetSignatureAge(out uint sig, out uint age); + } + [ComVisible(true), ComImport, Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006"), @@ -375,7 +499,6 @@ interface ISymUnmanagedDocumentWriter { void SetSource([In] uint sourceSize, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] source); void SetCheckSum([In] Guid algorithmId, [In] uint checkSumSize, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] checkSum); } -#pragma warning restore 1591 [ComVisible(true), ComImport, diff --git a/src/DotNet/Pdb/Dss/DataReaderIStream.cs b/src/DotNet/Pdb/Dss/DataReaderIStream.cs index 93f664ca5..1387f9b28 100644 --- a/src/DotNet/Pdb/Dss/DataReaderIStream.cs +++ b/src/DotNet/Pdb/Dss/DataReaderIStream.cs @@ -6,9 +6,6 @@ using dnlib.IO; namespace dnlib.DotNet.Pdb.Dss { - /// - /// Implements and uses an as the underlying stream. - /// sealed class DataReaderIStream : IStream, IDisposable { readonly DataReaderFactory dataReaderFactory; DataReader reader; @@ -17,17 +14,6 @@ sealed class DataReaderIStream : IStream, IDisposable { const int STG_E_INVALIDFUNCTION = unchecked((int)0x80030001); const int STG_E_CANTSAVE = unchecked((int)0x80030103); - /// - /// User can set this to anything he/she wants. If it implements , - /// its method will get called when this instance - /// is 'd. - /// - public object UserData { get; set; } - - /// - /// Constructor - /// - /// Source stream public DataReaderIStream(DataReaderFactory dataReaderFactory) : this(dataReaderFactory, dataReaderFactory.CreateReader(), string.Empty) { } @@ -38,14 +24,11 @@ public DataReaderIStream(DataReaderFactory dataReaderFactory) this.name = name ?? string.Empty; } - /// public void Clone(out IStream ppstm) => ppstm = new DataReaderIStream(dataReaderFactory, reader, name); - /// public void Commit(int grfCommitFlags) { } - /// public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { if (cb > int.MaxValue) cb = int.MaxValue; @@ -65,10 +48,8 @@ public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { Marshal.WriteInt64(pcbWritten, Marshal.ReadInt32(pcbWritten)); } - /// public void LockRegion(long libOffset, long cb, int dwLockType) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - /// public void Read(byte[] pv, int cb, IntPtr pcbRead) { if (cb < 0) cb = 0; @@ -80,7 +61,6 @@ public void Read(byte[] pv, int cb, IntPtr pcbRead) { Marshal.WriteInt32(pcbRead, cb); } - /// public void Revert() { } @@ -90,7 +70,6 @@ enum STREAM_SEEK { END = 2, } - /// public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) { switch ((STREAM_SEEK)dwOrigin) { case STREAM_SEEK.SET: @@ -110,7 +89,6 @@ public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) { Marshal.WriteInt64(plibNewPosition, reader.Position); } - /// public void SetSize(long libNewSize) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); enum STATFLAG { @@ -126,7 +104,6 @@ enum STGTY { PROPERTY = 4, } - /// public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag) { var s = new System.Runtime.InteropServices.ComTypes.STATSTG(); @@ -146,16 +123,8 @@ public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, i pstatstg = s; } - /// public void UnlockRegion(long libOffset, long cb, int dwLockType) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - - /// public void Write(byte[] pv, int cb, IntPtr pcbWritten) => Marshal.ThrowExceptionForHR(STG_E_CANTSAVE); - - /// - public void Dispose() { - if (UserData is IDisposable id) - id.Dispose(); - } + public void Dispose() { } } } diff --git a/src/DotNet/Pdb/Dss/MDEmitter.cs b/src/DotNet/Pdb/Dss/MDEmitter.cs index 4174f4530..6e7ebb0f2 100644 --- a/src/DotNet/Pdb/Dss/MDEmitter.cs +++ b/src/DotNet/Pdb/Dss/MDEmitter.cs @@ -6,18 +6,11 @@ using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Dss { - /// - /// Pass this instance to when writing the PDB file - /// - sealed class MDEmitter : IMetaDataImport, IMetaDataEmit { + sealed unsafe class MDEmitter : MetaDataImport, IMetaDataEmit { readonly Metadata metadata; readonly Dictionary tokenToTypeDef; readonly Dictionary tokenToMethodDef; - /// - /// Constructor - /// - /// Metadata public MDEmitter(Metadata metadata) { this.metadata = metadata; @@ -38,7 +31,7 @@ public MDEmitter(Metadata metadata) { } } - unsafe void IMetaDataImport.GetMethodProps(uint mb, uint* pClass, ushort* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr* ppvSigBlob, uint* pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags) { + public override void GetMethodProps(uint mb, uint* pClass, ushort* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, IntPtr* ppvSigBlob, uint* pcbSigBlob, uint* pulCodeRVA, uint* pdwImplFlags) { if ((mb >> 24) != 0x06) throw new ArgumentException(); var method = tokenToMethodDef[mb]; @@ -69,7 +62,7 @@ unsafe void IMetaDataImport.GetMethodProps(uint mb, uint* pClass, ushort* szMeth *pchMethod = (uint)len; } - unsafe void IMetaDataImport.GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends) { + public override void GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends) { if ((td >> 24) != 0x02) throw new ArgumentException(); var type = tokenToTypeDef[td]; @@ -78,20 +71,10 @@ unsafe void IMetaDataImport.GetTypeDefProps(uint td, ushort* szTypeDef, uint cch *pdwTypeDefFlags = row.Flags; if (ptkExtends != null) *ptkExtends = row.Extends; - - string name = type.Name.String ?? string.Empty; - int len = (int)Math.Min((uint)name.Length + 1, cchTypeDef); - if (szTypeDef != null) { - for (int i = 0; i < len - 1; i++, szTypeDef++) - *szTypeDef = (ushort)name[i]; - if (len > 0) - *szTypeDef = 0; - } - if (pchTypeDef != null) - *pchTypeDef = (uint)len; + CopyTypeName(type.Namespace, type.Name, szTypeDef, cchTypeDef, pchTypeDef); } - unsafe void IMetaDataImport.GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingClass) { + public override void GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingClass) { if ((tdNestedClass >> 24) != 0x02) throw new ArgumentException(); var type = tokenToTypeDef[tdNestedClass]; @@ -104,67 +87,10 @@ unsafe void IMetaDataImport.GetNestedClassProps(uint tdNestedClass, uint* ptdEnc } } + void IMetaDataEmit.GetTokenFromSig(IntPtr pvSig, uint cbSig, out uint pmsig) => pmsig = 0x11000000; + // The rest of the methods aren't called - void IMetaDataImport.CloseEnum(IntPtr hEnum) => throw new NotImplementedException(); - void IMetaDataImport.CountEnum(IntPtr hEnum, ref uint pulCount) => throw new NotImplementedException(); - void IMetaDataImport.ResetEnum(IntPtr hEnum, uint ulPos) => throw new NotImplementedException(); - void IMetaDataImport.EnumTypeDefs(IntPtr phEnum, uint[] rTypeDefs, uint cMax, out uint pcTypeDefs) => throw new NotImplementedException(); - void IMetaDataImport.EnumInterfaceImpls(ref IntPtr phEnum, uint td, uint[] rImpls, uint cMax, ref uint pcImpls) => throw new NotImplementedException(); - void IMetaDataImport.EnumTypeRefs(ref IntPtr phEnum, uint[] rTypeRefs, uint cMax, ref uint pcTypeRefs) => throw new NotImplementedException(); - void IMetaDataImport.FindTypeDefByName(string szTypeDef, uint tkEnclosingClass, out uint ptd) => throw new NotImplementedException(); - void IMetaDataImport.GetScopeProps(IntPtr szName, uint cchName, out uint pchName, out Guid pmvid) => throw new NotImplementedException(); - void IMetaDataImport.GetModuleFromScope(out uint pmd) => throw new NotImplementedException(); - void IMetaDataImport.GetInterfaceImplProps(uint iiImpl, out uint pClass, out uint ptkIface) => throw new NotImplementedException(); - void IMetaDataImport.GetTypeRefProps(uint tr, out uint ptkResolutionScope, IntPtr szName, uint cchName, out uint pchName) => throw new NotImplementedException(); - void IMetaDataImport.ResolveTypeRef(uint tr, ref Guid riid, out object ppIScope, out uint ptd) => throw new NotImplementedException(); - void IMetaDataImport.EnumMembers(ref IntPtr phEnum, uint cl, uint[] rMembers, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumMembersWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMembers, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumMethods(ref IntPtr phEnum, uint cl, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumMethodsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumFields(ref IntPtr phEnum, uint cl, uint[] rFields, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumFieldsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rFields, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumParams(ref IntPtr phEnum, uint mb, uint[] rParams, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumMemberRefs(ref IntPtr phEnum, uint tkParent, uint[] rMemberRefs, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumMethodImpls(ref IntPtr phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.EnumPermissionSets(ref IntPtr phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.FindMember(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); - void IMetaDataImport.FindMethod(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); - void IMetaDataImport.FindField(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); - void IMetaDataImport.FindMemberRef(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmr) => throw new NotImplementedException(); - void IMetaDataImport.GetMemberRefProps(uint mr, out uint ptk, IntPtr szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob, out uint pbSig) => throw new NotImplementedException(); - void IMetaDataImport.EnumProperties(ref IntPtr phEnum, uint td, uint[] rProperties, uint cMax, out uint pcProperties) => throw new NotImplementedException(); - void IMetaDataImport.EnumEvents(ref IntPtr phEnum, uint td, uint[] rEvents, uint cMax, out uint pcEvents) => throw new NotImplementedException(); - void IMetaDataImport.GetEventProps(uint ev, out uint pClass, string szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) => throw new NotImplementedException(); - void IMetaDataImport.EnumMethodSemantics(ref IntPtr phEnum, uint mb, uint[] rEventProp, uint cMax, out uint pcEventProp) => throw new NotImplementedException(); - void IMetaDataImport.GetMethodSemantics(uint mb, uint tkEventProp, out uint pdwSemanticsFlags) => throw new NotImplementedException(); - void IMetaDataImport.GetClassLayout(uint td, out uint pdwPackSize, out IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset, out uint pulClassSize) => throw new NotImplementedException(); - void IMetaDataImport.GetFieldMarshal(uint tk, out IntPtr ppvNativeType, out uint pcbNativeType) => throw new NotImplementedException(); - void IMetaDataImport.GetRVA(uint tk, out uint pulCodeRVA, out uint pdwImplFlags) => throw new NotImplementedException(); - void IMetaDataImport.GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission, out uint pcbPermission) => throw new NotImplementedException(); - void IMetaDataImport.GetSigFromToken(uint mdSig, out IntPtr ppvSig, out uint pcbSig) => throw new NotImplementedException(); - void IMetaDataImport.GetModuleRefProps(uint mur, IntPtr szName, uint cchName, out uint pchName) => throw new NotImplementedException(); - void IMetaDataImport.EnumModuleRefs(ref IntPtr phEnum, uint[] rModuleRefs, uint cmax, out uint pcModuleRefs) => throw new NotImplementedException(); - void IMetaDataImport.GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig, out uint pcbSig) => throw new NotImplementedException(); - void IMetaDataImport.GetNameFromToken(uint tk, out IntPtr pszUtf8NamePtr) => throw new NotImplementedException(); - void IMetaDataImport.EnumUnresolvedMethods(ref IntPtr phEnum, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); - void IMetaDataImport.GetUserString(uint stk, IntPtr szString, uint cchString, out uint pchString) => throw new NotImplementedException(); - void IMetaDataImport.GetPinvokeMap(uint tk, out uint pdwMappingFlags, IntPtr szImportName, uint cchImportName, out uint pchImportName, out uint pmrImportDLL) => throw new NotImplementedException(); - void IMetaDataImport.EnumSignatures(ref IntPtr phEnum, uint[] rSignatures, uint cmax, out uint pcSignatures) => throw new NotImplementedException(); - void IMetaDataImport.EnumTypeSpecs(ref IntPtr phEnum, uint[] rTypeSpecs, uint cmax, out uint pcTypeSpecs) => throw new NotImplementedException(); - void IMetaDataImport.EnumUserStrings(ref IntPtr phEnum, uint[] rStrings, uint cmax, out uint pcStrings) => throw new NotImplementedException(); - void IMetaDataImport.GetParamForMethodIndex(uint md, uint ulParamSeq, out uint ppd) => throw new NotImplementedException(); - void IMetaDataImport.EnumCustomAttributes(IntPtr phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax, out uint pcCustomAttributes) => throw new NotImplementedException(); - void IMetaDataImport.GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob, out uint pcbSize) => throw new NotImplementedException(); - void IMetaDataImport.FindTypeRef(uint tkResolutionScope, string szName, out uint ptr) => throw new NotImplementedException(); - void IMetaDataImport.GetMemberProps(uint mb, out uint pClass, IntPtr szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); - void IMetaDataImport.GetFieldProps(uint mb, out uint pClass, IntPtr szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); - void IMetaDataImport.GetPropertyProps(uint prop, out uint pClass, IntPtr szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) => throw new NotImplementedException(); - void IMetaDataImport.GetParamProps(uint tk, out uint pmd, out uint pulSequence, IntPtr szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); - void IMetaDataImport.GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData, out uint pcbData) => throw new NotImplementedException(); - bool IMetaDataImport.IsValidToken(uint tk) => throw new NotImplementedException(); - void IMetaDataImport.GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig, out uint pCallConv) => throw new NotImplementedException(); - void IMetaDataImport.IsGlobal(uint pd, out int pbGlobal) => throw new NotImplementedException(); void IMetaDataEmit.SetModuleProps(string szName) => throw new NotImplementedException(); void IMetaDataEmit.Save(string szFile, uint dwSaveFlags) => throw new NotImplementedException(); void IMetaDataEmit.SaveToStream(IStream pIStream, uint dwSaveFlags) => throw new NotImplementedException(); @@ -185,7 +111,6 @@ unsafe void IMetaDataImport.GetNestedClassProps(uint tdNestedClass, uint* ptdEnc void IMetaDataEmit.DeleteFieldMarshal(uint tk) => throw new NotImplementedException(); void IMetaDataEmit.DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission, out uint ppm) => throw new NotImplementedException(); void IMetaDataEmit.SetRVA(uint md, uint ulRVA) => throw new NotImplementedException(); - void IMetaDataEmit.GetTokenFromSig(IntPtr pvSig, uint cbSig, out uint pmsig) => throw new NotImplementedException(); void IMetaDataEmit.DefineModuleRef(string szName, out uint pmur) => throw new NotImplementedException(); void IMetaDataEmit.SetParent(uint mr, uint tk) => throw new NotImplementedException(); void IMetaDataEmit.GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig, out uint ptypespec) => throw new NotImplementedException(); diff --git a/src/DotNet/Pdb/Dss/MetaDataImport.cs b/src/DotNet/Pdb/Dss/MetaDataImport.cs new file mode 100644 index 000000000..a1d7a041a --- /dev/null +++ b/src/DotNet/Pdb/Dss/MetaDataImport.cs @@ -0,0 +1,106 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace dnlib.DotNet.Pdb.Dss { + unsafe abstract class MetaDataImport : IMetaDataImport { + public virtual void GetTypeDefProps([In] uint td, [In] ushort* szTypeDef, [In] uint cchTypeDef, [Out] uint* pchTypeDef, [Out] uint* pdwTypeDefFlags, [Out] uint* ptkExtends) => throw new NotImplementedException(); + public virtual void GetMethodProps(uint mb, uint* pClass, [In] ushort* szMethod, uint cchMethod, uint* pchMethod, uint* pdwAttr, [Out] IntPtr* ppvSigBlob, [Out] uint* pcbSigBlob, [Out] uint* pulCodeRVA, [Out] uint* pdwImplFlags) => throw new NotImplementedException(); + public virtual void GetNestedClassProps([In] uint tdNestedClass, [Out] uint* ptdEnclosingClass) => throw new NotImplementedException(); + public virtual void GetSigFromToken(uint mdSig, byte** ppvSig, uint* pcbSig) => throw new NotImplementedException(); + public virtual void GetTypeRefProps(uint tr, uint* ptkResolutionScope, ushort* szName, uint cchName, uint* pchName) => throw new NotImplementedException(); + + protected void CopyTypeName(string typeNamespace, string typeName, ushort* destBuffer, uint destBufferLen, uint* requiredLength) { + if (typeName == null) + typeName = string.Empty; + if (typeNamespace == null) + typeNamespace = string.Empty; + + if (destBuffer != null && destBufferLen > 0) { + uint maxChars = destBufferLen - 1; + uint w = 0; + if (typeNamespace.Length > 0) { + for (int i = 0; i < typeNamespace.Length && w < maxChars; i++, w++) + *destBuffer++ = typeNamespace[i]; + if (w < maxChars) { + *destBuffer++ = '.'; + w++; + } + } + for (int i = 0; i < typeName.Length && w < maxChars; i++, w++) + *destBuffer++ = typeName[i]; + Debug.Assert(w < destBufferLen); + *destBuffer = 0; + } + + if (requiredLength != null) { + int totalLen = typeNamespace.Length == 0 ? typeName.Length : typeNamespace.Length + 1 + typeName.Length; + int copyLen = Math.Min(totalLen, (int)Math.Min(int.MaxValue, destBufferLen == 0 ? 0 : destBufferLen - 1)); + if (destBuffer != null) + *requiredLength = (uint)copyLen; + else + *requiredLength = (uint)totalLen; + } + } + + void IMetaDataImport.CloseEnum(IntPtr hEnum) => throw new NotImplementedException(); + void IMetaDataImport.CountEnum(IntPtr hEnum, ref uint pulCount) => throw new NotImplementedException(); + void IMetaDataImport.ResetEnum(IntPtr hEnum, uint ulPos) => throw new NotImplementedException(); + void IMetaDataImport.EnumTypeDefs(IntPtr phEnum, uint[] rTypeDefs, uint cMax, out uint pcTypeDefs) => throw new NotImplementedException(); + void IMetaDataImport.EnumInterfaceImpls(ref IntPtr phEnum, uint td, uint[] rImpls, uint cMax, ref uint pcImpls) => throw new NotImplementedException(); + void IMetaDataImport.EnumTypeRefs(ref IntPtr phEnum, uint[] rTypeRefs, uint cMax, ref uint pcTypeRefs) => throw new NotImplementedException(); + void IMetaDataImport.FindTypeDefByName(string szTypeDef, uint tkEnclosingClass, out uint ptd) => throw new NotImplementedException(); + void IMetaDataImport.GetScopeProps(IntPtr szName, uint cchName, out uint pchName, out Guid pmvid) => throw new NotImplementedException(); + void IMetaDataImport.GetModuleFromScope(out uint pmd) => throw new NotImplementedException(); + void IMetaDataImport.GetInterfaceImplProps(uint iiImpl, out uint pClass, out uint ptkIface) => throw new NotImplementedException(); + void IMetaDataImport.ResolveTypeRef(uint tr, ref Guid riid, out object ppIScope, out uint ptd) => throw new NotImplementedException(); + void IMetaDataImport.EnumMembers(ref IntPtr phEnum, uint cl, uint[] rMembers, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMembersWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMembers, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethods(ref IntPtr phEnum, uint cl, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethodsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumFields(ref IntPtr phEnum, uint cl, uint[] rFields, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumFieldsWithName(ref IntPtr phEnum, uint cl, string szName, uint[] rFields, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumParams(ref IntPtr phEnum, uint mb, uint[] rParams, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMemberRefs(ref IntPtr phEnum, uint tkParent, uint[] rMemberRefs, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethodImpls(ref IntPtr phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.EnumPermissionSets(ref IntPtr phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.FindMember(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); + void IMetaDataImport.FindMethod(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); + void IMetaDataImport.FindField(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmb) => throw new NotImplementedException(); + void IMetaDataImport.FindMemberRef(uint td, string szName, IntPtr pvSigBlob, uint cbSigBlob, out uint pmr) => throw new NotImplementedException(); + void IMetaDataImport.GetMemberRefProps(uint mr, out uint ptk, IntPtr szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob, out uint pbSig) => throw new NotImplementedException(); + void IMetaDataImport.EnumProperties(ref IntPtr phEnum, uint td, uint[] rProperties, uint cMax, out uint pcProperties) => throw new NotImplementedException(); + void IMetaDataImport.EnumEvents(ref IntPtr phEnum, uint td, uint[] rEvents, uint cMax, out uint pcEvents) => throw new NotImplementedException(); + void IMetaDataImport.GetEventProps(uint ev, out uint pClass, string szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) => throw new NotImplementedException(); + void IMetaDataImport.EnumMethodSemantics(ref IntPtr phEnum, uint mb, uint[] rEventProp, uint cMax, out uint pcEventProp) => throw new NotImplementedException(); + void IMetaDataImport.GetMethodSemantics(uint mb, uint tkEventProp, out uint pdwSemanticsFlags) => throw new NotImplementedException(); + void IMetaDataImport.GetClassLayout(uint td, out uint pdwPackSize, out IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset, out uint pulClassSize) => throw new NotImplementedException(); + void IMetaDataImport.GetFieldMarshal(uint tk, out IntPtr ppvNativeType, out uint pcbNativeType) => throw new NotImplementedException(); + void IMetaDataImport.GetRVA(uint tk, out uint pulCodeRVA, out uint pdwImplFlags) => throw new NotImplementedException(); + void IMetaDataImport.GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission, out uint pcbPermission) => throw new NotImplementedException(); + void IMetaDataImport.GetModuleRefProps(uint mur, IntPtr szName, uint cchName, out uint pchName) => throw new NotImplementedException(); + void IMetaDataImport.EnumModuleRefs(ref IntPtr phEnum, uint[] rModuleRefs, uint cmax, out uint pcModuleRefs) => throw new NotImplementedException(); + void IMetaDataImport.GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig, out uint pcbSig) => throw new NotImplementedException(); + void IMetaDataImport.GetNameFromToken(uint tk, out IntPtr pszUtf8NamePtr) => throw new NotImplementedException(); + void IMetaDataImport.EnumUnresolvedMethods(ref IntPtr phEnum, uint[] rMethods, uint cMax, out uint pcTokens) => throw new NotImplementedException(); + void IMetaDataImport.GetUserString(uint stk, IntPtr szString, uint cchString, out uint pchString) => throw new NotImplementedException(); + void IMetaDataImport.GetPinvokeMap(uint tk, out uint pdwMappingFlags, IntPtr szImportName, uint cchImportName, out uint pchImportName, out uint pmrImportDLL) => throw new NotImplementedException(); + void IMetaDataImport.EnumSignatures(ref IntPtr phEnum, uint[] rSignatures, uint cmax, out uint pcSignatures) => throw new NotImplementedException(); + void IMetaDataImport.EnumTypeSpecs(ref IntPtr phEnum, uint[] rTypeSpecs, uint cmax, out uint pcTypeSpecs) => throw new NotImplementedException(); + void IMetaDataImport.EnumUserStrings(ref IntPtr phEnum, uint[] rStrings, uint cmax, out uint pcStrings) => throw new NotImplementedException(); + void IMetaDataImport.GetParamForMethodIndex(uint md, uint ulParamSeq, out uint ppd) => throw new NotImplementedException(); + void IMetaDataImport.EnumCustomAttributes(IntPtr phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax, out uint pcCustomAttributes) => throw new NotImplementedException(); + void IMetaDataImport.GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob, out uint pcbSize) => throw new NotImplementedException(); + void IMetaDataImport.FindTypeRef(uint tkResolutionScope, string szName, out uint ptr) => throw new NotImplementedException(); + void IMetaDataImport.GetMemberProps(uint mb, out uint pClass, IntPtr szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); + void IMetaDataImport.GetFieldProps(uint mb, out uint pClass, IntPtr szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); + void IMetaDataImport.GetPropertyProps(uint prop, out uint pClass, IntPtr szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod) => throw new NotImplementedException(); + void IMetaDataImport.GetParamProps(uint tk, out uint pmd, out uint pulSequence, IntPtr szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue) => throw new NotImplementedException(); + void IMetaDataImport.GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData, out uint pcbData) => throw new NotImplementedException(); + bool IMetaDataImport.IsValidToken(uint tk) => throw new NotImplementedException(); + void IMetaDataImport.GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig, out uint pCallConv) => throw new NotImplementedException(); + void IMetaDataImport.IsGlobal(uint pd, out int pbGlobal) => throw new NotImplementedException(); + } +} diff --git a/src/DotNet/Pdb/Dss/PinnedMetadata.cs b/src/DotNet/Pdb/Dss/PinnedMetadata.cs deleted file mode 100644 index 6aa6c3f6e..000000000 --- a/src/DotNet/Pdb/Dss/PinnedMetadata.cs +++ /dev/null @@ -1,75 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using dnlib.DotNet.MD; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Dss { - /// - /// Pins a metadata stream in memory - /// - sealed class PinnedMetadata : IDisposable { - GCHandle gcHandle; - readonly byte[] streamData; - readonly IntPtr address; - - /// - /// Gets the address - /// - public IntPtr Address => address; - - /// - /// Gets the size - /// - public int Size { get; } - - /// - /// Constructor - /// - /// .NET metadata - public unsafe PinnedMetadata(Metadata metadata) { - var peImage = metadata.PEImage; - var mdDataDir = metadata.ImageCor20Header.Metadata; - var mdReader = peImage.CreateReader(mdDataDir.VirtualAddress, mdDataDir.Size); - Size = (int)mdReader.Length; - - var realDataReaderFactory = peImage.DataReaderFactory; - if (realDataReaderFactory is NativeMemoryDataReaderFactory nativeMemFactory) { - address = (IntPtr)((byte*)nativeMemFactory.GetUnsafeUseAddress() + mdReader.StartOffset); - GC.SuppressFinalize(this); // no GCHandle so finalizer isn't needed - } - else if (realDataReaderFactory is MemoryMappedDataReaderFactory mmapMemFactory) { - address = (IntPtr)((byte*)mmapMemFactory.GetUnsafeUseAddress() + mdReader.StartOffset); - GC.SuppressFinalize(this); // no GCHandle so finalizer isn't needed - } - else if (realDataReaderFactory is ByteArrayDataReaderFactory memFactory) { - streamData = memFactory.DataArray; - gcHandle = GCHandle.Alloc(streamData, GCHandleType.Pinned); - address = new IntPtr(gcHandle.AddrOfPinnedObject().ToInt64() + memFactory.DataOffset + mdReader.StartOffset); - } - else { - streamData = mdReader.ToArray(); - gcHandle = GCHandle.Alloc(streamData, GCHandleType.Pinned); - address = gcHandle.AddrOfPinnedObject(); - } - } - - ~PinnedMetadata() => Dispose(false); - - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - void Dispose(bool disposing) { - if (gcHandle.IsAllocated) { - try { - gcHandle.Free(); - } - catch (InvalidOperationException) { - } - } - } - } -} diff --git a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs new file mode 100644 index 000000000..7776ab8e5 --- /dev/null +++ b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs @@ -0,0 +1,84 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Runtime.InteropServices; +using System.Threading; +using dnlib.DotNet.MD; + +namespace dnlib.DotNet.Pdb.Dss { + sealed unsafe class ReaderMetaDataImport : MetaDataImport, IDisposable { + readonly Metadata metadata; + byte* blobPtr; + IntPtr addrToFree; + + public ReaderMetaDataImport(Metadata metadata) { + this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); + var reader = metadata.BlobStream.CreateReader(); + addrToFree = Marshal.AllocHGlobal((int)reader.BytesLeft); + blobPtr = (byte*)addrToFree; + if (blobPtr == null) + throw new OutOfMemoryException(); + reader.ReadBytes(blobPtr, (int)reader.BytesLeft); + } + + ~ReaderMetaDataImport() => Dispose(false); + + public override void GetTypeRefProps(uint tr, uint* ptkResolutionScope, ushort* szName, uint cchName, uint* pchName) { + var token = new MDToken(tr); + if (token.Table != Table.TypeRef) + throw new ArgumentException(); + if (!metadata.TablesStream.TryReadTypeRefRow(token.Rid, out var row)) + throw new ArgumentException(); + if (ptkResolutionScope != null) + *ptkResolutionScope = row.ResolutionScope; + if (szName != null || pchName != null) { + var typeNamespace = metadata.StringsStream.ReadNoNull(row.Namespace); + var typeName = metadata.StringsStream.ReadNoNull(row.Name); + CopyTypeName(typeNamespace, typeName, szName, cchName, pchName); + } + } + + public override void GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef, uint* pchTypeDef, uint* pdwTypeDefFlags, uint* ptkExtends) { + var token = new MDToken(td); + if (token.Table != Table.TypeDef) + throw new ArgumentException(); + if (!metadata.TablesStream.TryReadTypeDefRow(token.Rid, out var row)) + throw new ArgumentException(); + if (pdwTypeDefFlags != null) + *pdwTypeDefFlags = row.Flags; + if (ptkExtends != null) + *ptkExtends = row.Extends; + if (szTypeDef != null || pchTypeDef != null) { + var typeNamespace = metadata.StringsStream.ReadNoNull(row.Namespace); + var typeName = metadata.StringsStream.ReadNoNull(row.Name); + CopyTypeName(typeNamespace, typeName, szTypeDef, cchTypeDef, pchTypeDef); + } + } + + public override void GetSigFromToken(uint mdSig, byte** ppvSig, uint* pcbSig) { + var token = new MDToken(mdSig); + if (token.Table != Table.StandAloneSig) + throw new ArgumentException(); + if (!metadata.TablesStream.TryReadStandAloneSigRow(token.Rid, out var row)) + throw new ArgumentException(); + if (!metadata.BlobStream.TryCreateReader(row.Signature, out var reader)) + throw new ArgumentException(); + if (ppvSig != null) + *ppvSig = blobPtr + (reader.StartOffset - (uint)metadata.BlobStream.StartOffset); + if (pcbSig != null) + *pcbSig = reader.Length; + } + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + void Dispose(bool disposing) { + var addrToFreeTmp = Interlocked.Exchange(ref addrToFree, IntPtr.Zero); + blobPtr = null; + if (addrToFreeTmp != IntPtr.Zero) + Marshal.FreeHGlobal(addrToFreeTmp); + } + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs index ca02ca7a2..9c10c818e 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs @@ -8,7 +8,10 @@ sealed class SymbolDocumentWriter : ISymbolDocumentWriter { readonly ISymUnmanagedDocumentWriter writer; public ISymUnmanagedDocumentWriter SymUnmanagedDocumentWriter => writer; public SymbolDocumentWriter(ISymUnmanagedDocumentWriter writer) => this.writer = writer; - public void SetCheckSum(Guid algorithmId, byte[] checkSum) => writer.SetCheckSum(algorithmId, (uint)(checkSum == null ? 0 : checkSum.Length), checkSum); + public void SetCheckSum(Guid algorithmId, byte[] checkSum) { + if (checkSum != null && checkSum.Length != 0 && algorithmId != Guid.Empty) + writer.SetCheckSum(algorithmId, (uint)checkSum.Length, checkSum); + } public void SetSource(byte[] source) => writer.SetSource((uint)source.Length, source); } } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs b/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs deleted file mode 100644 index ba5b95516..000000000 --- a/src/DotNet/Pdb/Dss/SymbolReaderCreator.cs +++ /dev/null @@ -1,136 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Security; -using dnlib.DotNet.MD; -using dnlib.IO; -using dnlib.DotNet.Pdb.Symbols; - -namespace dnlib.DotNet.Pdb.Dss { - /// - /// Creates a instance - /// - static class SymbolReaderCreator { - [DllImport("ole32")] - static extern int CoCreateInstance([In] ref Guid rclsid, IntPtr pUnkOuter, [In] uint dwClsContext, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppv); - - static readonly Guid CLSID_CorSymBinder_SxS = new Guid(0x0A29FF9E, 0x7F9C, 0x4437, 0x8B, 0x11, 0xF4, 0x24, 0x49, 0x1E, 0x39, 0x31); - - /// - /// Creates a new instance - /// - /// Path to assembly - /// A new instance or null if there's no PDB - /// file on disk or if any of the COM methods fail. - public static SymbolReader CreateFromAssemblyFile(string assemblyFileName) { - try { - var CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); - var IID_IMetaDataDispenser = new Guid(0x809C652E, 0x7396, 0x11D2, 0x97, 0x71, 0x00, 0xA0, 0xC9, 0xB4, 0xD5, 0x0C); - int hr = CoCreateInstance(ref CLSID_CorMetaDataDispenser, IntPtr.Zero, 1, ref IID_IMetaDataDispenser, out object mdDispObj); - if (hr < 0) - return null; - - var mdDisp = (IMetaDataDispenser)mdDispObj; - var IID_IMetaDataImport = new Guid(0x7DAC8207, 0xD3AE, 0x4C75, 0x9B, 0x67, 0x92, 0x80, 0x1A, 0x49, 0x7D, 0x44); - mdDisp.OpenScope(assemblyFileName, 0, ref IID_IMetaDataImport, out object mdImportObj); - Marshal.FinalReleaseComObject(mdDispObj); - - var binder = (ISymUnmanagedBinder)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymBinder_SxS)); - hr = binder.GetReaderForFile((IMetaDataImport)mdImportObj, assemblyFileName, null, out var symReader); - Marshal.FinalReleaseComObject(mdImportObj); - Marshal.FinalReleaseComObject(binder); - if (hr >= 0) - return new SymbolReaderImpl(symReader); - } - catch (IOException) { - } - catch (UnauthorizedAccessException) { - } - catch (SecurityException) { - } - catch (InvalidCastException) { - } - catch (COMException) { - } - return null; - } - - /// - /// Creates a new instance - /// - /// .NET metadata - /// Path to PDB file - /// A new instance or null if there's no PDB - /// file on disk or if any of the COM methods fail. - public static SymbolReader Create(Metadata metadata, string pdbFileName) => - Create(metadata, DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); - - /// - /// Creates a new instance - /// - /// .NET metadata - /// PDB file data - /// A new instance or null if any of the COM - /// methods fail. - public static SymbolReader Create(Metadata metadata, byte[] pdbData) { - if (pdbData == null) - return null; - return Create(metadata, ByteArrayDataReaderFactory.Create(pdbData, filename: null)); - } - - /// - /// Creates a new instance - /// - /// .NET metadata - /// PDB file stream which is now owned by this method - /// A new instance or null if any of the COM - /// methods fail. - public static SymbolReader Create(Metadata metadata, DataReaderFactory pdbStream) { - DataReaderIStream stream = null; - PinnedMetadata pinnedMd = null; - bool error = true; - try { - if (pdbStream == null) - return null; - - var CLSID_CorMetaDataDispenser = new Guid(0xE5CB7A31, 0x7512, 0x11D2, 0x89, 0xCE, 0x0, 0x80, 0xC7, 0x92, 0xE5, 0xD8); - var IID_IMetaDataDispenser = new Guid(0x809C652E, 0x7396, 0x11D2, 0x97, 0x71, 0x00, 0xA0, 0xC9, 0xB4, 0xD5, 0x0C); - int hr = CoCreateInstance(ref CLSID_CorMetaDataDispenser, IntPtr.Zero, 1, ref IID_IMetaDataDispenser, out object mdDispObj); - if (hr < 0) - return null; - - var mdDisp = (IMetaDataDispenser)mdDispObj; - var IID_IMetaDataImport = new Guid(0x7DAC8207, 0xD3AE, 0x4C75, 0x9B, 0x67, 0x92, 0x80, 0x1A, 0x49, 0x7D, 0x44); - pinnedMd = new PinnedMetadata(metadata); - mdDisp.OpenScopeOnMemory(pinnedMd.Address, (uint)pinnedMd.Size, 0x10, ref IID_IMetaDataImport, out object mdImportObj); - Marshal.FinalReleaseComObject(mdDispObj); - - var binder = (ISymUnmanagedBinder)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymBinder_SxS)); - stream = new DataReaderIStream(pdbStream) { UserData = pinnedMd }; - hr = binder.GetReaderFromStream((IMetaDataImport)mdImportObj, stream, out var symReader); - Marshal.FinalReleaseComObject(mdImportObj); - Marshal.FinalReleaseComObject(binder); - if (hr >= 0) { - error = false; - return new SymbolReaderImpl(symReader); - } - } - catch (IOException) { - } - catch (InvalidCastException) { - } - catch (COMException) { - } - finally { - if (error) { - stream?.Dispose(); - pinnedMd?.Dispose(); - pdbStream?.Dispose(); - } - } - return null; - } - } -} diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index c2534bfa7..b658ad238 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -11,15 +11,16 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolReaderImpl : SymbolReader { ModuleDef module; readonly ISymUnmanagedReader reader; + readonly object[] objsToKeepAlive; const int E_FAIL = unchecked((int)0x80004005); - /// - /// Constructor - /// - /// An unmanaged symbol reader - public SymbolReaderImpl(ISymUnmanagedReader reader) => + public SymbolReaderImpl(ISymUnmanagedReader reader, object[] objsToKeepAlive) { this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); + this.objsToKeepAlive = objsToKeepAlive ?? throw new ArgumentNullException(nameof(objsToKeepAlive)); + } + + ~SymbolReaderImpl() => Dispose(false); public override PdbFileKind PdbFileKind => PdbFileKind.WindowsPDB; @@ -76,5 +77,29 @@ internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { } + + public override void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + void Dispose(bool disposing) { + (reader as ISymUnmanagedDispose)?.Destroy(); + foreach (var obj in objsToKeepAlive) + (obj as IDisposable)?.Dispose(); + } + + public bool CheckVersion(Guid pdbId, uint stamp, uint age) { + if (reader is ISymUnmanagedReader4 reader4) { + // Only id and age are verified + int hr = reader4.MatchesModule(pdbId, stamp, age, out bool result); + if (hr < 0) + return false; + return result; + } + + // There seems to be no other method that can verify that we opened the correct PDB, so return true + return true; + } } } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs new file mode 100644 index 000000000..6801013b3 --- /dev/null +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -0,0 +1,196 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.IO; +using System.Runtime.InteropServices; +using dnlib.IO; +using dnlib.DotNet.Pdb.Symbols; +using System.Diagnostics; +using dnlib.PE; +using dnlib.DotNet.Writer; +using dnlib.DotNet.Pdb.WindowsPdb; + +namespace dnlib.DotNet.Pdb.Dss { + static class SymbolReaderWriterFactory { + [DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)] + [DllImport("Microsoft.DiaSymReader.Native.x86.dll", EntryPoint = "CreateSymReader")] + static extern void CreateSymReader_x86(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object symReader); + + [DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)] + [DllImport("Microsoft.DiaSymReader.Native.amd64.dll", EntryPoint = "CreateSymReader")] + static extern void CreateSymReader_x64(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object symReader); + + [DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)] + [DllImport("Microsoft.DiaSymReader.Native.arm.dll", EntryPoint = "CreateSymReader")] + static extern void CreateSymReader_arm(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object symReader); + + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] + [DllImport("Microsoft.DiaSymReader.Native.x86.dll", EntryPoint = "CreateSymWriter")] + static extern void CreateSymWriter_x86(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object symWriter); + + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] + [DllImport("Microsoft.DiaSymReader.Native.amd64.dll", EntryPoint = "CreateSymWriter")] + static extern void CreateSymWriter_x64(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object symWriter); + + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] + [DllImport("Microsoft.DiaSymReader.Native.arm.dll", EntryPoint = "CreateSymWriter")] + static extern void CreateSymWriter_arm(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object symWriter); + + static readonly Guid CLSID_CorSymReader_SxS = new Guid("0A3976C5-4529-4ef8-B0B0-42EED37082CD"); + static Type CorSymReader_Type; + + static readonly Guid CLSID_CorSymWriter_SxS = new Guid(0x0AE2DEB0, 0xF901, 0x478B, 0xBB, 0x9F, 0x88, 0x1E, 0xE8, 0x06, 0x67, 0x88); + static Type CorSymWriterType; + + static volatile bool canTry_Microsoft_DiaSymReader_Native = true; + + public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metadata, DataReaderFactory pdbStream) { + ISymUnmanagedReader unmanagedReader = null; + SymbolReaderImpl symReader = null; + ReaderMetaDataImport mdImporter = null; + DataReaderIStream comPdbStream = null; + bool error = true; + try { + if (pdbStream == null) + return null; + var debugDir = pdbContext.CodeViewDebugDirectory; + if (debugDir == null) + return null; + if (debugDir.MajorVersion != 0 || debugDir.MinorVersion != 0) + return null; + if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) + return null; + + unmanagedReader = CreateSymUnmanagedReader(pdbContext.Options); + if (unmanagedReader == null) + return null; + + mdImporter = new ReaderMetaDataImport(metadata); + comPdbStream = new DataReaderIStream(pdbStream); + int hr = unmanagedReader.Initialize(mdImporter, null, null, comPdbStream); + if (hr < 0) + return null; + + symReader = new SymbolReaderImpl(unmanagedReader, new object[] { pdbStream, mdImporter, comPdbStream }); + if (!symReader.CheckVersion(pdbGuid, debugDir.TimeDateStamp, age)) + return null; + + error = false; + return symReader; + } + catch (IOException) { + } + catch (InvalidCastException) { + } + catch (COMException) { + } + finally { + if (error) { + pdbStream?.Dispose(); + symReader?.Dispose(); + mdImporter?.Dispose(); + comPdbStream?.Dispose(); + (unmanagedReader as ISymUnmanagedDispose)?.Destroy(); + } + } + return null; + } + + static ISymUnmanagedReader CreateSymUnmanagedReader(PdbReaderOptions options) { + bool useDiaSymreader = (options & PdbReaderOptions.NoDiaSymReader) == 0; + bool useOldDiaSymreader = (options & PdbReaderOptions.NoOldDiaSymReader) == 0; + + if (useDiaSymreader && canTry_Microsoft_DiaSymReader_Native) { + try { + var guid = CLSID_CorSymReader_SxS; + object symReaderObj; + var machine = ProcessorArchUtils.GetProcessCpuArchitecture(); + switch (machine) { + case Machine.AMD64: + CreateSymReader_x64(ref guid, out symReaderObj); + break; + + case Machine.I386: + CreateSymReader_x86(ref guid, out symReaderObj); + break; + + case Machine.ARMNT: + CreateSymReader_arm(ref guid, out symReaderObj); + break; + + default: + Debug.Fail($"Microsoft.DiaSymReader.Native doesn't support this CPU arch: {machine}"); + symReaderObj = null; + break; + } + if (symReaderObj is ISymUnmanagedReader symReader) + return symReader; + } + catch (DllNotFoundException) { + Debug.WriteLine("Microsoft.DiaSymReader.Native not found, using diasymreader.dll instead"); + } + catch { + } + canTry_Microsoft_DiaSymReader_Native = false; + } + + if (useOldDiaSymreader) + return (ISymUnmanagedReader)Activator.CreateInstance(CorSymReader_Type ?? (CorSymReader_Type = Type.GetTypeFromCLSID(CLSID_CorSymReader_SxS))); + + return null; + } + + static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) { + bool useDiaSymreader = (options & PdbWriterOptions.NoDiaSymReader) == 0; + bool useOldDiaSymreader = (options & PdbWriterOptions.NoOldDiaSymReader) == 0; + + if (useDiaSymreader && canTry_Microsoft_DiaSymReader_Native) { + try { + var guid = CLSID_CorSymWriter_SxS; + object symWriterObj; + var machine = ProcessorArchUtils.GetProcessCpuArchitecture(); + switch (machine) { + case Machine.AMD64: + CreateSymWriter_x64(ref guid, out symWriterObj); + break; + + case Machine.I386: + CreateSymWriter_x86(ref guid, out symWriterObj); + break; + + case Machine.ARMNT: + CreateSymWriter_arm(ref guid, out symWriterObj); + break; + + default: + Debug.Fail($"Microsoft.DiaSymReader.Native doesn't support this CPU arch: {machine}"); + symWriterObj = null; + break; + } + if (symWriterObj is ISymUnmanagedWriter2 symWriter) + return symWriter; + } + catch (DllNotFoundException) { + Debug.WriteLine("Microsoft.DiaSymReader.Native not found, using diasymreader.dll instead"); + } + catch { + } + canTry_Microsoft_DiaSymReader_Native = false; + } + + if (useOldDiaSymreader) + return (ISymUnmanagedWriter2)Activator.CreateInstance(CorSymWriterType ?? (CorSymWriterType = Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS))); + + return null; + } + + public static ISymbolWriter2 Create(PdbWriterOptions options, string pdbFileName) { + if (File.Exists(pdbFileName)) + File.Delete(pdbFileName); + return new SymbolWriter(CreateSymUnmanagedWriter2(options), pdbFileName, File.Create(pdbFileName), options, ownsStream: true); + } + + public static ISymbolWriter2 Create(PdbWriterOptions options, Stream pdbStream, string pdbFileName) => + new SymbolWriter(CreateSymUnmanagedWriter2(options), pdbFileName, pdbStream, options, ownsStream: false); + } +} diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index ab278368a..e04d4c08f 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Diagnostics; using System.Diagnostics.SymbolStore; using System.IO; using System.Reflection; @@ -14,32 +15,22 @@ sealed class SymbolWriter : ISymbolWriter2 { readonly ISymUnmanagedAsyncMethodPropertiesWriter asyncMethodWriter; readonly string pdbFileName; readonly Stream pdbStream; + readonly bool ownsStream; + readonly bool isDeterministic; bool closeCalled; + public bool IsDeterministic => isDeterministic; public bool SupportsAsyncMethods => asyncMethodWriter != null; - /// - /// Constructor - /// - /// Writer - /// PDB file name - public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName) { - this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); - asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; - this.pdbFileName = pdbFileName ?? throw new ArgumentNullException(nameof(pdbFileName)); - } - - /// - /// Constructor - /// - /// Writer - /// PDB file name - /// PDB output stream - public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream) { + public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream, PdbWriterOptions options, bool ownsStream) { this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; this.pdbStream = pdbStream ?? throw new ArgumentNullException(nameof(pdbStream)); this.pdbFileName = pdbFileName; + this.ownsStream = ownsStream; + // If it's deterministic, we should call UpdateSignatureByHashingContent() or UpdateSignature(), + // but that requires v7 or v8. InitializeDeterministic() is v6. + isDeterministic = (options & PdbWriterOptions.Deterministic) != 0 && writer is ISymUnmanagedWriter7; } public void Abort() => writer.Abort(); @@ -146,25 +137,60 @@ public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, public void SetUserEntryPoint(SymbolToken entryMethod) => writer.SetUserEntryPoint((uint)entryMethod.GetToken()); public void UsingNamespace(string fullName) => writer.UsingNamespace(fullName); - public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY pIDD) { + public unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData) { + pIDD = default; + codeViewData = null; + + if (isDeterministic) { + ((ISymUnmanagedWriter3)writer).Commit(); + pdbStream.Position = 0; + var checksumBytes = Hasher.Hash(pdbChecksumAlgorithm, pdbStream, pdbStream.Length); + if (writer is ISymUnmanagedWriter8 writer8) { + RoslynContentIdProvider.GetContentId(checksumBytes, out guid, out stamp); + writer8.UpdateSignature(guid, stamp, pdbAge); + return true; + } + else { + var writer7 = (ISymUnmanagedWriter7)writer; + fixed (byte* p = checksumBytes) + writer7.UpdateSignatureByHashingContent(new IntPtr(p), (uint)checksumBytes.Length); + } + } + writer.GetDebugInfo(out pIDD, 0, out uint size, null); - var buffer = new byte[size]; - writer.GetDebugInfo(out pIDD, size, out size, buffer); - return buffer; + codeViewData = new byte[size]; + writer.GetDebugInfo(out pIDD, size, out size, codeViewData); + + if (writer is IPdbWriter comPdbWriter) { + var guidBytes = new byte[16]; + Array.Copy(codeViewData, 4, guidBytes, 0, 16); + guid = new Guid(guidBytes); + comPdbWriter.GetSignatureAge(out stamp, out uint age); + Debug.Assert(age == pdbAge); + pdbAge = age; + return true; + } + + Debug.Fail($"COM PDB writer doesn't impl {nameof(IPdbWriter)}"); + guid = default; + stamp = 0; + return false; } public void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset) => writer.DefineLocalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3, startOffset, endOffset); public void Initialize(Metadata metadata) { - if (pdbStream != null) - writer.Initialize(new MDEmitter(metadata), pdbFileName, new StreamIStream(pdbStream), true); - else if (!string.IsNullOrEmpty(pdbFileName)) - writer.Initialize(new MDEmitter(metadata), pdbFileName, null, true); + if (isDeterministic) + ((ISymUnmanagedWriter6)writer).InitializeDeterministic(new MDEmitter(metadata), new StreamIStream(pdbStream)); else - throw new InvalidOperationException(); + writer.Initialize(new MDEmitter(metadata), pdbFileName, new StreamIStream(pdbStream), true); } - public void Dispose() => Marshal.FinalReleaseComObject(writer); + public void Dispose() { + Marshal.FinalReleaseComObject(writer); + if (ownsStream) + pdbStream.Dispose(); + } } } diff --git a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs b/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs deleted file mode 100644 index 2d76baa5e..000000000 --- a/src/DotNet/Pdb/Dss/SymbolWriterCreator.cs +++ /dev/null @@ -1,41 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using dnlib.DotNet.Pdb.WindowsPdb; - -namespace dnlib.DotNet.Pdb.Dss { - /// - /// Creates a - /// - static class SymbolWriterCreator { - static readonly Guid CLSID_CorSymWriter_SxS = new Guid(0x0AE2DEB0, 0xF901, 0x478B, 0xBB, 0x9F, 0x88, 0x1E, 0xE8, 0x06, 0x67, 0x88); - - /// - /// Creates a instance - /// - /// A new instance - public static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2() => - (ISymUnmanagedWriter2)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS)); - - /// - /// Creates a new instance - /// - /// PDB file name - /// A new instance - public static ISymbolWriter2 Create(string pdbFileName) { - if (File.Exists(pdbFileName)) - File.Delete(pdbFileName); - return new SymbolWriter(CreateSymUnmanagedWriter2(), pdbFileName); - } - - /// - /// Creates a new instance - /// - /// PDB output stream - /// PDB file name - /// A new instance - public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) => - new SymbolWriter(CreateSymUnmanagedWriter2(), pdbFileName, pdbStream); - } -} diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index afd324551..d81f3c84a 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -42,8 +42,12 @@ sealed class PdbReader : SymbolReader { public Guid Guid { get; private set; } readonly Guid expectedGuid; + readonly uint expectedAge; - public PdbReader(Guid expectedGuid) => this.expectedGuid = expectedGuid; + public PdbReader(Guid expectedGuid, uint expectedAge) { + this.expectedGuid = expectedGuid; + this.expectedAge = expectedAge; + } public override void Initialize(ModuleDef module) => this.module = module; @@ -105,7 +109,7 @@ void ReadInternal(ref DataReader reader) { ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); ReadNames(); - if (Guid != expectedGuid) + if (Guid != expectedGuid || Age != expectedAge) return; ReadStringTable(); var tokenMapStream = ReadModules(); diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs index bc783c72d..d7c1647e2 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs @@ -27,9 +27,9 @@ public static SymbolReader Create(PdbReaderContext pdbContext, DataReaderFactory if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; - var pdbReader = new PdbReader(pdbGuid); + var pdbReader = new PdbReader(pdbGuid, age); pdbReader.Read(pdbStream.CreateReader()); - if (pdbReader.Guid == pdbGuid) + if (pdbReader.Guid == pdbGuid && pdbReader.Age == age) return pdbReader; return null; } diff --git a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs b/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs deleted file mode 100644 index f10926191..000000000 --- a/src/DotNet/Pdb/ManagedSymbolReaderCreator.cs +++ /dev/null @@ -1,57 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.IO; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb { - static class ManagedSymbolReaderCreator { - public static SymbolReader CreateFromAssemblyFile(PdbReaderContext pdbContext, Metadata metadata, string assemblyFileName) => - Create(pdbContext, metadata, Path.ChangeExtension(assemblyFileName, "pdb")); - - public static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata, string pdbFileName) => - Create(pdbContext, metadata, DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); - - public static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata, byte[] pdbData) => - Create(pdbContext, metadata, ByteArrayDataReaderFactory.Create(pdbData, filename: null)); - - public static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream) { - try { - // Embedded pdbs have priority - var res = Create(pdbContext, metadata); - if (res != null) { - pdbStream?.Dispose(); - return res; - } - - return CreateCore(pdbContext, pdbStream); - } - catch { - pdbStream?.Dispose(); - throw; - } - } - - static SymbolReader CreateCore(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { - if (pdbStream == null) - return null; - try { - var reader = pdbStream.CreateReader(); - if (reader.Length >= 4) { - uint sig = reader.ReadUInt32(); - if (sig == 0x424A5342) - return Portable.SymbolReaderCreator.TryCreate(pdbContext, pdbStream, isEmbeddedPortablePdb: false); - return Managed.SymbolReaderCreator.Create(pdbContext, pdbStream); - } - } - catch (IOException) { - } - pdbStream?.Dispose(); - return null; - } - - internal static SymbolReader Create(PdbReaderContext pdbContext, Metadata metadata) => - Portable.SymbolReaderCreator.TryCreate(pdbContext, metadata); - } -} diff --git a/src/DotNet/Pdb/PdbImplType.cs b/src/DotNet/Pdb/PdbImplType.cs deleted file mode 100644 index 147bd24f3..000000000 --- a/src/DotNet/Pdb/PdbImplType.cs +++ /dev/null @@ -1,25 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb { - /// - /// PDB implementation type - /// - public enum PdbImplType { - /// - /// Use Microsoft's COM DLL (diasymreader.dll). It's not recommended to use this reader since it can only be accessed on the COM thread. - /// - /// This reader can only read the old PDB files (aka Windows PDB files). It does not support portable PDB files. - /// - MicrosoftCOM, - - /// - /// Use the managed PDB reader. It supports Windows PDB files and portable PDB files and is the default PDB reader. - /// - Managed, - - /// - /// Use the default PDB reader - /// - Default = Managed, - } -} diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs index 3a67c9f0d..c5bef1f7b 100644 --- a/src/DotNet/Pdb/PdbReaderContext.cs +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -11,9 +11,11 @@ readonly struct PdbReaderContext { public bool HasDebugInfo => codeViewDebugDir != null; public ImageDebugDirectory CodeViewDebugDirectory => codeViewDebugDir; + public PdbReaderOptions Options { get; } - public PdbReaderContext(IPEImage peImage) { + public PdbReaderContext(IPEImage peImage, PdbReaderOptions options) { this.peImage = peImage; + Options = options; codeViewDebugDir = TryGetDebugDirectoryEntry(peImage, ImageDebugType.CodeView); } diff --git a/src/DotNet/Pdb/PdbReaderOptions.cs b/src/DotNet/Pdb/PdbReaderOptions.cs new file mode 100644 index 000000000..2c36df1f1 --- /dev/null +++ b/src/DotNet/Pdb/PdbReaderOptions.cs @@ -0,0 +1,44 @@ +// dnlib: See LICENSE.txt for more info + +using System; + +namespace dnlib.DotNet.Pdb { + /// + /// PDB reader options + /// + [Flags] + public enum PdbReaderOptions { + /// + /// No bit is set + /// + None = 0, + + /// + /// Use the COM Windows PDB reader instead of the managed Windows PDB reader. + /// + /// This is NOT recommended since the COM reader can only be called on the same + /// thread it was created on. It also requires a Windows OS. + /// + /// If this is not set, the managed PDB reader will be used. + /// + /// This option is only used if it's a Windows PDB file, not if it's a Portable PDB file. + /// + MicrosoftComReader = 0x00000001, + + /// + /// Don't use Microsoft.DiaSymReader.Native. This is a NuGet package with an updated Windows PDB reader/writer implementation, + /// and if it's available at runtime, dnlib will try to use it. If this option is set, dnlib won't use it. + /// You have to add a reference to the NuGet package if you want to use it, dnlib has no reference to the NuGet package. + /// + /// Only used if is set and if it's a Windows PDB file + /// + NoDiaSymReader = 0x00000002, + + /// + /// Don't use diasymreader.dll's PDB reader that is shipped with .NET Framework. + /// + /// Only used if is set and if it's a Windows PDB file + /// + NoOldDiaSymReader = 0x00000004, + } +} diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 19842612b..0c65deda5 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -429,14 +429,10 @@ static Instruction GetInstruction(IList instrs, int offset, ref int internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { Debug.Assert(token.Table != Table.Method, "Methods get initialized when reading the method bodies"); - if (reader != null) - reader.GetCustomDebugInfos(token.ToInt32(), gpContext, result); + reader?.GetCustomDebugInfos(token.ToInt32(), gpContext, result); } - internal void Dispose() { - if (reader != null) - reader.Dispose(); - } + internal void Dispose() => reader?.Dispose(); } enum Compiler { diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs index 3c16a9e6a..1878bb757 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs @@ -50,7 +50,7 @@ public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFact return null; } - public static SymbolReader TryCreate(PdbReaderContext pdbContext, Metadata metadata) { + public static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext pdbContext, Metadata metadata) { if (metadata == null) return null; try { diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderCreator.cs index 96f4789e7..71e7c575a 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderCreator.cs @@ -1,129 +1,113 @@ // dnlib: See LICENSE.txt for more info -using System; +using System.IO; +using System.Text; using dnlib.DotNet.MD; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; namespace dnlib.DotNet.Pdb { - /// - /// Creates a instance - /// static class SymbolReaderCreator { - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata - /// Path to assembly - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static SymbolReader CreateFromAssemblyFile(PdbImplType pdbImpl, Metadata metadata, string assemblyFileName) { - var pdbContext = new PdbReaderContext(metadata.PEImage); + public static SymbolReader CreateFromAssemblyFile(PdbReaderOptions options, Metadata metadata, string assemblyFileName) => + Create(options, metadata, Path.ChangeExtension(assemblyFileName, "pdb")); + + public static SymbolReader Create(PdbReaderOptions options, Metadata metadata, string pdbFileName) { + var pdbContext = new PdbReaderContext(metadata.PEImage, options); if (!pdbContext.HasDebugInfo) return null; - - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.CreateFromAssemblyFile(assemblyFileName); - - case PdbImplType.Managed: - return ManagedSymbolReaderCreator.CreateFromAssemblyFile(pdbContext, metadata, assemblyFileName); - - default: throw new InvalidOperationException(); - } + return CreateCore(pdbContext, metadata, DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); } - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata - /// Path to PDB file - /// A new instance or null if there's no PDB - /// file on disk or if it's not possible to create a . - public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, string pdbFileName) { - var pdbContext = new PdbReaderContext(metadata.PEImage); + public static SymbolReader Create(PdbReaderOptions options, Metadata metadata, byte[] pdbData) { + var pdbContext = new PdbReaderContext(metadata.PEImage, options); if (!pdbContext.HasDebugInfo) return null; + return CreateCore(pdbContext, metadata, ByteArrayDataReaderFactory.Create(pdbData, filename: null)); + } - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(metadata, pdbFileName); - - case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(pdbContext, metadata, pdbFileName); + public static SymbolReader Create(PdbReaderOptions options, Metadata metadata, DataReaderFactory pdbStream) { + var pdbContext = new PdbReaderContext(metadata.PEImage, options); + return CreateCore(pdbContext, metadata, pdbStream); + } - default: throw new InvalidOperationException(); + static SymbolReader CreateCore(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream) { + SymbolReader symReader = null; + bool error = true; + try { + if (!pdbContext.HasDebugInfo) + return null; + + if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && pdbStream != null && IsWindowsPdb(pdbStream.CreateReader())) + symReader = Dss.SymbolReaderWriterFactory.Create(pdbContext, metadata, pdbStream); + else + symReader = CreateManaged(pdbContext, metadata, pdbStream); + + if (symReader != null) { + error = false; + return symReader; + } } + catch (IOException) { + } + finally { + if (error) { + pdbStream?.Dispose(); + symReader?.Dispose(); + } + } + return null; } - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata - /// PDB file data - /// A new instance or null if it's not possible - /// to create a . - public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, byte[] pdbData) { - var pdbContext = new PdbReaderContext(metadata.PEImage); - if (!pdbContext.HasDebugInfo) - return null; - - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(metadata, pdbData); - - case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(pdbContext, metadata, pdbData); - - default: throw new InvalidOperationException(); - } + static bool IsWindowsPdb(DataReader reader) { + const string SIG = "Microsoft C/C++ MSF 7.00\r\n\u001ADS\0"; + if (!reader.CanRead(SIG.Length)) + return false; + return reader.ReadString(SIG.Length, Encoding.ASCII) == SIG; } - /// - /// Creates a new instance - /// - /// PDB implementation to use - /// .NET metadata - /// PDB file stream which is now owned by us - /// A new instance or null if it's not possible - /// to create a . - public static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata, DataReaderFactory pdbStream) { - var pdbContext = new PdbReaderContext(metadata.PEImage); - if (!pdbContext.HasDebugInfo) { - pdbStream?.Dispose(); + public static SymbolReader TryCreateEmbeddedPdbReader(PdbReaderOptions options, Metadata metadata) { + var pdbContext = new PdbReaderContext(metadata.PEImage, options); + if (!pdbContext.HasDebugInfo) return null; - } - - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: - return Dss.SymbolReaderCreator.Create(metadata, pdbStream); + return TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); + } - case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(pdbContext, metadata, pdbStream); + static SymbolReader CreateManaged(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream) { + try { + // Embedded PDBs have priority + var embeddedReader = TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); + if (embeddedReader != null) { + pdbStream?.Dispose(); + return embeddedReader; + } - default: + return CreateManagedCore(pdbContext, pdbStream); + } + catch { pdbStream?.Dispose(); - throw new InvalidOperationException(); + throw; } } - internal static SymbolReader Create(PdbImplType pdbImpl, Metadata metadata) { - var pdbContext = new PdbReaderContext(metadata.PEImage); - if (!pdbContext.HasDebugInfo) - return null; - - switch (pdbImpl) { - case PdbImplType.MicrosoftCOM: + static SymbolReader CreateManagedCore(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { + if (pdbStream == null) return null; - - case PdbImplType.Managed: - return ManagedSymbolReaderCreator.Create(pdbContext, metadata); - - default: throw new InvalidOperationException(); + try { + var reader = pdbStream.CreateReader(); + if (reader.Length >= 4) { + uint sig = reader.ReadUInt32(); + if (sig == 0x424A5342) + return Portable.SymbolReaderCreator.TryCreate(pdbContext, pdbStream, isEmbeddedPortablePdb: false); + return Managed.SymbolReaderCreator.Create(pdbContext, pdbStream); + } + } + catch (IOException) { } + pdbStream?.Dispose(); + return null; } + + static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext pdbContext, Metadata metadata) => + Portable.SymbolReaderCreator.TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); } } diff --git a/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs index 1caee32d4..b5f478c03 100644 --- a/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs +++ b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs @@ -5,84 +5,17 @@ using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.WindowsPdb { - /// - /// Implements and adds a few extra methods we need that are part of - /// ISymUnmanagedWriter and ISymUnmanagedWriter2 but not present in - /// . - /// - public interface ISymbolWriter2 : ISymbolWriter, IDisposable { - /// - /// Same as except that this method has an - /// extra that specifies the size of all the arrays. - /// - /// Document - /// Size of the arrays - /// Offsets - /// Start lines - /// Start columns - /// End lines - /// End columns - void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns); - - /// - /// Gets debug info. See ISymUnmanagedWriter.GetDebugInfo() - /// - /// Updated by writer - /// Debug data for the symbol store - byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY pIDD); + interface ISymbolWriter2 : ISymbolWriter, IDisposable { + bool IsDeterministic { get; } + bool SupportsAsyncMethods { get; } - /// - /// Define a local. See ISymUnmanagedWriter2.DefineLocalVariable2() - /// - /// Name - /// Attributes - /// Signature token - /// Address kind - /// Address #1 - /// Address #2 - /// Address #3 - /// Start offset - /// End offset + void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns); + bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData); void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset); - - /// - /// Initializes this instance. This must be called before any other method. - /// - /// Metadata void Initialize(Metadata metadata); - - /// - /// Defines a constant - /// - /// Name of constant - /// Constant value - /// StandAloneSig token of constant field type void DefineConstant2(string name, object value, uint sigToken); - - /// - /// true if it supports , - /// and - /// - bool SupportsAsyncMethods { get; } - - /// - /// Defines an async kickoff method - /// - /// Kickoff method token void DefineKickoffMethod(uint kickoffMethod); - - /// - /// Defines an async catch handler - /// - /// Catch handler IL offset void DefineCatchHandlerILOffset(uint catchHandlerOffset); - - /// - /// Defines async step info - /// - /// Yield IL offsets - /// Breakpoint method IL offset - /// Breakpoint method void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod); } } diff --git a/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs b/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs deleted file mode 100644 index ccaed2270..000000000 --- a/src/DotNet/Pdb/WindowsPdb/SymbolWriterCreator.cs +++ /dev/null @@ -1,25 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.IO; - -namespace dnlib.DotNet.Pdb.WindowsPdb { - /// - /// Creates a - /// - static class SymbolWriterCreator { - /// - /// Creates a new instance - /// - /// PDB file name - /// A new instance - public static ISymbolWriter2 Create(string pdbFileName) => Dss.SymbolWriterCreator.Create(pdbFileName); - - /// - /// Creates a new instance - /// - /// PDB output stream - /// PDB file name - /// A new instance - public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) => Dss.SymbolWriterCreator.Create(pdbStream, pdbFileName); - } -} diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 6b364bbdf..2fa280755 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -8,10 +8,6 @@ using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.WindowsPdb { - /// - /// PDB writer - /// - /// This class is not thread safe because it's a writer class sealed class WindowsPdbWriter : IDisposable { ISymbolWriter2 writer; readonly PdbState pdbState; @@ -23,17 +19,8 @@ sealed class WindowsPdbWriter : IDisposable { readonly PdbCustomDebugInfoWriterContext customDebugInfoWriterContext; readonly int localsEndScopeIncValue; - /// - /// Gets/sets the logger - /// public ILogger Logger { get; set; } - /// - /// Constructor - /// - /// Symbol writer - /// PDB state - /// Meta data public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, Metadata metadata) : this(pdbState, metadata) { if (pdbState == null) @@ -53,11 +40,6 @@ public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, Metadata metad localsEndScopeIncValue = PdbUtils.IsEndInclusive(PdbFileKind.WindowsPDB, pdbState.Compiler) ? 1 : 0; } - /// - /// Adds if it doesn't exist - /// - /// PDB document - /// A instance ISymbolDocumentWriter Add(PdbDocument pdbDoc) { if (pdbDocs.TryGetValue(pdbDoc, out var docWriter)) return docWriter; @@ -67,9 +49,6 @@ ISymbolDocumentWriter Add(PdbDocument pdbDoc) { return docWriter; } - /// - /// Writes the PDB file - /// public void Write() { writer.SetUserEntryPoint(new SymbolToken(GetUserEntryPointToken())); @@ -427,21 +406,11 @@ int GetUserEntryPointToken() { return new MDToken(MD.Table.Method, rid).ToInt32(); } - /// - /// Gets the and debug data that should be written to - /// the PE file. - /// - /// Updated with new values - /// Debug data - public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY idd) => writer.GetDebugInfo(out idd); - - /// - /// Closes the PDB writer - /// - public void Close() => writer.Close(); + public bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY idd, out byte[] codeViewData) => + writer.GetDebugInfo(pdbChecksumAlgorithm, ref pdbAge, out guid, out stamp, out idd, out codeViewData); + public void Close() => writer.Close(); ILogger GetLogger() => Logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; - void Error(string message, params object[] args) => GetLogger().Log(this, LoggerEvent.Error, message, args); /// diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index aaf0da33e..7559d59e8 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -35,7 +35,7 @@ public void Populate(BlobStream blobStream) { if (blobStream == null || blobStream.StreamLength == 0) return; - var reader = blobStream.GetReader(); + var reader = blobStream.CreateReader(); originalData = reader.ToArray(); nextOffset = (uint)originalData.Length; Populate(ref reader); diff --git a/src/DotNet/Writer/DataReaderHeap.cs b/src/DotNet/Writer/DataReaderHeap.cs index dbf682abe..c2906eaf3 100644 --- a/src/DotNet/Writer/DataReaderHeap.cs +++ b/src/DotNet/Writer/DataReaderHeap.cs @@ -24,7 +24,7 @@ public sealed class DataReaderHeap : HeapBase { /// The stream whose data will be copied to the new metadata file public DataReaderHeap(DotNetStream stream) { OptionalOriginalStream = stream ?? throw new ArgumentNullException(nameof(stream)); - heapReader = stream.GetReader(); + heapReader = stream.CreateReader(); Name = stream.Name; } diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 7ca7c782c..87459d540 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -99,6 +99,47 @@ public ContentId(Guid guid, uint timestamp) { /// Event args public delegate void EventHandler2(object sender, TEventArgs e); + /// + /// PDB writer options + /// + [Flags] + public enum PdbWriterOptions { + /// + /// No bit is set + /// + None = 0, + + /// + /// Don't use Microsoft.DiaSymReader.Native. This is a NuGet package with an updated Windows PDB reader/writer implementation, + /// and if it's available at runtime, dnlib will try to use it. If this option is set, dnlib won't use it. + /// You have to add a reference to the NuGet package if you want to use it, dnlib has no reference to the NuGet package. + /// + /// Only used if it's a Windows PDB file + /// + NoDiaSymReader = 0x00000001, + + /// + /// Don't use diasymreader.dll's PDB writer that is shipped with .NET Framework. + /// + /// Only used if it's a Windows PDB file + /// + NoOldDiaSymReader = 0x00000002, + + /// + /// Create a deterministic PDB file and add a debug directory entry to the PE file. + /// + /// It's ignored if the PDB writer doesn't support it. + /// + Deterministic = 0x00000004, + + /// + /// Hash the PDB file and add a PDB checksum debug directory entry to the PE file. + /// + /// It's ignored if the PDB writer doesn't support it. + /// + PdbChecksum = 0x00000008, + } + /// /// Common module writer options base class /// @@ -267,6 +308,11 @@ public bool Is64Bit { /// public bool WritePdb { get; set; } + /// + /// PDB writer options. This property is ignored if is false. + /// + public PdbWriterOptions PdbOptions { get; set; } + /// /// PDB file name. If it's null a PDB file with the same name as the output assembly /// will be created but with a PDB extension. must be true or @@ -284,21 +330,10 @@ public bool Is64Bit { /// /// Gets the PDB content id. The argument is the PDB stream with the PDB ID zeroed out, /// and the 2nd argument is the default timestamp. - /// This property is ignored if is true. + /// This property is ignored if a deterministic PDB file is created or if the PDB checksum is calculated. /// public Func GetPdbContentId { get; set; } - /// - /// Create a reproducible PDB, if the PDB writer supports it. - /// If true, is ignored and a debug directory entry is added to the EXE/DLL file. - /// - public bool ReproduciblePdb { get; set; } - - /// - /// true to add a PDB checksum debug directory entry to the PE file - /// - public bool AddPdbChecksumDebugDirectoryEntry { get; set; } - const ChecksumAlgorithm DefaultPdbChecksumAlgorithm = ChecksumAlgorithm.SHA256; /// @@ -379,8 +414,10 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PEHeadersOptions.Win32VersionValue = ntHeaders.OptionalHeader.Win32VersionValue; AddCheckSum = ntHeaders.OptionalHeader.CheckSum != 0; AddMvidSection = HasMvidSection(modDefMD.Metadata.PEImage.ImageSectionHeaders); - ReproduciblePdb = HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.Reproducible); - AddPdbChecksumDebugDirectoryEntry = HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.PdbChecksum); + if (HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.Reproducible)) + PdbOptions |= PdbWriterOptions.Deterministic; + if (HasDebugDirectoryEntry(modDefMD.Metadata.PEImage.ImageDebugDirectories, ImageDebugType.PdbChecksum)) + PdbOptions |= PdbWriterOptions.PdbChecksum; if (TryGetPdbChecksumAlgorithm(modDefMD.Metadata.PEImage, modDefMD.Metadata.PEImage.ImageDebugDirectories, out var pdbChecksumAlgorithm)) PdbChecksumAlgorithm = pdbChecksumAlgorithm; } @@ -851,12 +888,11 @@ void AddPdbChecksumDebugDirectoryEntry(byte[] checksumBytes, ChecksumAlgorithm c debugDirectory.Add(blob, ImageDebugType.PdbChecksum, majorVersion: 1, minorVersion: 0, timeDateStamp: 0); } + const uint PdbAge = 1; void WriteWindowsPdb(PdbState pdbState) { - bool reproduciblePdb = TheOptions.ReproduciblePdb; - reproduciblePdb = false;//TODO: If this is true, create a reproducible PDB writer - bool addPdbChecksumDebugDirectoryEntry = TheOptions.AddPdbChecksumDebugDirectoryEntry; + bool addPdbChecksumDebugDirectoryEntry = (TheOptions.PdbOptions & PdbWriterOptions.PdbChecksum) != 0; addPdbChecksumDebugDirectoryEntry = false;//TODO: If this is true, get the checksum from the PDB writer - var symWriter = GetWindowsPdbSymbolWriter(); + var symWriter = GetWindowsPdbSymbolWriter(TheOptions.PdbOptions, out var pdbFilename); if (symWriter == null) { Error("Could not create a PDB symbol writer. A Windows OS might be required."); return; @@ -866,13 +902,28 @@ void WriteWindowsPdb(PdbState pdbState) { pdbWriter.Logger = TheOptions.Logger; pdbWriter.Write(); - var data = pdbWriter.GetDebugInfo(out var idd); - var entry = debugDirectory.Add(data); - entry.DebugDirectory = idd; - entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); + var pdbAge = PdbAge; + bool hasContentId = pdbWriter.GetDebugInfo(TheOptions.PdbChecksumAlgorithm, ref pdbAge, out var pdbGuid, out uint stamp, out var idd, out var codeViewData); + if (hasContentId) { + debugDirectory.Add(GetCodeViewData(pdbGuid, pdbAge, pdbFilename), + type: ImageDebugType.CodeView, + majorVersion: 0, + minorVersion: 0, + timeDateStamp: stamp); + } + else { + Debug.Fail("Failed to get the PDB content ID"); + if (codeViewData == null) + throw new InvalidOperationException(); + var entry = debugDirectory.Add(codeViewData); + entry.DebugDirectory = idd; + entry.DebugDirectory.TimeDateStamp = GetTimeDateStamp(); + } + + //TODO: Only do this if symWriter supports PDB checksums if (addPdbChecksumDebugDirectoryEntry) {}//TODO: AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm);, and verify that the order of the debug dir entries is the same as Roslyn created binaries - if (reproduciblePdb) + if (symWriter.IsDeterministic) AddReproduciblePdbDebugDirectoryEntry(); } } @@ -889,23 +940,23 @@ protected uint GetTimeDateStamp() { return (uint)TheOptions.PEHeadersOptions.TimeDateStamp; } - ISymbolWriter2 GetWindowsPdbSymbolWriter() { + ISymbolWriter2 GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbFilename) { if (TheOptions.PdbStream != null) { - return SymbolWriterCreator.Create(TheOptions.PdbStream, - TheOptions.PdbFileName ?? + return Pdb.Dss.SymbolReaderWriterFactory.Create(options, TheOptions.PdbStream, + pdbFilename = TheOptions.PdbFileName ?? GetStreamName(TheOptions.PdbStream) ?? GetDefaultPdbFileName()); } if (!string.IsNullOrEmpty(TheOptions.PdbFileName)) { - createdPdbFileName = TheOptions.PdbFileName; - return SymbolWriterCreator.Create(createdPdbFileName); + createdPdbFileName = pdbFilename = TheOptions.PdbFileName; + return Pdb.Dss.SymbolReaderWriterFactory.Create(options, createdPdbFileName); } - createdPdbFileName = GetDefaultPdbFileName(); + createdPdbFileName = pdbFilename = GetDefaultPdbFileName(); if (createdPdbFileName == null) return null; - return SymbolWriterCreator.Create(createdPdbFileName); + return Pdb.Dss.SymbolReaderWriterFactory.Create(options, createdPdbFileName); } static string GetStreamName(Stream stream) => (stream as FileStream)?.Name; @@ -960,7 +1011,9 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { var pdbIdWriter = new ArrayWriter(pdbId); uint codeViewTimestamp; byte[] checksumBytes; - if (TheOptions.ReproduciblePdb || TheOptions.AddPdbChecksumDebugDirectoryEntry || TheOptions.GetPdbContentId == null) { + if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0 || + (TheOptions.PdbOptions & PdbWriterOptions.PdbChecksum) != 0 || + TheOptions.GetPdbContentId == null) { pdbStream.Position = 0; checksumBytes = Hasher.Hash(TheOptions.PdbChecksumAlgorithm, pdbStream, pdbStream.Length); if (checksumBytes.Length < 20) @@ -985,8 +1038,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { // - Reproducible // - EmbeddedPortablePdb - const uint age = 1; - debugDirectory.Add(GetCodeViewData(pdbGuid, age, pdbFilename), + debugDirectory.Add(GetCodeViewData(pdbGuid, PdbAge, pdbFilename), type: ImageDebugType.CodeView, majorVersion: PortablePdbConstants.FormatVersion, minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, @@ -995,7 +1047,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { if (checksumBytes != null) AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm); - if (TheOptions.ReproduciblePdb) + if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0) AddReproduciblePdbDebugDirectoryEntry(); if (isEmbeddedPortablePdb) { diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index a1909a11c..95ad5cd2d 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -52,7 +52,7 @@ public void Populate(StringsStream stringsStream) { if (stringsStream == null || stringsStream.StreamLength == 0) return; - var reader = stringsStream.GetReader(); + var reader = stringsStream.CreateReader(); originalData = reader.ToArray(); nextOffset = (uint)originalData.Length; Populate(ref reader); diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index 935e73034..f94a648b4 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -33,7 +33,7 @@ public void Populate(USStream usStream) { if (usStream == null || usStream.StreamLength == 0) return; - var reader = usStream.GetReader(); + var reader = usStream.CreateReader(); originalData = reader.ToArray(); nextOffset = (uint)originalData.Length; Populate(ref reader); diff --git a/src/HandleProcessCorruptedStateExceptionsAttribute.cs b/src/HandleProcessCorruptedStateExceptionsAttribute.cs index e11099865..cb3f54202 100644 --- a/src/HandleProcessCorruptedStateExceptionsAttribute.cs +++ b/src/HandleProcessCorruptedStateExceptionsAttribute.cs @@ -1,7 +1,5 @@ // dnlib: See LICENSE.txt for more info -#pragma warning disable 1591 // XML doc warning - namespace System.Runtime.ExceptionServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] sealed class HandleProcessCorruptedStateExceptionsAttribute : Attribute { diff --git a/src/IO/DataStreamFactory.cs b/src/IO/DataStreamFactory.cs index febe51000..7a914b180 100644 --- a/src/IO/DataStreamFactory.cs +++ b/src/IO/DataStreamFactory.cs @@ -1,17 +1,31 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Diagnostics; +using dnlib.PE; namespace dnlib.IO { /// /// Creates s /// public static unsafe class DataStreamFactory { + //TODO: There are other places that use pointers that also need to be updated static bool supportsUnalignedAccesses = CalculateSupportsUnalignedAccesses(); - //TODO: ARM doesn't support unaligned accesses - //TODO: There are other places that use pointers that also need to be updated - static bool CalculateSupportsUnalignedAccesses() => true; + static bool CalculateSupportsUnalignedAccesses() { + var machine = ProcessorArchUtils.GetProcessCpuArchitecture(); + switch (machine) { + case Machine.I386: + case Machine.AMD64: + return true; + case Machine.ARMNT: + case Machine.ARM64: + return false; + default: + Debug.Fail($"Unknown CPU arch: {machine}"); + return true; + } + } /// /// Creates a that reads from native memory diff --git a/src/IO/MemoryMappedDataReaderFactory.cs b/src/IO/MemoryMappedDataReaderFactory.cs index 89fc6e8e2..28b69b276 100644 --- a/src/IO/MemoryMappedDataReaderFactory.cs +++ b/src/IO/MemoryMappedDataReaderFactory.cs @@ -36,7 +36,6 @@ sealed unsafe class MemoryMappedDataReaderFactory : DataReaderFactory { IntPtr data; OSType osType; long origDataLength; - bool unsafeUseAddress; MemoryMappedDataReaderFactory(string filename) { osType = OSType.Unknown; @@ -270,11 +269,6 @@ void Dispose(bool disposing) { } } - internal IntPtr GetUnsafeUseAddress() { - unsafeUseAddress = true; - return data; - } - /// /// true if memory mapped I/O is enabled /// @@ -287,8 +281,6 @@ internal IntPtr GetUnsafeUseAddress() { internal void UnsafeDisableMemoryMappedIO() { if (dataAry != null) return; - if (unsafeUseAddress) - throw new InvalidOperationException("Can't convert to non-memory mapped I/O because the PDB reader uses the address. Use the managed PDB reader instead."); var newAry = new byte[length]; Marshal.Copy(data, newAry, 0, newAry.Length); FreeMemoryMappedIoData(); diff --git a/src/IO/NativeMemoryDataReaderFactory.cs b/src/IO/NativeMemoryDataReaderFactory.cs index 202cbb10f..2b337a9e4 100644 --- a/src/IO/NativeMemoryDataReaderFactory.cs +++ b/src/IO/NativeMemoryDataReaderFactory.cs @@ -17,18 +17,14 @@ public sealed unsafe class NativeMemoryDataReaderFactory : DataReaderFactory { /// public override uint Length => length; - internal IntPtr GetUnsafeUseAddress() => unsafeUseAddress; - DataStream stream; string filename; uint length; - IntPtr unsafeUseAddress; NativeMemoryDataReaderFactory(byte* data, uint length, string filename) { this.filename = filename; this.length = length; stream = DataStreamFactory.Create(data); - unsafeUseAddress = (IntPtr)data; } internal void SetLength(uint length) => this.length = length; @@ -61,7 +57,6 @@ public override void Dispose() { stream = EmptyDataStream.Instance; length = 0; filename = null; - unsafeUseAddress = IntPtr.Zero; } } } diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs new file mode 100644 index 000000000..55617c130 --- /dev/null +++ b/src/PE/ProcessorArchUtils.cs @@ -0,0 +1,78 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Diagnostics; + +namespace dnlib.PE { + static class ProcessorArchUtils { + static Machine cachedMachine = 0; + + public static Machine GetProcessCpuArchitecture() { + if (cachedMachine == 0) + cachedMachine = GetProcessCpuArchitectureCore(); + return cachedMachine; + } + + static Machine GetProcessCpuArchitectureCore() { + bool isWindows = true;//TODO: + if (isWindows && TryGetProcessCpuArchitecture_Windows(out var machine)) + return machine; + + Debug.WriteLine("Couldn't detect CPU arch, assuming x86 or x64"); + return IntPtr.Size == 4 ? Machine.I386 : Machine.AMD64; + } + + static bool TryGetProcessCpuArchitecture_Windows(out Machine machine) { + //TODO: We shouldn't trust the environment + string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); + if (arch != null) { + // https://msdn.microsoft.com/en-us/library/aa384274.aspx ("WOW64 Implementation Details / Environment Variables") + switch (arch.ToUpperInvariant()) { + case "AMD64": + if (IntPtr.Size == 8) { + machine = Machine.AMD64; + return true; + } + Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); + break; + + case "X86": + if (IntPtr.Size == 4) { + machine = Machine.I386; + return true; + } + Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); + break; + + case "IA64": + if (IntPtr.Size == 8) { + machine = Machine.IA64; + return true; + } + Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); + break; + + //TODO: This string hasn't been tested + case "ARM": + if (IntPtr.Size == 4) { + machine = Machine.ARMNT; + return true; + } + Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); + break; + + case "ARM64": + if (IntPtr.Size == 8) { + machine = Machine.ARM64; + return true; + } + Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); + break; + } + } + + machine = default; + return false; + } + } +} diff --git a/src/dnlib.csproj b/src/dnlib.csproj index b67be29a4..f2aa616fd 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -47,6 +47,7 @@ true + @@ -177,9 +178,11 @@ + + + - @@ -192,6 +195,7 @@ + @@ -223,7 +227,6 @@ - @@ -231,17 +234,14 @@ - - - @@ -255,7 +255,6 @@ - @@ -402,6 +401,7 @@ + diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index e8d94e785..a0000ba7b 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -17,6 +17,7 @@ portable + From 31f5c0aaff57d1e2c4dedd7b81b8c82028007a42 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 3 Apr 2018 20:46:38 +0200 Subject: [PATCH 191/511] Misc --- src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs | 3 ++- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 17 ++++++++++------ .../Pdb/Dss/SymbolReaderWriterFactory.cs | 20 +++++++++---------- src/DotNet/Pdb/Dss/SymbolWriter.cs | 2 ++ src/DotNet/Pdb/Managed/PdbReader.cs | 13 ++++-------- src/DotNet/Pdb/Managed/SymbolReaderCreator.cs | 4 +--- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 4 +++- src/DotNet/Resource.cs | 2 +- src/DotNet/Writer/DataReaderChunk.cs | 2 +- src/DotNet/Writer/Metadata.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 4 ++-- src/DotNet/Writer/NativeModuleWriter.cs | 6 +++--- src/DotNet/Writer/Win32ResourcesChunk.cs | 6 +++--- src/IO/DataReaderFactory.cs | 13 +++++++----- src/W32Resources/ResourceData.cs | 2 +- 15 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs index 7776ab8e5..3c13192b5 100644 --- a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet.Pdb.Dss { sealed unsafe class ReaderMetaDataImport : MetaDataImport, IDisposable { - readonly Metadata metadata; + Metadata metadata; byte* blobPtr; IntPtr addrToFree; @@ -75,6 +75,7 @@ public void Dispose() { } void Dispose(bool disposing) { + metadata = null; var addrToFreeTmp = Interlocked.Exchange(ref addrToFree, IntPtr.Zero); blobPtr = null; if (addrToFreeTmp != IntPtr.Zero) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index b658ad238..a819d633a 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -10,8 +10,8 @@ namespace dnlib.DotNet.Pdb.Dss { sealed class SymbolReaderImpl : SymbolReader { ModuleDef module; - readonly ISymUnmanagedReader reader; - readonly object[] objsToKeepAlive; + ISymUnmanagedReader reader; + object[] objsToKeepAlive; const int E_FAIL = unchecked((int)0x80004005); @@ -85,13 +85,18 @@ public override void Dispose() { void Dispose(bool disposing) { (reader as ISymUnmanagedDispose)?.Destroy(); - foreach (var obj in objsToKeepAlive) - (obj as IDisposable)?.Dispose(); + var o = objsToKeepAlive; + if (o != null) { + foreach (var obj in o) + (obj as IDisposable)?.Dispose(); + } + module = null; + reader = null; + objsToKeepAlive = null; } - public bool CheckVersion(Guid pdbId, uint stamp, uint age) { + public bool IsValidSignature(Guid pdbId, uint stamp, uint age) { if (reader is ISymUnmanagedReader4 reader4) { - // Only id and age are verified int hr = reader4.MatchesModule(pdbId, stamp, age, out bool result); if (hr < 0) return false; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 6801013b3..d1cba7d30 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -56,8 +56,6 @@ public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metad var debugDir = pdbContext.CodeViewDebugDirectory; if (debugDir == null) return null; - if (debugDir.MajorVersion != 0 || debugDir.MinorVersion != 0) - return null; if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; @@ -72,7 +70,7 @@ public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metad return null; symReader = new SymbolReaderImpl(unmanagedReader, new object[] { pdbStream, mdImporter, comPdbStream }); - if (!symReader.CheckVersion(pdbGuid, debugDir.TimeDateStamp, age)) + if (!symReader.IsValidSignature(pdbGuid, debugDir.TimeDateStamp, age)) return null; error = false; @@ -97,10 +95,10 @@ public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metad } static ISymUnmanagedReader CreateSymUnmanagedReader(PdbReaderOptions options) { - bool useDiaSymreader = (options & PdbReaderOptions.NoDiaSymReader) == 0; - bool useOldDiaSymreader = (options & PdbReaderOptions.NoOldDiaSymReader) == 0; + bool useDiaSymReader = (options & PdbReaderOptions.NoDiaSymReader) == 0; + bool useOldDiaSymReader = (options & PdbReaderOptions.NoOldDiaSymReader) == 0; - if (useDiaSymreader && canTry_Microsoft_DiaSymReader_Native) { + if (useDiaSymReader && canTry_Microsoft_DiaSymReader_Native) { try { var guid = CLSID_CorSymReader_SxS; object symReaderObj; @@ -134,17 +132,17 @@ static ISymUnmanagedReader CreateSymUnmanagedReader(PdbReaderOptions options) { canTry_Microsoft_DiaSymReader_Native = false; } - if (useOldDiaSymreader) + if (useOldDiaSymReader) return (ISymUnmanagedReader)Activator.CreateInstance(CorSymReader_Type ?? (CorSymReader_Type = Type.GetTypeFromCLSID(CLSID_CorSymReader_SxS))); return null; } static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) { - bool useDiaSymreader = (options & PdbWriterOptions.NoDiaSymReader) == 0; - bool useOldDiaSymreader = (options & PdbWriterOptions.NoOldDiaSymReader) == 0; + bool useDiaSymReader = (options & PdbWriterOptions.NoDiaSymReader) == 0; + bool useOldDiaSymReader = (options & PdbWriterOptions.NoOldDiaSymReader) == 0; - if (useDiaSymreader && canTry_Microsoft_DiaSymReader_Native) { + if (useDiaSymReader && canTry_Microsoft_DiaSymReader_Native) { try { var guid = CLSID_CorSymWriter_SxS; object symWriterObj; @@ -178,7 +176,7 @@ static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) canTry_Microsoft_DiaSymReader_Native = false; } - if (useOldDiaSymreader) + if (useOldDiaSymReader) return (ISymUnmanagedWriter2)Activator.CreateInstance(CorSymWriterType ?? (CorSymWriterType = Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS))); return null; diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index e04d4c08f..73a1a4049 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -143,8 +143,10 @@ public unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint if (isDeterministic) { ((ISymUnmanagedWriter3)writer).Commit(); + var oldPos = pdbStream.Position; pdbStream.Position = 0; var checksumBytes = Hasher.Hash(pdbChecksumAlgorithm, pdbStream, pdbStream.Length); + pdbStream.Position = oldPos; if (writer is ISymUnmanagedWriter8 writer8) { RoslynContentIdProvider.GetContentId(checksumBytes, out guid, out stamp); writer8.UpdateSignature(guid, stamp, pdbAge); diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index d81f3c84a..2468b7d74 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -32,15 +32,10 @@ sealed class PdbReader : SymbolReader { public override PdbFileKind PdbFileKind => PdbFileKind.WindowsPDB; - /// - /// The age of PDB file. - /// - public uint Age { get; private set; } - /// - /// The GUID of PDB file. - /// - public Guid Guid { get; private set; } + uint Age { get; set; } + Guid Guid { get; set; } + internal bool IsValidSignature => expectedGuid == Guid && expectedAge == Age; readonly Guid expectedGuid; readonly uint expectedAge; @@ -109,7 +104,7 @@ void ReadInternal(ref DataReader reader) { ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); ReadNames(); - if (Guid != expectedGuid || Age != expectedAge) + if (!IsValidSignature) return; ReadStringTable(); var tokenMapStream = ReadModules(); diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs index d7c1647e2..e2578ac7f 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs @@ -22,14 +22,12 @@ public static SymbolReader Create(PdbReaderContext pdbContext, DataReaderFactory var debugDir = pdbContext.CodeViewDebugDirectory; if (debugDir == null) return null; - if (debugDir.MajorVersion != 0 || debugDir.MinorVersion != 0) - return null; if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; var pdbReader = new PdbReader(pdbGuid, age); pdbReader.Read(pdbStream.CreateReader()); - if (pdbReader.Guid == pdbGuid && pdbReader.Age == age) + if (pdbReader.IsValidSignature) return pdbReader; return null; } diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 2fa280755..bbea97d62 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -355,7 +355,7 @@ void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { var constant = constants[i]; sig.Type = constant.Type; var token = metadata.GetToken(sig); - writer.DefineConstant2(constant.Name, constant.Value ?? 0, token.Raw); + writer.DefineConstant2(constant.Name, constant.Value ?? boxedZeroInt32, token.Raw); } } var scopeNamespaces = scope.Namespaces; @@ -368,6 +368,7 @@ void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { WriteScope(ref info, scopes[i], recursionCounter + 1); writer.CloseScope(startOffset == 0 && endOffset == info.BodySize ? endOffset : endOffset - localsEndScopeIncValue); } + static readonly object boxedZeroInt32 = 0; void AddLocals(MethodDef method, IList locals, uint startOffset, uint endOffset) { if (locals.Count == 0) @@ -417,6 +418,7 @@ public bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge public void Dispose() { if (writer != null) Close(); + writer?.Dispose(); writer = null; } } diff --git a/src/DotNet/Resource.cs b/src/DotNet/Resource.cs index 671241aca..56227890c 100644 --- a/src/DotNet/Resource.cs +++ b/src/DotNet/Resource.cs @@ -146,7 +146,7 @@ public EmbeddedResource(UTF8String name, DataReaderFactory dataReaderFactory, ui /// Gets a data reader that can access the resource /// /// - public DataReader GetReader() => dataReaderFactory.CreateReader(resourceStartOffset, resourceLength); + public DataReader CreateReader() => dataReaderFactory.CreateReader(resourceStartOffset, resourceLength); /// public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - size: {(resourceLength)}"; diff --git a/src/DotNet/Writer/DataReaderChunk.cs b/src/DotNet/Writer/DataReaderChunk.cs index 111521830..f94b70e78 100644 --- a/src/DotNet/Writer/DataReaderChunk.cs +++ b/src/DotNet/Writer/DataReaderChunk.cs @@ -59,7 +59,7 @@ internal DataReaderChunk(ref DataReader data, uint virtualSize) { /// /// Gets the data reader /// - public DataReader GetReader() => data; + public DataReader CreateReader() => data; /// /// Replaces the old data with new data. The new data must be the same size as the old data if diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 976725033..a6822c8ef 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2889,7 +2889,7 @@ uint AddEmbeddedResource(EmbeddedResource er) { 0); rid = tablesHeap.ManifestResourceTable.Add(row); manifestResourceInfos.Add(er, rid); - embeddedResourceToByteArray[er] = netResources.Add(er.GetReader()); + embeddedResourceToByteArray[er] = netResources.Add(er.CreateReader()); //TODO: Add custom attributes //TODO: Add custom debug infos return rid; diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 87459d540..7a664f131 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -114,14 +114,14 @@ public enum PdbWriterOptions { /// and if it's available at runtime, dnlib will try to use it. If this option is set, dnlib won't use it. /// You have to add a reference to the NuGet package if you want to use it, dnlib has no reference to the NuGet package. /// - /// Only used if it's a Windows PDB file + /// This is only used if it's a Windows PDB file. /// NoDiaSymReader = 0x00000001, /// /// Don't use diasymreader.dll's PDB writer that is shipped with .NET Framework. /// - /// Only used if it's a Windows PDB file + /// This is only used if it's a Windows PDB file. /// NoOldDiaSymReader = 0x00000002, diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 60ac5ff2d..677dbd93d 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -132,8 +132,8 @@ public void Dispose() { /// public override string ToString() { - uint offs = Chunk.GetReader().StartOffset; - return $"{PESection.DisplayName} FO:{offs:X8} L:{Chunk.GetReader().Length:X8}"; + uint offs = Chunk.CreateReader().StartOffset; + return $"{PESection.DisplayName} FO:{offs:X8} L:{Chunk.CreateReader().Length:X8}"; } } @@ -331,7 +331,7 @@ void CreateExtraData() { return; var lastOffs = GetLastFileSectionOffset(); extraData = new DataReaderChunk(peImage.CreateReader((FileOffset)lastOffs)); - if (extraData.GetReader().Length == 0) + if (extraData.CreateReader().Length == 0) extraData = null; } diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 89441b319..13fa02cd3 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -305,7 +305,7 @@ public void SetOffset(FileOffset offset, RVA rva) { foreach (var data in dataList) { rsrcOffset = Utils.AlignUp(rsrcOffset, RESOURCE_DATA_ALIGNMENT); dataDict[data] = rsrcOffset; - rsrcOffset += data.GetReader().Length; + rsrcOffset += data.CreateReader().Length; } length = rsrcOffset; @@ -400,7 +400,7 @@ public void WriteTo(DataWriter writer) { if (dataDict[data] != offset) throw new ModuleWriterException("Invalid Win32 resource data offset"); - var reader = data.GetReader(); + var reader = data.CreateReader(); offset += reader.BytesLeft; reader.CopyTo(writer, dataBuffer); } @@ -466,7 +466,7 @@ static void GetNamedAndIds(ResourceDirectory dir, out List /// - public DataReader CreateReader() => CreateReader(0, Length); + public DataReader CreateReader() => CreateReader(0U, Length); /// /// Creates a data reader @@ -33,6 +33,9 @@ public abstract class DataReaderFactory : IDisposable { /// public abstract DataReader CreateReader(uint offset, uint length); + static void ThrowArgumentOutOfRangeException(string paramName) => + throw new ArgumentOutOfRangeException(paramName); + /// /// Creates a data reader /// @@ -41,7 +44,7 @@ public abstract class DataReaderFactory : IDisposable { /// public DataReader CreateReader(uint offset, int length) { if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length)); + ThrowArgumentOutOfRangeException(nameof(length)); return CreateReader(offset, (uint)length); } @@ -53,7 +56,7 @@ public DataReader CreateReader(uint offset, int length) { /// public DataReader CreateReader(int offset, uint length) { if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset)); + ThrowArgumentOutOfRangeException(nameof(offset)); return CreateReader((uint)offset, length); } @@ -65,9 +68,9 @@ public DataReader CreateReader(int offset, uint length) { /// public DataReader CreateReader(int offset, int length) { if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset)); + ThrowArgumentOutOfRangeException(nameof(offset)); if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length)); + ThrowArgumentOutOfRangeException(nameof(length)); return CreateReader((uint)offset, (uint)length); } diff --git a/src/W32Resources/ResourceData.cs b/src/W32Resources/ResourceData.cs index 3832829ee..a2d3d3f15 100644 --- a/src/W32Resources/ResourceData.cs +++ b/src/W32Resources/ResourceData.cs @@ -19,7 +19,7 @@ public sealed class ResourceData : ResourceDirectoryEntry { /// Gets the data reader /// /// - public DataReader GetReader() => dataReaderFactory.CreateReader(resourceStartOffset, resourceLength); + public DataReader CreateReader() => dataReaderFactory.CreateReader(resourceStartOffset, resourceLength); /// /// Gets/sets the code page From 49b52ee9294aa6bcc6c969dc08490ffa56f8ea2e Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 3 Apr 2018 20:46:48 +0200 Subject: [PATCH 192/511] Rename --- README.md | 5 + src/DotNet/CallingConventionSig.cs | 6 +- src/DotNet/Emit/InstructionPrinter.cs | 2 +- src/DotNet/EventDef.cs | 2 +- src/DotNet/ExportedType.cs | 20 +-- src/DotNet/FieldDef.cs | 2 +- ...{FullNameCreator.cs => FullNameFactory.cs} | 146 +++++++++--------- ...{MetadataCreator.cs => MetadataFactory.cs} | 2 +- src/DotNet/MemberRef.cs | 4 +- src/DotNet/MethodDef.cs | 2 +- src/DotNet/MethodSpec.cs | 4 +- src/DotNet/ModuleDefMD.cs | 38 ++--- ...eaderCreator.cs => SymbolReaderFactory.cs} | 2 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 2 +- ...eaderCreator.cs => SymbolReaderFactory.cs} | 2 +- ...eaderCreator.cs => SymbolReaderFactory.cs} | 8 +- src/DotNet/PropertyDef.cs | 2 +- ...eDataCreator.cs => ResourceDataFactory.cs} | 4 +- src/DotNet/Resources/ResourceReader.cs | 50 +++--- src/DotNet/Resources/ResourceWriter.cs | 4 +- src/DotNet/TypeDef.cs | 18 +-- src/DotNet/TypeDefFinder.cs | 12 +- src/DotNet/TypeRef.cs | 18 +-- src/DotNet/TypeSig.cs | 24 +-- src/DotNet/TypeSpec.cs | 22 +-- src/DotNet/Writer/CustomAttributeWriter.cs | 4 +- src/DotNet/Writer/DeclSecurityWriter.cs | 2 +- src/DotNet/Writer/MarshalBlobWriter.cs | 6 +- src/DotNet/Writer/Metadata.cs | 4 +- src/DotNet/Writer/MethodBodyWriter.cs | 10 +- src/dnlib.csproj | 12 +- 31 files changed, 222 insertions(+), 217 deletions(-) rename src/DotNet/{FullNameCreator.cs => FullNameFactory.cs} (94%) rename src/DotNet/MD/{MetadataCreator.cs => MetadataFactory.cs} (99%) rename src/DotNet/Pdb/Managed/{SymbolReaderCreator.cs => SymbolReaderFactory.cs} (97%) rename src/DotNet/Pdb/Portable/{SymbolReaderCreator.cs => SymbolReaderFactory.cs} (98%) rename src/DotNet/Pdb/{SymbolReaderCreator.cs => SymbolReaderFactory.cs} (94%) rename src/DotNet/Resources/{ResourceDataCreator.cs => ResourceDataFactory.cs} (99%) diff --git a/README.md b/README.md index 1b76dab92..023e666c8 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,11 @@ v3.0 breaking changes - `MetadataOptions`' `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded` and `PreserveHeapOrder()` instead. - `Instruction.GetLocal()` returns a local if the instruction is a `ldloca` or `ldloca.s` instruction (it used to return null) - `ModuleCreationOptions.PdbImplementation` has been removed and replaced with `PdbOptions` +- Renamed + - `ITokenCreator` -> `ITokenProvider` + - `MetadataCreator` -> `MetadataFactory` + - `ResourceDataCreator` -> `ResourceDataFactory` + - `FullNameCreator` -> `FullNameFactory` Examples -------- diff --git a/src/DotNet/CallingConventionSig.cs b/src/DotNet/CallingConventionSig.cs index 52c1185cd..a8d242240 100644 --- a/src/DotNet/CallingConventionSig.cs +++ b/src/DotNet/CallingConventionSig.cs @@ -219,7 +219,7 @@ internal FieldSig(CallingConvention callingConvention, TypeSig type) { public FieldSig Clone() => new FieldSig(callingConvention, type); /// - public override string ToString() => FullNameCreator.FullName(type, false, null, null, null, null); + public override string ToString() => FullNameFactory.FullName(type, false, null, null, null, null); } /// @@ -580,7 +580,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi public MethodSig Clone() => new MethodSig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); /// - public override string ToString() => FullNameCreator.MethodBaseSigFullName(this, null); + public override string ToString() => FullNameFactory.MethodBaseSigFullName(this, null); } /// @@ -771,7 +771,7 @@ internal PropertySig(CallingConvention callingConvention, uint genParamCount, Ty public PropertySig Clone() => new PropertySig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); /// - public override string ToString() => FullNameCreator.MethodBaseSigFullName(this, null); + public override string ToString() => FullNameFactory.MethodBaseSigFullName(this, null); } /// diff --git a/src/DotNet/Emit/InstructionPrinter.cs b/src/DotNet/Emit/InstructionPrinter.cs index 34ccf4aef..6e1a95bfe 100644 --- a/src/DotNet/Emit/InstructionPrinter.cs +++ b/src/DotNet/Emit/InstructionPrinter.cs @@ -83,7 +83,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string case OperandType.InlineSig: sb.Append(extra); - sb.Append(FullNameCreator.MethodFullName(null, (UTF8String)null, op as MethodSig, null, null, null, null)); + sb.Append(FullNameFactory.MethodFullName(null, (UTF8String)null, op as MethodSig, null, null, null, null)); break; case OperandType.InlineString: diff --git a/src/DotNet/EventDef.cs b/src/DotNet/EventDef.cs index c659d767b..f2c0867db 100644 --- a/src/DotNet/EventDef.cs +++ b/src/DotNet/EventDef.cs @@ -249,7 +249,7 @@ public TypeDef DeclaringType2 { /// /// Gets the full name of the event /// - public string FullName => FullNameCreator.EventFullName(declaringType2?.FullName, name, eventType, null, null); + public string FullName => FullNameFactory.EventFullName(declaringType2?.FullName, name, eventType, null, null); bool IIsTypeOrMethod.IsType => false; bool IIsTypeOrMethod.IsMethod => false; diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index bb6ed505c..7cb7e3f1b 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -94,7 +94,7 @@ public bool IsValueType { public bool IsPrimitive => this.IsPrimitive(); /// - string IType.TypeName => FullNameCreator.Name(this, false, null); + string IType.TypeName => FullNameFactory.Name(this, false, null); /// public UTF8String Name { @@ -103,31 +103,31 @@ public UTF8String Name { } /// - public string ReflectionName => FullNameCreator.Name(this, true, null); + public string ReflectionName => FullNameFactory.Name(this, true, null); /// - public string Namespace => FullNameCreator.Namespace(this, false, null); + public string Namespace => FullNameFactory.Namespace(this, false, null); /// - public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); + public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); /// - public string FullName => FullNameCreator.FullName(this, false, null, null); + public string FullName => FullNameFactory.FullName(this, false, null, null); /// - public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); + public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); /// - public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); + public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); + public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); /// - public IScope Scope => FullNameCreator.Scope(this); + public IScope Scope => FullNameFactory.Scope(this); /// - public ITypeDefOrRef ScopeType => FullNameCreator.ScopeType(this); + public ITypeDefOrRef ScopeType => FullNameFactory.ScopeType(this); /// /// Always returns false since a does not contain any diff --git a/src/DotNet/FieldDef.cs b/src/DotNet/FieldDef.cs index 6d6ecfa5d..ac1279d98 100644 --- a/src/DotNet/FieldDef.cs +++ b/src/DotNet/FieldDef.cs @@ -618,7 +618,7 @@ public bool HasFieldRVA { /// /// Returns the full name of this field /// - public string FullName => FullNameCreator.FieldFullName(declaringType2?.FullName, name, FieldSig, null, null); + public string FullName => FullNameFactory.FieldFullName(declaringType2?.FullName, name, FieldSig, null, null); /// /// Gets the size of this field in bytes or 0 if unknown. diff --git a/src/DotNet/FullNameCreator.cs b/src/DotNet/FullNameFactory.cs similarity index 94% rename from src/DotNet/FullNameCreator.cs rename to src/DotNet/FullNameFactory.cs index 4c192d8c3..73049c8e4 100644 --- a/src/DotNet/FullNameCreator.cs +++ b/src/DotNet/FullNameFactory.cs @@ -5,9 +5,9 @@ namespace dnlib.DotNet { /// - /// Helps create a name + /// Helps create a name /// - public interface IFullNameCreatorHelper { + public interface IFullNameFactoryHelper { /// /// Checks whether the assembly name should be included when printing /// the full type name. The assembly name isn't required in custom attributes @@ -23,18 +23,18 @@ public interface IFullNameCreatorHelper { /// /// Creates type names, method names, etc. /// - public struct FullNameCreator { + public struct FullNameFactory { const string RECURSION_ERROR_RESULT_STRING = "<<>>"; const string NULLVALUE = "<<>>"; readonly StringBuilder sb; readonly bool isReflection; - readonly IFullNameCreatorHelper helper; + readonly IFullNameFactoryHelper helper; GenericArguments genericArguments; RecursionCounter recursionCounter; /// /// Checks whether the assembly name should be included when printing the full name. - /// See for more info. + /// See for more info. /// /// Owner module /// The type (TypeDef, TypeRef or ExportedType) @@ -64,7 +64,7 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type) { /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) => + public static string FullName(IType type, bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) => FullNameSB(type, isReflection, helper, sb).ToString(); /// @@ -75,7 +75,7 @@ public static string FullName(IType type, bool isReflection, IFullNameCreatorHel /// Helps print the name /// String builder to use or null /// The full name - public static StringBuilder FullNameSB(IType type, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + public static StringBuilder FullNameSB(IType type, bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { if (type is TypeDef td) return FullNameSB(td, isReflection, helper, sb); if (type is TypeRef tr) @@ -158,7 +158,7 @@ public static StringBuilder NamespaceSB(IType type, bool isReflection, StringBui /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string AssemblyQualifiedName(IType type, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => AssemblyQualifiedNameSB(type, helper, sb).ToString(); /// @@ -168,7 +168,7 @@ public static string AssemblyQualifiedName(IType type, IFullNameCreatorHelper he /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static StringBuilder AssemblyQualifiedNameSB(IType type, IFullNameCreatorHelper helper, StringBuilder sb) { + public static StringBuilder AssemblyQualifiedNameSB(IType type, IFullNameFactoryHelper helper, StringBuilder sb) { if (type is TypeDef td) return AssemblyQualifiedNameSB(td, helper, sb); @@ -209,7 +209,7 @@ public static string PropertyFullName(string declaringType, UTF8String name, Cal /// String builder to use or null /// Property full name public static StringBuilder PropertyFullNameSB(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs, StringBuilder sb) { - var fnc = new FullNameCreator(false, null, sb); + var fnc = new FullNameFactory(false, null, sb); if (typeGenArgs != null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); @@ -241,7 +241,7 @@ public static string EventFullName(string declaringType, UTF8String name, ITypeD /// String builder to use or null /// Property full name public static StringBuilder EventFullNameSB(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs, StringBuilder sb) { - var fnc = new FullNameCreator(false, null, sb); + var fnc = new FullNameFactory(false, null, sb); if (typeGenArgs != null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); @@ -273,7 +273,7 @@ public static string FieldFullName(string declaringType, string name, FieldSig f /// String builder to use or null /// Field full name public static StringBuilder FieldFullNameSB(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs, StringBuilder sb) { - var fnc = new FullNameCreator(false, null, sb); + var fnc = new FullNameFactory(false, null, sb); if (typeGenArgs != null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); @@ -309,7 +309,7 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// String builder to use or null /// Method full name public static StringBuilder MethodFullNameSB(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod, StringBuilder sb) { - var fnc = new FullNameCreator(false, null, sb); + var fnc = new FullNameFactory(false, null, sb); if (typeGenArgs != null || methodGenArgs != null) fnc.genericArguments = new GenericArguments(); if (typeGenArgs != null) @@ -336,7 +336,7 @@ public static string MethodBaseSigFullName(MethodBaseSig sig, StringBuilder sb = /// String builder to use or null /// Property sig full name public static StringBuilder MethodBaseSigFullNameSB(MethodBaseSig sig, StringBuilder sb) { - var fnc = new FullNameCreator(false, null, sb); + var fnc = new FullNameFactory(false, null, sb); fnc.CreateMethodFullName(null, null, sig, null); return fnc.sb ?? new StringBuilder(); } @@ -363,7 +363,7 @@ public static string MethodBaseSigFullName(string declType, string name, MethodB /// String builder to use or null /// Sig full name public static StringBuilder MethodBaseSigFullNameSB(string declType, string name, MethodBaseSig sig, MethodDef gppMethod, StringBuilder sb) { - var fnc = new FullNameCreator(false, null, sb); + var fnc = new FullNameFactory(false, null, sb); fnc.CreateMethodFullName(declType, name, sig, gppMethod); return fnc.sb ?? new StringBuilder(); } @@ -386,7 +386,7 @@ public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder /// String builder to use or null /// The namespace public static StringBuilder NamespaceSB(TypeRef typeRef, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateNamespace(typeRef); return fnc.sb ?? new StringBuilder(); } @@ -409,7 +409,7 @@ public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb = /// String builder to use or null /// The name public static StringBuilder NameSB(TypeRef typeRef, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateName(typeRef); return fnc.sb ?? new StringBuilder(); } @@ -422,7 +422,7 @@ public static StringBuilder NameSB(TypeRef typeRef, bool isReflection, StringBui /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string FullName(TypeRef typeRef, bool isReflection, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => FullNameSB(typeRef, isReflection, helper, sb).ToString(); /// @@ -433,8 +433,8 @@ public static string FullName(TypeRef typeRef, bool isReflection, IFullNameCreat /// Helps print the name /// String builder to use or null /// The full name - public static StringBuilder FullNameSB(TypeRef typeRef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, helper, sb); + public static StringBuilder FullNameSB(TypeRef typeRef, bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(isReflection, helper, sb); fnc.CreateFullName(typeRef); return fnc.sb ?? new StringBuilder(); } @@ -446,7 +446,7 @@ public static StringBuilder FullNameSB(TypeRef typeRef, bool isReflection, IFull /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => AssemblyQualifiedNameSB(typeRef, helper, sb).ToString(); /// @@ -456,8 +456,8 @@ public static string AssemblyQualifiedName(TypeRef typeRef, IFullNameCreatorHelp /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static StringBuilder AssemblyQualifiedNameSB(TypeRef typeRef, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(true, helper, sb); + public static StringBuilder AssemblyQualifiedNameSB(TypeRef typeRef, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeRef); return fnc.sb ?? new StringBuilder(); } @@ -468,7 +468,7 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeRef typeRef, IFullNameCr /// The TypeRef /// A or null if none found public static IAssembly DefinitionAssembly(TypeRef typeRef) => - new FullNameCreator().GetDefinitionAssembly(typeRef); + new FullNameFactory().GetDefinitionAssembly(typeRef); /// /// Gets the scope @@ -476,7 +476,7 @@ public static IAssembly DefinitionAssembly(TypeRef typeRef) => /// The TypeRef /// The or null if none found public static IScope Scope(TypeRef typeRef) => - new FullNameCreator().GetScope(typeRef); + new FullNameFactory().GetScope(typeRef); /// /// Returns the owner module. The type was created from metadata in this module. @@ -484,7 +484,7 @@ public static IScope Scope(TypeRef typeRef) => /// The TypeRef /// A or null if none found public static ModuleDef OwnerModule(TypeRef typeRef) => - new FullNameCreator().GetOwnerModule(typeRef); + new FullNameFactory().GetOwnerModule(typeRef); /// /// Returns the namespace of a @@ -504,7 +504,7 @@ public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder /// String builder to use or null /// The namespace public static StringBuilder NamespaceSB(TypeDef typeDef, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateNamespace(typeDef); return fnc.sb ?? new StringBuilder(); } @@ -527,7 +527,7 @@ public static string Name(TypeDef typeDef, bool isReflection, StringBuilder sb = /// String builder to use or null /// The name public static StringBuilder NameSB(TypeDef typeDef, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateName(typeDef); return fnc.sb ?? new StringBuilder(); } @@ -540,7 +540,7 @@ public static StringBuilder NameSB(TypeDef typeDef, bool isReflection, StringBui /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string FullName(TypeDef typeDef, bool isReflection, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => FullNameSB(typeDef, isReflection, helper, sb).ToString(); /// @@ -551,8 +551,8 @@ public static string FullName(TypeDef typeDef, bool isReflection, IFullNameCreat /// Helps print the name /// String builder to use or null /// The full name - public static StringBuilder FullNameSB(TypeDef typeDef, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, helper, sb); + public static StringBuilder FullNameSB(TypeDef typeDef, bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(isReflection, helper, sb); fnc.CreateFullName(typeDef); return fnc.sb ?? new StringBuilder(); } @@ -564,7 +564,7 @@ public static StringBuilder FullNameSB(TypeDef typeDef, bool isReflection, IFull /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => AssemblyQualifiedNameSB(typeDef, helper, sb).ToString(); /// @@ -574,8 +574,8 @@ public static string AssemblyQualifiedName(TypeDef typeDef, IFullNameCreatorHelp /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static StringBuilder AssemblyQualifiedNameSB(TypeDef typeDef, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(true, helper, sb); + public static StringBuilder AssemblyQualifiedNameSB(TypeDef typeDef, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeDef); return fnc.sb ?? new StringBuilder(); } @@ -586,7 +586,7 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeDef typeDef, IFullNameCr /// The TypeDef /// A or null if none found public static IAssembly DefinitionAssembly(TypeDef typeDef) => - new FullNameCreator().GetDefinitionAssembly(typeDef); + new FullNameFactory().GetDefinitionAssembly(typeDef); /// /// Returns the owner module. The type was created from metadata in this module. @@ -594,7 +594,7 @@ public static IAssembly DefinitionAssembly(TypeDef typeDef) => /// The TypeDef /// A or null if none found public static ModuleDef OwnerModule(TypeDef typeDef) => - new FullNameCreator().GetOwnerModule(typeDef); + new FullNameFactory().GetOwnerModule(typeDef); /// /// Returns the namespace of a @@ -614,7 +614,7 @@ public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuild /// String builder to use or null /// The namespace public static StringBuilder NamespaceSB(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateNamespace(typeSpec); return fnc.sb ?? new StringBuilder(); } @@ -637,7 +637,7 @@ public static string Name(TypeSpec typeSpec, bool isReflection, StringBuilder sb /// String builder to use or null /// The name public static StringBuilder NameSB(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateName(typeSpec); return fnc.sb ?? new StringBuilder(); } @@ -650,7 +650,7 @@ public static StringBuilder NameSB(TypeSpec typeSpec, bool isReflection, StringB /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => FullNameSB(typeSpec, isReflection, helper, sb).ToString(); /// @@ -661,8 +661,8 @@ public static string FullName(TypeSpec typeSpec, bool isReflection, IFullNameCre /// Helps print the name /// String builder to use or null /// The full name - public static StringBuilder FullNameSB(TypeSpec typeSpec, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, helper, sb); + public static StringBuilder FullNameSB(TypeSpec typeSpec, bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(isReflection, helper, sb); fnc.CreateFullName(typeSpec); return fnc.sb ?? new StringBuilder(); } @@ -674,7 +674,7 @@ public static StringBuilder FullNameSB(TypeSpec typeSpec, bool isReflection, IFu /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => AssemblyQualifiedNameSB(typeSpec, helper, sb).ToString(); /// @@ -684,8 +684,8 @@ public static string AssemblyQualifiedName(TypeSpec typeSpec, IFullNameCreatorHe /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static StringBuilder AssemblyQualifiedNameSB(TypeSpec typeSpec, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(true, helper, sb); + public static StringBuilder AssemblyQualifiedNameSB(TypeSpec typeSpec, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeSpec); return fnc.sb ?? new StringBuilder(); } @@ -696,7 +696,7 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeSpec typeSpec, IFullName /// The TypeSpec /// A or null if none found public static IAssembly DefinitionAssembly(TypeSpec typeSpec) => - new FullNameCreator().GetDefinitionAssembly(typeSpec); + new FullNameFactory().GetDefinitionAssembly(typeSpec); /// /// Gets the scope type @@ -704,7 +704,7 @@ public static IAssembly DefinitionAssembly(TypeSpec typeSpec) => /// The TypeSpec /// The scope type or null if none found public static ITypeDefOrRef ScopeType(TypeSpec typeSpec) => - new FullNameCreator().GetScopeType(typeSpec); + new FullNameFactory().GetScopeType(typeSpec); /// /// Gets the scope @@ -712,7 +712,7 @@ public static ITypeDefOrRef ScopeType(TypeSpec typeSpec) => /// The TypeSpec /// The or null if none found public static IScope Scope(TypeSpec typeSpec) => - new FullNameCreator().GetScope(typeSpec); + new FullNameFactory().GetScope(typeSpec); /// /// Returns the owner module. The type was created from metadata in this module. @@ -720,7 +720,7 @@ public static IScope Scope(TypeSpec typeSpec) => /// The TypeSpec /// A or null if none found public static ModuleDef OwnerModule(TypeSpec typeSpec) => - new FullNameCreator().GetOwnerModule(typeSpec); + new FullNameFactory().GetOwnerModule(typeSpec); /// /// Returns the namespace of a @@ -740,7 +740,7 @@ public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder /// String builder to use or null /// The namespace public static StringBuilder NamespaceSB(TypeSig typeSig, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateNamespace(typeSig); return fnc.sb ?? new StringBuilder(); } @@ -763,7 +763,7 @@ public static string Name(TypeSig typeSig, bool isReflection, StringBuilder sb = /// String builder to use or null /// The name public static StringBuilder NameSB(TypeSig typeSig, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateName(typeSig); return fnc.sb ?? new StringBuilder(); } @@ -778,7 +778,7 @@ public static StringBuilder NameSB(TypeSig typeSig, bool isReflection, StringBui /// Method generic args or null if none /// String builder to use or null /// The full name - public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper = null, IList typeGenArgs = null, IList methodGenArgs = null, StringBuilder sb = null) => + public static string FullName(TypeSig typeSig, bool isReflection, IFullNameFactoryHelper helper = null, IList typeGenArgs = null, IList methodGenArgs = null, StringBuilder sb = null) => FullNameSB(typeSig, isReflection, helper, typeGenArgs, methodGenArgs, sb).ToString(); /// @@ -791,8 +791,8 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameCreat /// Method generic args or null if none /// String builder to use or null /// The full name - public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFullNameCreatorHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, helper, sb); + public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFullNameFactoryHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { + var fnc = new FullNameFactory(isReflection, helper, sb); if (typeGenArgs != null || methodGenArgs != null) fnc.genericArguments = new GenericArguments(); if (typeGenArgs != null) @@ -810,7 +810,7 @@ public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFull /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => AssemblyQualifiedNameSB(typeSig, helper, sb).ToString(); /// @@ -820,8 +820,8 @@ public static string AssemblyQualifiedName(TypeSig typeSig, IFullNameCreatorHelp /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static StringBuilder AssemblyQualifiedNameSB(TypeSig typeSig, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(true, helper, sb); + public static StringBuilder AssemblyQualifiedNameSB(TypeSig typeSig, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(true, helper, sb); fnc.CreateAssemblyQualifiedName(typeSig); return fnc.sb ?? new StringBuilder(); } @@ -832,7 +832,7 @@ public static StringBuilder AssemblyQualifiedNameSB(TypeSig typeSig, IFullNameCr /// The TypeSig /// A or null if none found public static IAssembly DefinitionAssembly(TypeSig typeSig) => - new FullNameCreator().GetDefinitionAssembly(typeSig); + new FullNameFactory().GetDefinitionAssembly(typeSig); /// /// Gets the scope @@ -840,7 +840,7 @@ public static IAssembly DefinitionAssembly(TypeSig typeSig) => /// The TypeSig /// The or null if none found public static IScope Scope(TypeSig typeSig) => - new FullNameCreator().GetScope(typeSig); + new FullNameFactory().GetScope(typeSig); /// /// Gets the scope type @@ -848,7 +848,7 @@ public static IScope Scope(TypeSig typeSig) => /// The TypeSig /// The scope type or null if none found public static ITypeDefOrRef ScopeType(TypeSig typeSig) => - new FullNameCreator().GetScopeType(typeSig); + new FullNameFactory().GetScopeType(typeSig); /// /// Returns the owner module. The type was created from metadata in this module. @@ -856,7 +856,7 @@ public static ITypeDefOrRef ScopeType(TypeSig typeSig) => /// The TypeSig /// A or null if none found public static ModuleDef OwnerModule(TypeSig typeSig) => - new FullNameCreator().GetOwnerModule(typeSig); + new FullNameFactory().GetOwnerModule(typeSig); /// /// Returns the namespace of a @@ -876,7 +876,7 @@ public static string Namespace(ExportedType exportedType, bool isReflection, Str /// String builder to use or null /// The namespace public static StringBuilder NamespaceSB(ExportedType exportedType, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateNamespace(exportedType); return fnc.sb ?? new StringBuilder(); } @@ -899,7 +899,7 @@ public static string Name(ExportedType exportedType, bool isReflection, StringBu /// String builder to use or null /// The name public static StringBuilder NameSB(ExportedType exportedType, bool isReflection, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, null, sb); + var fnc = new FullNameFactory(isReflection, null, sb); fnc.CreateName(exportedType); return fnc.sb ?? new StringBuilder(); } @@ -912,7 +912,7 @@ public static StringBuilder NameSB(ExportedType exportedType, bool isReflection, /// Helps print the name /// String builder to use or null /// The full name - public static string FullName(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string FullName(ExportedType exportedType, bool isReflection, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => FullNameSB(exportedType, isReflection, helper, sb).ToString(); /// @@ -923,8 +923,8 @@ public static string FullName(ExportedType exportedType, bool isReflection, IFul /// Helps print the name /// String builder to use or null /// The full name - public static StringBuilder FullNameSB(ExportedType exportedType, bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(isReflection, helper, sb); + public static StringBuilder FullNameSB(ExportedType exportedType, bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(isReflection, helper, sb); fnc.CreateFullName(exportedType); return fnc.sb ?? new StringBuilder(); } @@ -936,7 +936,7 @@ public static StringBuilder FullNameSB(ExportedType exportedType, bool isReflect /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameCreatorHelper helper = null, StringBuilder sb = null) => + public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => AssemblyQualifiedNameSB(exportedType, helper, sb).ToString(); /// @@ -946,8 +946,8 @@ public static string AssemblyQualifiedName(ExportedType exportedType, IFullNameC /// Helps print the name /// String builder to use or null /// The assembly qualified full name - public static StringBuilder AssemblyQualifiedNameSB(ExportedType exportedType, IFullNameCreatorHelper helper, StringBuilder sb) { - var fnc = new FullNameCreator(true, helper, sb); + public static StringBuilder AssemblyQualifiedNameSB(ExportedType exportedType, IFullNameFactoryHelper helper, StringBuilder sb) { + var fnc = new FullNameFactory(true, helper, sb); fnc.CreateAssemblyQualifiedName(exportedType); return fnc.sb ?? new StringBuilder(); } @@ -958,7 +958,7 @@ public static StringBuilder AssemblyQualifiedNameSB(ExportedType exportedType, I /// The ExportedType /// A or null if none found public static IAssembly DefinitionAssembly(ExportedType exportedType) => - new FullNameCreator().GetDefinitionAssembly(exportedType); + new FullNameFactory().GetDefinitionAssembly(exportedType); /// /// Gets the scope type @@ -966,7 +966,7 @@ public static IAssembly DefinitionAssembly(ExportedType exportedType) => /// The ExportedType /// The scope type or null if none found public static ITypeDefOrRef ScopeType(ExportedType exportedType) => - new FullNameCreator().GetScopeType(exportedType); + new FullNameFactory().GetScopeType(exportedType); /// /// Gets the scope @@ -974,7 +974,7 @@ public static ITypeDefOrRef ScopeType(ExportedType exportedType) => /// The ExportedType /// The or null if none found public static IScope Scope(ExportedType exportedType) => - new FullNameCreator().GetScope(exportedType); + new FullNameFactory().GetScope(exportedType); /// /// Returns the owner module. The type was created from metadata in this module. @@ -982,11 +982,11 @@ public static IScope Scope(ExportedType exportedType) => /// The ExportedType /// A or null if none found public static ModuleDef OwnerModule(ExportedType exportedType) => - new FullNameCreator().GetOwnerModule(exportedType); + new FullNameFactory().GetOwnerModule(exportedType); string Result => sb?.ToString(); - FullNameCreator(bool isReflection, IFullNameCreatorHelper helper, StringBuilder sb) { + FullNameFactory(bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { this.sb = sb ?? new StringBuilder(); this.isReflection = isReflection; this.helper = helper; diff --git a/src/DotNet/MD/MetadataCreator.cs b/src/DotNet/MD/MetadataFactory.cs similarity index 99% rename from src/DotNet/MD/MetadataCreator.cs rename to src/DotNet/MD/MetadataFactory.cs index ca6981a64..bc7acee36 100644 --- a/src/DotNet/MD/MetadataCreator.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.MD { /// /// Low level access to a .NET file's metadata /// - public static class MetadataCreator { + public static class MetadataFactory { enum MetadataType { Unknown, Compressed, // #~ (normal) diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index d96bfea16..87109018a 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -259,10 +259,10 @@ public string FullName { } var methodSig = MethodSig; if (methodSig != null) - return FullNameCreator.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null, null, null); + return FullNameFactory.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null, null, null); var fieldSig = FieldSig; if (fieldSig != null) - return FullNameCreator.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs, null); + return FullNameFactory.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs, null); return string.Empty; } } diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 30141ba41..43172cd91 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -434,7 +434,7 @@ public NativeMethodBody NativeBody { /// /// Gets the full name /// - public string FullName => FullNameCreator.MethodFullName(declaringType2?.FullName, name, MethodSig, null, null, this, null); + public string FullName => FullNameFactory.MethodFullName(declaringType2?.FullName, name, MethodSig, null, null, this, null); /// /// Gets/sets the diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index 7944504df..1b1ed6aeb 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -138,14 +138,14 @@ public string FullName { var methodGenArgs = GenericInstMethodSig?.GenericArguments; var m = method; if (m is MethodDef methodDef) - return FullNameCreator.MethodFullName(methodDef.DeclaringType?.FullName, methodDef.Name, methodDef.MethodSig, null, methodGenArgs, null, null); + return FullNameFactory.MethodFullName(methodDef.DeclaringType?.FullName, methodDef.Name, methodDef.MethodSig, null, methodGenArgs, null, null); if (m is MemberRef memberRef) { var methodSig = memberRef.MethodSig; if (methodSig != null) { var gis = (memberRef.Class as TypeSpec)?.TypeSig as GenericInstSig; var typeGenArgs = gis?.GenericArguments; - return FullNameCreator.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs, null, null); + return FullNameFactory.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs, null, null); } } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 4f66a1b51..87ebfdd77 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -149,7 +149,7 @@ protected override VTableFixups GetVTableFixups_NoLock() { /// File name of an existing .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) => Load(MetadataCreator.Load(fileName), options); + public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) => Load(MetadataFactory.Load(fileName), options); /// /// Creates a instance from a byte[] @@ -165,7 +165,7 @@ protected override VTableFixups GetVTableFixups_NoLock() { /// Contents of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) => Load(MetadataCreator.Load(data), options); + public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) => Load(MetadataFactory.Load(data), options); /// /// Creates a instance from a reflection module @@ -241,7 +241,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// /// Address of a .NET module/assembly /// A new instance - public static ModuleDefMD Load(IntPtr addr) => Load(MetadataCreator.Load(addr), (ModuleCreationOptions)null); + public static ModuleDefMD Load(IntPtr addr) => Load(MetadataFactory.Load(addr), (ModuleCreationOptions)null); /// /// Creates a instance from a memory location @@ -249,7 +249,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Address of a .NET module/assembly /// Module context or null /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleContext context) => Load(MetadataCreator.Load(addr), new ModuleCreationOptions(context)); + public static ModuleDefMD Load(IntPtr addr, ModuleContext context) => Load(MetadataFactory.Load(addr), new ModuleCreationOptions(context)); /// /// Creates a instance from a memory location @@ -257,14 +257,14 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Address of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options) => Load(MetadataCreator.Load(addr), options); + public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options) => Load(MetadataFactory.Load(addr), options); /// /// Creates a instance /// /// PE image /// A new instance - public static ModuleDefMD Load(IPEImage peImage) => Load(MetadataCreator.Load(peImage), (ModuleCreationOptions)null); + public static ModuleDefMD Load(IPEImage peImage) => Load(MetadataFactory.Load(peImage), (ModuleCreationOptions)null); /// /// Creates a instance @@ -272,7 +272,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// PE image /// Module context or null /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) => Load(MetadataCreator.Load(peImage), new ModuleCreationOptions(context)); + public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) => Load(MetadataFactory.Load(peImage), new ModuleCreationOptions(context)); /// /// Creates a instance @@ -280,7 +280,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// PE image /// Module creation options or null /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) => Load(MetadataCreator.Load(peImage), options); + public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) => Load(MetadataFactory.Load(peImage), options); /// /// Creates a instance from a memory location @@ -289,7 +289,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Module context or null /// Image layout of the file in memory /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout imageLayout) => Load(MetadataCreator.Load(addr, imageLayout), new ModuleCreationOptions(context)); + public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout imageLayout) => Load(MetadataFactory.Load(addr, imageLayout), new ModuleCreationOptions(context)); /// /// Creates a instance from a memory location @@ -298,7 +298,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Module creation options or null /// Image layout of the file in memory /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, ImageLayout imageLayout) => Load(MetadataCreator.Load(addr, imageLayout), options); + public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, ImageLayout imageLayout) => Load(MetadataFactory.Load(addr, imageLayout), options); /// /// Creates a instance from a stream @@ -392,23 +392,23 @@ SymbolReader CreateSymbolReader(ModuleCreationOptions options) { if (options.PdbFileOrData != null) { var pdbFileName = options.PdbFileOrData as string; if (!string.IsNullOrEmpty(pdbFileName)) { - var symReader = SymbolReaderCreator.Create(options.PdbOptions, metadata, pdbFileName); + var symReader = SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbFileName); if (symReader != null) return symReader; } if (options.PdbFileOrData is byte[] pdbData) - return SymbolReaderCreator.Create(options.PdbOptions, metadata, pdbData); + return SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbData); if (options.PdbFileOrData is DataReaderFactory pdbStream) - return SymbolReaderCreator.Create(options.PdbOptions, metadata, pdbStream); + return SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbStream); } if (options.TryToLoadPdbFromDisk) { if (!string.IsNullOrEmpty(location)) - return SymbolReaderCreator.CreateFromAssemblyFile(options.PdbOptions, metadata, location); + return SymbolReaderFactory.CreateFromAssemblyFile(options.PdbOptions, metadata, location); else - return SymbolReaderCreator.TryCreateEmbeddedPdbReader(options.PdbOptions, metadata); + return SymbolReaderFactory.TryCreateEmbeddedPdbReader(options.PdbOptions, metadata); } return null; @@ -442,7 +442,7 @@ public void LoadPdb(string pdbFileName) => /// PDB reader options /// PDB file name public void LoadPdb(PdbReaderOptions options, string pdbFileName) => - LoadPdb(SymbolReaderCreator.Create(options, metadata, pdbFileName)); + LoadPdb(SymbolReaderFactory.Create(options, metadata, pdbFileName)); /// /// Loads symbols from a byte array @@ -457,7 +457,7 @@ public void LoadPdb(byte[] pdbData) => /// PDB reader options /// PDB data public void LoadPdb(PdbReaderOptions options, byte[] pdbData) => - LoadPdb(SymbolReaderCreator.Create(options, metadata, pdbData)); + LoadPdb(SymbolReaderFactory.Create(options, metadata, pdbData)); /// /// Loads symbols from a stream @@ -472,7 +472,7 @@ public void LoadPdb(DataReaderFactory pdbStream) => /// PDB reader options /// PDB file stream which is now owned by us public void LoadPdb(PdbReaderOptions options, DataReaderFactory pdbStream) => - LoadPdb(SymbolReaderCreator.Create(options, metadata, pdbStream)); + LoadPdb(SymbolReaderFactory.Create(options, metadata, pdbStream)); /// /// Loads symbols if a PDB file is available @@ -488,7 +488,7 @@ public void LoadPdb(PdbReaderOptions options) { var loc = location; if (string.IsNullOrEmpty(loc)) return; - LoadPdb(SymbolReaderCreator.Create(options, metadata, loc)); + LoadPdb(SymbolReaderFactory.Create(options, metadata, loc)); } internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { diff --git a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs similarity index 97% rename from src/DotNet/Pdb/Managed/SymbolReaderCreator.cs rename to src/DotNet/Pdb/Managed/SymbolReaderFactory.cs index e2578ac7f..4f0ea1ef5 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Pdb.Managed { /// /// Creates a instance /// - static class SymbolReaderCreator { + static class SymbolReaderFactory { /// /// Creates a new instance /// diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index b2f0049ab..6c2a377ed 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -23,7 +23,7 @@ sealed class PortablePdbReader : SymbolReader { public PortablePdbReader(DataReaderFactory pdbStream, PdbFileKind pdbFileKind) { this.pdbFileKind = pdbFileKind; - pdbMetadata = MetadataCreator.CreateStandalonePortablePDB(pdbStream, true); + pdbMetadata = MetadataFactory.CreateStandalonePortablePDB(pdbStream, true); } internal bool CheckVersion(Guid pdbGuid, uint timestamp) { diff --git a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs similarity index 98% rename from src/DotNet/Pdb/Portable/SymbolReaderCreator.cs rename to src/DotNet/Pdb/Portable/SymbolReaderFactory.cs index 1878bb757..81fccce88 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs @@ -10,7 +10,7 @@ using DDW = dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Portable { - static class SymbolReaderCreator { + static class SymbolReaderFactory { public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFactory pdbStream, bool isEmbeddedPortablePdb) { bool disposePdbStream = true; try { diff --git a/src/DotNet/Pdb/SymbolReaderCreator.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs similarity index 94% rename from src/DotNet/Pdb/SymbolReaderCreator.cs rename to src/DotNet/Pdb/SymbolReaderFactory.cs index 71e7c575a..78bec4d59 100644 --- a/src/DotNet/Pdb/SymbolReaderCreator.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -7,7 +7,7 @@ using dnlib.IO; namespace dnlib.DotNet.Pdb { - static class SymbolReaderCreator { + static class SymbolReaderFactory { public static SymbolReader CreateFromAssemblyFile(PdbReaderOptions options, Metadata metadata, string assemblyFileName) => Create(options, metadata, Path.ChangeExtension(assemblyFileName, "pdb")); @@ -97,8 +97,8 @@ static SymbolReader CreateManagedCore(PdbReaderContext pdbContext, DataReaderFac if (reader.Length >= 4) { uint sig = reader.ReadUInt32(); if (sig == 0x424A5342) - return Portable.SymbolReaderCreator.TryCreate(pdbContext, pdbStream, isEmbeddedPortablePdb: false); - return Managed.SymbolReaderCreator.Create(pdbContext, pdbStream); + return Portable.SymbolReaderFactory.TryCreate(pdbContext, pdbStream, isEmbeddedPortablePdb: false); + return Managed.SymbolReaderFactory.Create(pdbContext, pdbStream); } } catch (IOException) { @@ -108,6 +108,6 @@ static SymbolReader CreateManagedCore(PdbReaderContext pdbContext, DataReaderFac } static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext pdbContext, Metadata metadata) => - Portable.SymbolReaderCreator.TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); + Portable.SymbolReaderFactory.TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); } } diff --git a/src/DotNet/PropertyDef.cs b/src/DotNet/PropertyDef.cs index 06a8be1be..4d83e3eca 100644 --- a/src/DotNet/PropertyDef.cs +++ b/src/DotNet/PropertyDef.cs @@ -333,7 +333,7 @@ public TypeDef DeclaringType2 { /// /// Gets the full name of the property /// - public string FullName => FullNameCreator.PropertyFullName(declaringType2?.FullName, name, type, null, null); + public string FullName => FullNameFactory.PropertyFullName(declaringType2?.FullName, name, type, null, null); bool IIsTypeOrMethod.IsType => false; bool IIsTypeOrMethod.IsMethod => false; diff --git a/src/DotNet/Resources/ResourceDataCreator.cs b/src/DotNet/Resources/ResourceDataFactory.cs similarity index 99% rename from src/DotNet/Resources/ResourceDataCreator.cs rename to src/DotNet/Resources/ResourceDataFactory.cs index 46ea92c23..6f2cc8322 100644 --- a/src/DotNet/Resources/ResourceDataCreator.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -10,7 +10,7 @@ namespace dnlib.DotNet.Resources { /// /// Creates resource data /// - public class ResourceDataCreator { + public class ResourceDataFactory { readonly ModuleDef module; readonly ModuleDefMD moduleMD; readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); @@ -25,7 +25,7 @@ public class ResourceDataCreator { /// Constructor /// /// Owner module - public ResourceDataCreator(ModuleDef module) { + public ResourceDataFactory(ModuleDef module) { this.module = module; moduleMD = module as ModuleDefMD; } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 2a20c5a7e..0c0a181cc 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -41,11 +41,11 @@ public ResourceReaderException(SerializationInfo info, StreamingContext context) /// Gets called to create a from serialized data. Returns null /// if a default instance should be created. /// - /// ResourceDataCreator + /// ResourceDataFactory /// Serialized type /// Serialized data /// - public delegate IResourceData CreateResourceDataDelegate(ResourceDataCreator resourceDataCreator, UserResourceType type, byte[] serializedData); + public delegate IResourceData CreateResourceDataDelegate(ResourceDataFactory resourceDataFactory, UserResourceType type, byte[] serializedData); /// /// Reads .NET resources @@ -53,12 +53,12 @@ public ResourceReaderException(SerializationInfo info, StreamingContext context) public struct ResourceReader { DataReader reader; readonly uint baseFileOffset; - readonly ResourceDataCreator resourceDataCreator; + readonly ResourceDataFactory resourceDataFactory; readonly CreateResourceDataDelegate createResourceDataDelegate; ResourceReader(ModuleDef module, ref DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) { this.reader = reader; - resourceDataCreator = new ResourceDataCreator(module); + resourceDataFactory = new ResourceDataFactory(module); this.createResourceDataDelegate = createResourceDataDelegate; baseFileOffset = reader.StartOffset; } @@ -165,25 +165,25 @@ IResourceData ReadResourceData(List userTypes, int size) { uint endPos = reader.Position + (uint)size; uint code = ReadUInt32(ref reader); switch ((ResourceTypeCode)code) { - case ResourceTypeCode.Null: return resourceDataCreator.CreateNull(); - case ResourceTypeCode.String: return resourceDataCreator.Create(reader.ReadSerializedString()); - case ResourceTypeCode.Boolean: return resourceDataCreator.Create(reader.ReadBoolean()); - case ResourceTypeCode.Char: return resourceDataCreator.Create(reader.ReadChar()); - case ResourceTypeCode.Byte: return resourceDataCreator.Create(reader.ReadByte()); - case ResourceTypeCode.SByte: return resourceDataCreator.Create(reader.ReadSByte()); - case ResourceTypeCode.Int16: return resourceDataCreator.Create(reader.ReadInt16()); - case ResourceTypeCode.UInt16: return resourceDataCreator.Create(reader.ReadUInt16()); - case ResourceTypeCode.Int32: return resourceDataCreator.Create(reader.ReadInt32()); - case ResourceTypeCode.UInt32: return resourceDataCreator.Create(reader.ReadUInt32()); - case ResourceTypeCode.Int64: return resourceDataCreator.Create(reader.ReadInt64()); - case ResourceTypeCode.UInt64: return resourceDataCreator.Create(reader.ReadUInt64()); - case ResourceTypeCode.Single: return resourceDataCreator.Create(reader.ReadSingle()); - case ResourceTypeCode.Double: return resourceDataCreator.Create(reader.ReadDouble()); - case ResourceTypeCode.Decimal: return resourceDataCreator.Create(reader.ReadDecimal()); - case ResourceTypeCode.DateTime: return resourceDataCreator.Create(DateTime.FromBinary(reader.ReadInt64())); - case ResourceTypeCode.TimeSpan: return resourceDataCreator.Create(new TimeSpan(reader.ReadInt64())); - case ResourceTypeCode.ByteArray:return resourceDataCreator.Create(reader.ReadBytes(reader.ReadInt32())); - case ResourceTypeCode.Stream: return resourceDataCreator.CreateStream(reader.ReadBytes(reader.ReadInt32())); + case ResourceTypeCode.Null: return resourceDataFactory.CreateNull(); + case ResourceTypeCode.String: return resourceDataFactory.Create(reader.ReadSerializedString()); + case ResourceTypeCode.Boolean: return resourceDataFactory.Create(reader.ReadBoolean()); + case ResourceTypeCode.Char: return resourceDataFactory.Create(reader.ReadChar()); + case ResourceTypeCode.Byte: return resourceDataFactory.Create(reader.ReadByte()); + case ResourceTypeCode.SByte: return resourceDataFactory.Create(reader.ReadSByte()); + case ResourceTypeCode.Int16: return resourceDataFactory.Create(reader.ReadInt16()); + case ResourceTypeCode.UInt16: return resourceDataFactory.Create(reader.ReadUInt16()); + case ResourceTypeCode.Int32: return resourceDataFactory.Create(reader.ReadInt32()); + case ResourceTypeCode.UInt32: return resourceDataFactory.Create(reader.ReadUInt32()); + case ResourceTypeCode.Int64: return resourceDataFactory.Create(reader.ReadInt64()); + case ResourceTypeCode.UInt64: return resourceDataFactory.Create(reader.ReadUInt64()); + case ResourceTypeCode.Single: return resourceDataFactory.Create(reader.ReadSingle()); + case ResourceTypeCode.Double: return resourceDataFactory.Create(reader.ReadDouble()); + case ResourceTypeCode.Decimal: return resourceDataFactory.Create(reader.ReadDecimal()); + case ResourceTypeCode.DateTime: return resourceDataFactory.Create(DateTime.FromBinary(reader.ReadInt64())); + case ResourceTypeCode.TimeSpan: return resourceDataFactory.Create(new TimeSpan(reader.ReadInt64())); + case ResourceTypeCode.ByteArray:return resourceDataFactory.Create(reader.ReadBytes(reader.ReadInt32())); + case ResourceTypeCode.Stream: return resourceDataFactory.CreateStream(reader.ReadBytes(reader.ReadInt32())); default: int userTypeIndex = (int)(code - (uint)ResourceTypeCode.UserTypes); if (userTypeIndex < 0 || userTypeIndex >= userTypes.Count) @@ -191,11 +191,11 @@ IResourceData ReadResourceData(List userTypes, int size) { var userType = userTypes[userTypeIndex]; var serializedData = reader.ReadBytes((int)(endPos - reader.Position)); if (createResourceDataDelegate != null) { - var res = createResourceDataDelegate(resourceDataCreator, userType, serializedData); + var res = createResourceDataDelegate(resourceDataFactory, userType, serializedData); if (res != null) return res; } - return resourceDataCreator.CreateSerialized(serializedData, userType); + return resourceDataFactory.CreateSerialized(serializedData, userType); } } diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index ceb65520a..2a35eaa0e 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -15,12 +15,12 @@ public sealed class ResourceWriter { ModuleDef module; BinaryWriter writer; ResourceElementSet resources; - ResourceDataCreator typeCreator; + ResourceDataFactory typeCreator; Dictionary dataToNewType = new Dictionary(); ResourceWriter(ModuleDef module, Stream stream, ResourceElementSet resources) { this.module = module; - typeCreator = new ResourceDataCreator(module); + typeCreator = new ResourceDataFactory(module); writer = new BinaryWriter(stream); this.resources = resources; } diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index da371d725..d1064ab8f 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -52,28 +52,28 @@ public uint Rid { int IGenericParameterProvider.NumberOfGenericParameters => GenericParameters.Count; /// - string IType.TypeName => FullNameCreator.Name(this, false, null); + string IType.TypeName => FullNameFactory.Name(this, false, null); /// - public string ReflectionName => FullNameCreator.Name(this, true, null); + public string ReflectionName => FullNameFactory.Name(this, true, null); /// - string IType.Namespace => FullNameCreator.Namespace(this, false, null); + string IType.Namespace => FullNameFactory.Namespace(this, false, null); /// - public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); + public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); /// - public string FullName => FullNameCreator.FullName(this, false, null, null); + public string FullName => FullNameFactory.FullName(this, false, null, null); /// - public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); + public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); /// - public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); + public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); + public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); /// public IScope Scope => Module; @@ -88,7 +88,7 @@ public uint Rid { public bool ContainsGenericParameter => false; /// - public ModuleDef Module => FullNameCreator.OwnerModule(this); + public ModuleDef Module => FullNameFactory.OwnerModule(this); /// /// Gets/sets the owner module diff --git a/src/DotNet/TypeDefFinder.cs b/src/DotNet/TypeDefFinder.cs index da42a2cee..480914b5d 100644 --- a/src/DotNet/TypeDefFinder.cs +++ b/src/DotNet/TypeDefFinder.cs @@ -166,7 +166,7 @@ TypeDef FindCacheReflection(string fullName) { if (cachedType == null) return cachedType; sb.Length = 0; - if (FullNameCreator.FullName(cachedType, true, null, sb) == fullName) + if (FullNameFactory.FullName(cachedType, true, null, sb) == fullName) return cachedType; } } @@ -181,7 +181,7 @@ TypeDef FindCacheNormal(string fullName) { if (cachedType == null) return cachedType; sb.Length = 0; - if (FullNameCreator.FullName(cachedType, false, null, sb) == fullName) + if (FullNameFactory.FullName(cachedType, false, null, sb) == fullName) return cachedType; } } @@ -203,7 +203,7 @@ TypeDef FindSlowReflection(string fullName) { if (type == null) return type; sb.Length = 0; - if (FullNameCreator.FullName(type, true, null, sb) == fullName) + if (FullNameFactory.FullName(type, true, null, sb) == fullName) return type; } } @@ -215,7 +215,7 @@ TypeDef FindSlowNormal(string fullName) { if (type == null) return type; sb.Length = 0; - if (FullNameCreator.FullName(type, false, null, sb) == fullName) + if (FullNameFactory.FullName(type, false, null, sb) == fullName) return type; } } @@ -251,10 +251,10 @@ TypeDef GetNextTypeDefCache() { typeRefCache[type] = type; string fn; sb.Length = 0; - if (!normalNameCache.ContainsKey(fn = FullNameCreator.FullName(type, false, null, sb))) + if (!normalNameCache.ContainsKey(fn = FullNameFactory.FullName(type, false, null, sb))) normalNameCache[fn] = type; sb.Length = 0; - if (!reflectionNameCache.ContainsKey(fn = FullNameCreator.FullName(type, true, null, sb))) + if (!reflectionNameCache.ContainsKey(fn = FullNameFactory.FullName(type, true, null, sb))) reflectionNameCache[fn] = type; return type; diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index 53f43d2df..1390df475 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -52,31 +52,31 @@ public uint Rid { int IGenericParameterProvider.NumberOfGenericParameters => 0; /// - string IType.TypeName => FullNameCreator.Name(this, false, null); + string IType.TypeName => FullNameFactory.Name(this, false, null); /// - public string ReflectionName => FullNameCreator.Name(this, true, null); + public string ReflectionName => FullNameFactory.Name(this, true, null); /// - string IType.Namespace => FullNameCreator.Namespace(this, false, null); + string IType.Namespace => FullNameFactory.Namespace(this, false, null); /// - public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); + public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); /// - public string FullName => FullNameCreator.FullName(this, false, null, null); + public string FullName => FullNameFactory.FullName(this, false, null, null); /// - public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); + public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); /// - public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); + public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); + public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); /// - public IScope Scope => FullNameCreator.Scope(this); + public IScope Scope => FullNameFactory.Scope(this); /// public ITypeDefOrRef ScopeType => this; diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index 55e5ecd77..2afb84feb 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -95,43 +95,43 @@ public bool IsValueType { public bool IsPrimitive => ElementType.IsPrimitive(); /// - public string TypeName => FullNameCreator.Name(this, false, null); + public string TypeName => FullNameFactory.Name(this, false, null); /// UTF8String IFullName.Name { - get => new UTF8String(FullNameCreator.Name(this, false, null)); + get => new UTF8String(FullNameFactory.Name(this, false, null)); set => throw new NotSupportedException(); } /// - public string ReflectionName => FullNameCreator.Name(this, true, null); + public string ReflectionName => FullNameFactory.Name(this, true, null); /// - public string Namespace => FullNameCreator.Namespace(this, false, null); + public string Namespace => FullNameFactory.Namespace(this, false, null); /// - public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); + public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); /// - public string FullName => FullNameCreator.FullName(this, false, null, null, null, null); + public string FullName => FullNameFactory.FullName(this, false, null, null, null, null); /// - public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null, null, null); + public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null, null, null); /// - public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); + public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); + public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); /// - public IScope Scope => FullNameCreator.Scope(this); + public IScope Scope => FullNameFactory.Scope(this); /// - public ITypeDefOrRef ScopeType => FullNameCreator.ScopeType(this); + public ITypeDefOrRef ScopeType => FullNameFactory.ScopeType(this); /// - public ModuleDef Module => FullNameCreator.OwnerModule(this); + public ModuleDef Module => FullNameFactory.OwnerModule(this); /// /// true if it's a diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index baf638be0..57d906ed5 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -110,40 +110,40 @@ public bool IsPrimitive { } /// - public string TypeName => FullNameCreator.Name(this, false, null); + public string TypeName => FullNameFactory.Name(this, false, null); /// - public string ReflectionName => FullNameCreator.Name(this, true, null); + public string ReflectionName => FullNameFactory.Name(this, true, null); /// - string IType.Namespace => FullNameCreator.Namespace(this, false, null); + string IType.Namespace => FullNameFactory.Namespace(this, false, null); /// - public string ReflectionNamespace => FullNameCreator.Namespace(this, true, null); + public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); /// - public string FullName => FullNameCreator.FullName(this, false, null, null); + public string FullName => FullNameFactory.FullName(this, false, null, null); /// - public string ReflectionFullName => FullNameCreator.FullName(this, true, null, null); + public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); /// - public string AssemblyQualifiedName => FullNameCreator.AssemblyQualifiedName(this, null, null); + public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); /// - public IAssembly DefinitionAssembly => FullNameCreator.DefinitionAssembly(this); + public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); /// - public IScope Scope => FullNameCreator.Scope(this); + public IScope Scope => FullNameFactory.Scope(this); /// - public ITypeDefOrRef ScopeType => FullNameCreator.ScopeType(this); + public ITypeDefOrRef ScopeType => FullNameFactory.ScopeType(this); /// public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// - public ModuleDef Module => FullNameCreator.OwnerModule(this); + public ModuleDef Module => FullNameFactory.OwnerModule(this); /// /// From column TypeSpec.Signature diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index 67a434cef..9e297d029 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Writer { /// /// Helps write custom attributes /// - public interface ICustomAttributeWriterHelper : IWriterError, IFullNameCreatorHelper { + public interface ICustomAttributeWriterHelper : IWriterError, IFullNameFactoryHelper { } /// @@ -716,7 +716,7 @@ void WriteType(IType type) { WriteUTF8String(UTF8String.Empty); } else - WriteUTF8String(FullNameCreator.AssemblyQualifiedName(type, helper)); + WriteUTF8String(FullNameFactory.AssemblyQualifiedName(type, helper)); } static bool CheckCorLibType(TypeSig ts, string name) { diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index bb30da208..575892d8c 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -88,6 +88,6 @@ byte[] WriteFormat2(IList secAttrs) { uint WriteCompressedUInt32(DataWriter writer, uint value) => writer.WriteCompressedUInt32(helper, value); void Write(DataWriter writer, UTF8String s) => writer.Write(helper, s); void IWriterError.Error(string message) => helper.Error(message); - bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); + bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type); } } diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index e003c3850..63895ee13 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet.Writer { /// /// Writes field marshal blobs /// - public readonly struct MarshalBlobWriter : IDisposable, IFullNameCreatorHelper { + public readonly struct MarshalBlobWriter : IDisposable, IFullNameFactoryHelper { readonly ModuleDef module; readonly MemoryStream outStream; readonly DataWriter writer; @@ -84,7 +84,7 @@ byte[] Write(MarshalType marshalType) { Write(custMarshaler.Guid); Write(custMarshaler.NativeTypeName); var cm = custMarshaler.CustomMarshaler; - var cmName = cm == null ? string.Empty : FullNameCreator.AssemblyQualifiedName(cm, this); + var cmName = cm == null ? string.Empty : FullNameFactory.AssemblyQualifiedName(cm, this); Write(cmName); Write(custMarshaler.Cookie); break; @@ -130,6 +130,6 @@ bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { /// public void Dispose() => outStream?.Dispose(); - bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); + bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type); } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index a6822c8ef..d4ec797b2 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -407,7 +407,7 @@ public MetadataProgressEventArgs(Metadata metadata, double progress) { /// /// .NET meta data /// - public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenCreator, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper { + public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenProvider, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper { uint length; FileOffset offset; RVA rva; @@ -3468,7 +3468,7 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdb void IWriterError.Error(string message) => Error(message); /// - bool IFullNameCreatorHelper.MustUseAssemblyName(IType type) => FullNameCreator.MustUseAssemblyName(module, type); + bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type); /// /// Called before any other methods diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index c60dd7d1d..f62f8c5eb 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -8,7 +8,7 @@ namespace dnlib.DotNet.Writer { /// /// Returns tokens of token types, strings and signatures /// - public interface ITokenCreator : IWriterError { + public interface ITokenProvider : IWriterError { /// /// Gets the token of /// @@ -30,7 +30,7 @@ public interface ITokenCreator : IWriterError { /// Writes CIL method bodies /// public sealed class MethodBodyWriter : MethodBodyWriterBase { - readonly ITokenCreator helper; + readonly ITokenProvider helper; CilBody cilBody; bool keepMaxStack; uint codeSize; @@ -62,7 +62,7 @@ public sealed class MethodBodyWriter : MethodBodyWriterBase { /// /// Helps this instance /// The CIL method body - public MethodBodyWriter(ITokenCreator helper, CilBody cilBody) + public MethodBodyWriter(ITokenProvider helper, CilBody cilBody) : this(helper, cilBody, false) { } @@ -73,14 +73,14 @@ public MethodBodyWriter(ITokenCreator helper, CilBody cilBody) /// The CIL method body /// Keep the original max stack value that has been initialized /// in - public MethodBodyWriter(ITokenCreator helper, CilBody cilBody, bool keepMaxStack) + public MethodBodyWriter(ITokenProvider helper, CilBody cilBody, bool keepMaxStack) : base(cilBody.Instructions, cilBody.ExceptionHandlers) { this.helper = helper; this.cilBody = cilBody; this.keepMaxStack = keepMaxStack; } - internal MethodBodyWriter(ITokenCreator helper) => this.helper = helper; + internal MethodBodyWriter(ITokenProvider helper) => this.helper = helper; internal void Reset(CilBody cilBody, bool keepMaxStack) { Reset(cilBody.Instructions, cilBody.ExceptionHandlers); diff --git a/src/dnlib.csproj b/src/dnlib.csproj index f2aa616fd..f91a6a6cd 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -98,7 +98,7 @@ - + @@ -137,7 +137,7 @@ - + @@ -210,7 +210,7 @@ - + @@ -252,13 +252,13 @@ - + - + @@ -272,7 +272,7 @@ - + From 628db9bb87b69696d3a86f0f97386dcd51f3eb3b Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 3 Apr 2018 20:46:59 +0200 Subject: [PATCH 193/511] Support embedded sources, source link, source server --- src/DotNet/Pdb/Dss/ComInterfaces.cs | 27 ++++------- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 33 ++++++++++++- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 47 ++++++++++++++++++- .../Pdb/Dss/SymbolReaderWriterFactory.cs | 2 +- src/DotNet/Pdb/Dss/SymbolWriter.cs | 18 +++++++ src/DotNet/Pdb/Managed/DbiDocument.cs | 29 +++++++++--- src/DotNet/Pdb/Managed/PdbReader.cs | 26 +++++++++- src/DotNet/Pdb/Managed/SymbolReaderFactory.cs | 2 +- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 43 +++++++++++++++-- src/DotNet/Pdb/PdbDocument.cs | 16 ++++++- src/DotNet/Pdb/PdbState.cs | 14 +++++- .../PortablePdbCustomDebugInfoReader.cs | 4 +- .../PortablePdbCustomDebugInfoWriter.cs | 3 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 4 +- .../Pdb/Portable/SymbolReaderFactory.cs | 2 +- src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs | 2 + src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 20 ++++++++ src/DotNet/Writer/Metadata.cs | 1 + 18 files changed, 250 insertions(+), 43 deletions(-) diff --git a/src/DotNet/Pdb/Dss/ComInterfaces.cs b/src/DotNet/Pdb/Dss/ComInterfaces.cs index 6d996ee71..9a61f7e9d 100644 --- a/src/DotNet/Pdb/Dss/ComInterfaces.cs +++ b/src/DotNet/Pdb/Dss/ComInterfaces.cs @@ -17,23 +17,11 @@ interface ISymUnmanagedDispose { [ComVisible(true), ComImport, - Guid("809C652E-7396-11D2-9771-00A0C9B4D50C"), + Guid("997DD0CC-A76F-4c82-8D79-EA87559D27AD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface IMetaDataDispenser { - void DefineScope([In] ref Guid rclsid, [In] uint dwCreateFlags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppIUnk); - void OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] string szScope, [In] uint dwOpenFlags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppIUnk); - void OpenScopeOnMemory([In] IntPtr pData, [In] uint cbData, [In] uint dwOpenFlags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppIUnk); - } - - [ComVisible(true), - ComImport, - Guid("AA544D42-28CB-11D3-BD22-0000F80849BD"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedBinder { + interface ISymUnmanagedSourceServerModule { [PreserveSig] - int GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.LPWStr)] string fileName, [In, MarshalAs(UnmanagedType.LPWStr)] string searchPath, [Out] out ISymUnmanagedReader pRetVal); - [PreserveSig] - int GetReaderFromStream([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IStream pstream, [Out] out ISymUnmanagedReader pRetVal); + int GetSourceServerData(out int pDataByteCount, out IntPtr ppData); } [ComVisible(true), @@ -93,7 +81,8 @@ interface ISymUnmanagedReader4 : ISymUnmanagedReader3 { [PreserveSig] int MatchesModule(Guid guid, uint stamp, uint age, [MarshalAs(UnmanagedType.Bool)] out bool result); void GetPortableDebugMetadata(out IntPtr pMetadata, out uint pcMetadata); - void GetSourceServerData(out IntPtr data, out uint pcData); + [PreserveSig] + int GetSourceServerData(out IntPtr data, out int pcData); } [ComVisible(true), @@ -118,8 +107,10 @@ interface ISymUnmanagedDocument { void GetCheckSum([In] uint cData, [Out] out uint pcData, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] data); void FindClosestLine([In] uint line, [Out] out uint pRetVal); void HasEmbeddedSource([Out] out bool pRetVal); - void GetSourceLength([Out] out uint pRetVal); - void GetSourceRange([In] uint startLine, [In] uint startColumn, [In] uint endLine, [In] uint endColumn, [In] uint cSourceBytes, [Out] out uint pcSourceBytes, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] source); + [PreserveSig] + int GetSourceLength([Out] out int pRetVal); + [PreserveSig] + int GetSourceRange([In] uint startLine, [In] uint startColumn, [In] uint endLine, [In] uint endColumn, [In] int cSourceBytes, [Out] out int pcSourceBytes, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] source); } [ComVisible(true), diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index 47eaa8bfe..88a8d91ac 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -57,6 +57,37 @@ public override byte[] CheckSum { } } - public override PdbCustomDebugInfo[] CustomDebugInfos => Array2.Empty(); + byte[] SourceCode { + get { + int hr = document.GetSourceLength(out int size); + if (hr < 0) + return null; + if (size <= 0) + return null; + var sourceCode = new byte[size]; + hr = document.GetSourceRange(0, 0, int.MaxValue, int.MaxValue, size, out var bytesRead, sourceCode); + if (hr < 0) + return null; + if (bytesRead <= 0) + return null; + if (bytesRead != sourceCode.Length) + Array.Resize(ref sourceCode, bytesRead); + return sourceCode; + } + } + + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { + if (customDebugInfos == null) { + var sourceCode = SourceCode; + if (sourceCode != null) + customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; + else + customDebugInfos = Array2.Empty(); + } + return customDebugInfos; + } + } + PdbCustomDebugInfo[] customDebugInfos; } } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index a819d633a..1971ea1f0 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.InteropServices; using dnlib.DotNet.Emit; using dnlib.DotNet.Pdb.Symbols; @@ -76,6 +77,50 @@ internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, } public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { + if (token == 0x00000001) + GetCustomDebugInfos_ModuleDef(result); + } + + void GetCustomDebugInfos_ModuleDef(IList result) { + var sourceLinkData = GetSourceLinkData(); + if (sourceLinkData != null) + result.Add(new PdbSourceLinkCustomDebugInfo(sourceLinkData)); + var sourceServerData = GetSourceServerData(); + if (sourceServerData != null) + result.Add(new PdbSourceServerCustomDebugInfo(sourceServerData)); + } + + byte[] GetSourceLinkData() { + if (reader is ISymUnmanagedReader4 reader4) { + // It returns data that it owns. The data is freed once its Destroy() method is called + Debug.Assert(reader is ISymUnmanagedDispose); + // Despite its name, it seems to only return source link, and not source server info + if (reader4.GetSourceServerData(out var srcLinkData, out int sizeData) >= 0 && sizeData > 0) { + var data = new byte[sizeData]; + Marshal.Copy(srcLinkData, data, 0, data.Length); + return data; + } + } + return null; + } + + byte[] GetSourceServerData() { + if (reader is ISymUnmanagedSourceServerModule srcSrvModule) { + var srcSrvData = IntPtr.Zero; + try { + // This method only returns source server, not source link info + if (srcSrvModule.GetSourceServerData(out int sizeData, out srcSrvData) >= 0 && sizeData > 0) { + var data = new byte[sizeData]; + Marshal.Copy(srcSrvData, data, 0, data.Length); + return data; + } + } + finally { + if (srcSrvData != IntPtr.Zero) + Marshal.FreeCoTaskMem(srcSrvData); + } + } + return null; } public override void Dispose() { @@ -95,7 +140,7 @@ void Dispose(bool disposing) { objsToKeepAlive = null; } - public bool IsValidSignature(Guid pdbId, uint stamp, uint age) { + public bool MatchesModule(Guid pdbId, uint stamp, uint age) { if (reader is ISymUnmanagedReader4 reader4) { int hr = reader4.MatchesModule(pdbId, stamp, age, out bool result); if (hr < 0) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index d1cba7d30..0b531eeba 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -70,7 +70,7 @@ public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metad return null; symReader = new SymbolReaderImpl(unmanagedReader, new object[] { pdbStream, mdImporter, comPdbStream }); - if (!symReader.IsValidSignature(pdbGuid, debugDir.TimeDateStamp, age)) + if (!symReader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age)) return null; error = false; diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriter.cs index 73a1a4049..98d68f232 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriter.cs @@ -189,6 +189,24 @@ public void Initialize(Metadata metadata) { writer.Initialize(new MDEmitter(metadata), pdbFileName, new StreamIStream(pdbStream), true); } + public unsafe void SetSourceServerData(byte[] data) { + if (data == null) + return; + if (writer is ISymUnmanagedWriter8 writer8) { + fixed (void* p = data) + writer8.SetSourceServerData(new IntPtr(p), (uint)data.Length); + } + } + + public unsafe void SetSourceLinkData(byte[] data) { + if (data == null) + return; + if (writer is ISymUnmanagedWriter8 writer8) { + fixed (void* p = data) + writer8.SetSourceLinkData(new IntPtr(p), (uint)data.Length); + } + } + public void Dispose() { Marshal.FinalReleaseComObject(writer); if (ownsStream) diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index 27d3f5d55..f35b53bd1 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; @@ -13,6 +14,7 @@ sealed class DbiDocument : SymbolDocument { Guid documentType; Guid checkSumAlgorithmId; byte[] checkSum; + byte[] sourceCode; public override string URL => url; public override Guid Language => language; @@ -20,7 +22,21 @@ sealed class DbiDocument : SymbolDocument { public override Guid DocumentType => documentType; public override Guid CheckSumAlgorithmId => checkSumAlgorithmId; public override byte[] CheckSum => checkSum; - public override PdbCustomDebugInfo[] CustomDebugInfos => Array2.Empty(); + byte[] SourceCode => sourceCode; + + public override PdbCustomDebugInfo[] CustomDebugInfos { + get { + if (customDebugInfos == null) { + var sourceCode = SourceCode; + if (sourceCode != null) + customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; + else + customDebugInfos = Array2.Empty(); + } + return customDebugInfos; + } + } + PdbCustomDebugInfo[] customDebugInfos; public DbiDocument(string url) { this.url = url; @@ -33,12 +49,11 @@ public void Read(ref DataReader reader) { languageVendor = reader.ReadGuid(); documentType = reader.ReadGuid(); checkSumAlgorithmId = reader.ReadGuid(); - - var len = reader.ReadInt32(); - if (reader.ReadUInt32() != 0) - throw new PdbException("Unexpected value"); - - checkSum = reader.ReadBytes(len); + int checkSumLen = reader.ReadInt32(); + int sourceLen = reader.ReadInt32(); + checkSum = reader.ReadBytes(checkSumLen); + sourceCode = sourceLen == 0 ? null : reader.ReadBytes(sourceLen); + Debug.Assert(reader.BytesLeft == 0); } } } diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 2468b7d74..0a9d765d8 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -28,6 +28,8 @@ sealed class PdbReader : SymbolReader { Dictionary documents; Dictionary functions; + byte[] sourcelinkData; + byte[] srcsrvData; uint entryPt; public override PdbFileKind PdbFileKind => PdbFileKind.WindowsPDB; @@ -35,7 +37,7 @@ sealed class PdbReader : SymbolReader { uint Age { get; set; } Guid Guid { get; set; } - internal bool IsValidSignature => expectedGuid == Guid && expectedAge == Age; + internal bool MatchesModule => expectedGuid == Guid && expectedAge == Age; readonly Guid expectedGuid; readonly uint expectedAge; @@ -104,7 +106,7 @@ void ReadInternal(ref DataReader reader) { ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); ReadNames(); - if (!IsValidSignature) + if (!MatchesModule) return; ReadStringTable(); var tokenMapStream = ReadModules(); @@ -125,6 +127,17 @@ void ReadInternal(ref DataReader reader) { functions.Add(func.Token, func); } } + + sourcelinkData = TryGetRawFileData("sourcelink"); + srcsrvData = TryGetRawFileData("srcsrv"); + } + + byte[] TryGetRawFileData(string name) { + if (!names.TryGetValue(name, out uint streamId)) + return null; + if (streamId > ushort.MaxValue || !IsValidStreamIndex((ushort)streamId)) + return null; + return streams[streamId].Content.ToArray(); } bool IsValidStreamIndex(ushort index) => index != STREAM_INVALID_INDEX && index < streams.Length; @@ -336,6 +349,15 @@ internal void GetCustomDebugInfos(DbiFunction symMethod, MethodDef method, CilBo } public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { + if (token == 0x00000001) + GetCustomDebugInfos_ModuleDef(result); + } + + void GetCustomDebugInfos_ModuleDef(IList result) { + if (sourcelinkData != null) + result.Add(new PdbSourceLinkCustomDebugInfo(sourcelinkData)); + if (srcsrvData != null) + result.Add(new PdbSourceServerCustomDebugInfo(srcsrvData)); } } } diff --git a/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs index 4f0ea1ef5..49d26727b 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs @@ -27,7 +27,7 @@ public static SymbolReader Create(PdbReaderContext pdbContext, DataReaderFactory var pdbReader = new PdbReader(pdbGuid, age); pdbReader.Read(pdbStream.CreateReader()); - if (pdbReader.IsValidSignature) + if (pdbReader.MatchesModule) return pdbReader; return null; } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 0e755c7cf..3d8c71c78 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -87,6 +87,11 @@ public enum PdbCustomDebugInfoKind { /// SourceLink, + /// + /// + /// + SourceServer, + /// /// /// @@ -799,7 +804,7 @@ public sealed class PdbSourceLinkCustomDebugInfo : PdbCustomDebugInfo { /// /// Gets the source link file contents /// - public byte[] SourceLinkBlob { get; set; } + public byte[] FileBlob { get; set; } /// /// Constructor @@ -810,8 +815,40 @@ public PdbSourceLinkCustomDebugInfo() { /// /// Constructor /// - /// Source link file contents - public PdbSourceLinkCustomDebugInfo(byte[] sourceLinkBlob) => SourceLinkBlob = sourceLinkBlob; + /// Source link file contents + public PdbSourceLinkCustomDebugInfo(byte[] fileBlob) => FileBlob = fileBlob; + } + + /// + /// Contains the source server file + /// + public sealed class PdbSourceServerCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.SourceServer; + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid => Guid.Empty; + + /// + /// Gets the source server file contents + /// + public byte[] FileBlob { get; set; } + + /// + /// Constructor + /// + public PdbSourceServerCustomDebugInfo() { + } + + /// + /// Constructor + /// + /// Source server file contents + public PdbSourceServerCustomDebugInfo(byte[] fileBlob) => FileBlob = fileBlob; } /// diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index 0e733580a..fb2ce43bc 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -51,7 +51,7 @@ public sealed class PdbDocument : IHasCustomDebugInformation { /// Gets all custom debug infos /// public IList CustomDebugInfos => customDebugInfos; - readonly IList customDebugInfos = new List(); + IList customDebugInfos; /// /// Default constructor @@ -63,15 +63,27 @@ public PdbDocument() { /// Constructor /// /// A instance - public PdbDocument(SymbolDocument symDoc) { + public PdbDocument(SymbolDocument symDoc) : this(symDoc, partial: false) { + } + + PdbDocument(SymbolDocument symDoc, bool partial) { if (symDoc == null) throw new ArgumentNullException(nameof(symDoc)); Url = symDoc.URL; + if (!partial) + Initialize(symDoc); + } + + internal static PdbDocument CreatePartialForCompare(SymbolDocument symDoc) => + new PdbDocument(symDoc, partial: true); + + internal void Initialize(SymbolDocument symDoc) { Language = symDoc.Language; LanguageVendor = symDoc.LanguageVendor; DocumentType = symDoc.DocumentType; CheckSumAlgorithmId = symDoc.CheckSumAlgorithmId; CheckSum = symDoc.CheckSum; + customDebugInfos = new List(); foreach (var cdi in symDoc.CustomDebugInfos) customDebugInfos.Add(cdi); } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 0c65deda5..90d98a98a 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -100,7 +100,7 @@ public PdbState(SymbolReader reader, ModuleDefMD module) { var documents = reader.Documents; int count = documents.Count; for (int i = 0; i < count; i++) - Add_NoLock(new PdbDocument(documents[i])); + Add_NoLock(documents[i]); } /// @@ -126,6 +126,16 @@ PdbDocument Add_NoLock(PdbDocument doc) { return doc; } + PdbDocument Add_NoLock(SymbolDocument symDoc) { + var doc = PdbDocument.CreatePartialForCompare(symDoc); + if (docDict.TryGetValue(doc, out var orig)) + return orig; + // Expensive part, can read source code etc + doc.Initialize(symDoc); + docDict.Add(doc, doc); + return doc; + } + /// /// Removes /// @@ -236,7 +246,7 @@ void AddSequencePoints(CilBody body, SymbolMethod method) { if (instr == null) continue; var seqPoint = new SequencePoint() { - Document = Add_NoLock(new PdbDocument(sp.Document)), + Document = Add_NoLock(sp.Document), StartLine = sp.Line, StartColumn = sp.Column, EndLine = sp.EndLine, diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index beb02a7cb..ea21df1f5 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -124,7 +124,7 @@ PdbCustomDebugInfo ReadDynamicLocalVariables(long recPosEnd) { return new PdbDynamicLocalVariablesCustomDebugInfo(flags); } - PdbCustomDebugInfo ReadEmbeddedSource() => new PdbEmbeddedSourceCustomDebugInfo(reader.ToArray()); + PdbCustomDebugInfo ReadEmbeddedSource() => new PdbEmbeddedSourceCustomDebugInfo(reader.ReadRemainingBytes()); PdbCustomDebugInfo ReadEncLambdaAndClosureMap(long recPosEnd) { var data = reader.ReadBytes((int)(recPosEnd - reader.Position)); @@ -136,7 +136,7 @@ PdbCustomDebugInfo ReadEncLocalSlotMap(long recPosEnd) { return new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data); } - PdbCustomDebugInfo ReadSourceLink() => new PdbSourceLinkCustomDebugInfo(reader.ToArray()); + PdbCustomDebugInfo ReadSourceLink() => new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { if (bodyOpt == null) diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 15e671768..a6ab6a5f1 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -40,6 +40,7 @@ byte[] Write(PdbCustomDebugInfo cdi) { case PdbCustomDebugInfoKind.DynamicLocals: case PdbCustomDebugInfoKind.TupleElementNames: case PdbCustomDebugInfoKind.IteratorMethod: + case PdbCustomDebugInfoKind.SourceServer: default: helper.Error("Unreachable code, caller should filter these out"); return null; @@ -201,7 +202,7 @@ void WriteEmbeddedSource(PdbEmbeddedSourceCustomDebugInfo cdi) { } void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { - var d = cdi.SourceLinkBlob; + var d = cdi.FileBlob; if (d == null) { helper.Error("Source link blob is null"); return; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 6c2a377ed..28f5151ec 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -26,7 +26,7 @@ public PortablePdbReader(DataReaderFactory pdbStream, PdbFileKind pdbFileKind) { pdbMetadata = MetadataFactory.CreateStandalonePortablePDB(pdbStream, true); } - internal bool CheckVersion(Guid pdbGuid, uint timestamp) { + internal bool MatchesModule(Guid pdbGuid, uint timestamp, uint age) { if (pdbMetadata.PdbStream is PdbStream pdbStream) { var pdbGuidArray = pdbStream.Id; Array.Resize(ref pdbGuidArray, 16); @@ -34,6 +34,8 @@ internal bool CheckVersion(Guid pdbGuid, uint timestamp) { return false; if (BitConverter.ToUInt32(pdbStream.Id, 16) != timestamp) return false; + if (age != 1) + return false; return true; } diff --git a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs index 81fccce88..94a18d114 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs @@ -36,7 +36,7 @@ public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFact return null; var reader = new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB); - if (!reader.CheckVersion(pdbGuid, debugDir.TimeDateStamp)) + if (!reader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age)) return null; disposePdbStream = false; return reader; diff --git a/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs index b5f478c03..ae038003d 100644 --- a/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs +++ b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs @@ -17,5 +17,7 @@ interface ISymbolWriter2 : ISymbolWriter, IDisposable { void DefineKickoffMethod(uint kickoffMethod); void DefineCatchHandlerILOffset(uint catchHandlerOffset); void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod); + void SetSourceServerData(byte[] data); + void SetSourceLinkData(byte[] data); } } diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index bbea97d62..4a2bbbd0b 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -45,10 +45,25 @@ ISymbolDocumentWriter Add(PdbDocument pdbDoc) { return docWriter; docWriter = writer.DefineDocument(pdbDoc.Url, pdbDoc.Language, pdbDoc.LanguageVendor, pdbDoc.DocumentType); docWriter.SetCheckSum(pdbDoc.CheckSumAlgorithmId, pdbDoc.CheckSum); + if (TryGetCustomDebugInfo(pdbDoc, out PdbEmbeddedSourceCustomDebugInfo sourceCdi)) + docWriter.SetSource(sourceCdi.SourceCodeBlob); pdbDocs.Add(pdbDoc, docWriter); return docWriter; } + static bool TryGetCustomDebugInfo(IHasCustomDebugInformation hci, out TCDI cdi) where TCDI : PdbCustomDebugInfo { + var cdis = hci.CustomDebugInfos; + int count = cdis.Count; + for (int i = 0; i < count; i++) { + if (cdis[i] is TCDI cdi2) { + cdi = cdi2; + return true; + } + } + cdi = null; + return false; + } + public void Write() { writer.SetUserEntryPoint(new SymbolToken(GetUserEntryPointToken())); @@ -67,6 +82,11 @@ public void Write() { Write(method, cdiBuilder); } } + + if (TryGetCustomDebugInfo(module, out PdbSourceLinkCustomDebugInfo sourceLinkCdi)) + writer.SetSourceLinkData(sourceLinkCdi.FileBlob); + if (TryGetCustomDebugInfo(module, out PdbSourceServerCustomDebugInfo sourceServerCdi)) + writer.SetSourceServerData(sourceServerCdi.FileBlob); } bool ShouldAddMethod(MethodDef method) { diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index d4ec797b2..e640134ae 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3255,6 +3255,7 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, case PdbCustomDebugInfoKind.StateMachineTypeName: case PdbCustomDebugInfoKind.DynamicLocals: case PdbCustomDebugInfoKind.TupleElementNames: + case PdbCustomDebugInfoKind.SourceServer: // These are Windows PDB CDIs Error("Unsupported custom debug info {0}", cdi.Kind); break; From b8cf2bf67799a4f3bec26aa62d8c4986a909b49a Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 3 Apr 2018 20:47:08 +0200 Subject: [PATCH 194/511] Rename --- src/DotNet/Writer/ChunkListBase.cs | 2 +- src/DotNet/Writer/DebugDirectory.cs | 2 +- src/DotNet/Writer/Extensions.cs | 14 +++++++------- src/DotNet/Writer/HeapBase.cs | 2 +- src/DotNet/Writer/ImportDirectory.cs | 2 +- src/DotNet/Writer/ManagedExportsWriter.cs | 17 ++++------------- src/DotNet/Writer/Metadata.cs | 2 +- src/DotNet/Writer/MetadataHeader.cs | 4 ++-- src/DotNet/Writer/MethodBody.cs | 2 +- src/DotNet/Writer/MethodBodyChunks.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 2 +- src/DotNet/Writer/NetResources.cs | 2 +- src/DotNet/Writer/StrongNameSignature.cs | 2 +- src/DotNet/Writer/TablesHeap.cs | 2 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 8 ++++---- 15 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index e3fbc1cf5..321809ac2 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -109,7 +109,7 @@ public void WriteTo(DataWriter writer) { if (elem.chunk.GetVirtualSize() == 0) continue; int paddingF = (int)offset2.AlignUp(elem.alignment) - (int)offset2; - writer.WriteZeros(paddingF); + writer.WriteZeroes(paddingF); elem.chunk.VerifyWriteTo(writer); offset2 += (uint)paddingF + elem.chunk.GetFileLength(); } diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index 9cb5128df..3d62d6582 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -165,7 +165,7 @@ public void WriteTo(DataWriter writer) { static void WriteAlign(DataWriter writer, ref uint offs) { uint align = Utils.AlignUp(offs, DEFAULT_DEBUGDIRECTORY_ALIGNMENT) - offs; offs += align; - writer.WriteZeros((int)align); + writer.WriteZeroes((int)align); } } } diff --git a/src/DotNet/Writer/Extensions.cs b/src/DotNet/Writer/Extensions.cs index 0723f1420..d28bc84c6 100644 --- a/src/DotNet/Writer/Extensions.cs +++ b/src/DotNet/Writer/Extensions.cs @@ -4,19 +4,19 @@ namespace dnlib.DotNet.Writer { /// /// Extension methods /// - public static partial class Extensions { + static partial class Extensions { /// /// Write zeros /// /// this /// Number of zeros - public static void WriteZeros(this DataWriter writer, int count) { - if (count <= 0x20) { - for (int i = 0; i < count; i++) - writer.WriteByte(0); + public static void WriteZeroes(this DataWriter writer, int count) { + while (count >= 8) { + writer.WriteUInt64(0); + count -= 8; } - else - writer.WriteBytes(new byte[count]); + for (int i = 0; i < count; i++) + writer.WriteByte(0); } } } diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index 3d6903da7..99831e387 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -60,7 +60,7 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { /// public void WriteTo(DataWriter writer) { WriteToImpl(writer); - writer.WriteZeros((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength())); + writer.WriteZeroes((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength())); } /// diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index fe22b990d..63dbdbf95 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -109,7 +109,7 @@ public void WriteTo(DataWriter writer) { writer.WriteInt32(0); } - writer.WriteZeros(stringsPadding); + writer.WriteZeroes(stringsPadding); writer.WriteUInt16(0); writer.WriteBytes(Encoding.UTF8.GetBytes(IsExeFile ? "_CorExeMain\0" : "_CorDllMain\0")); writer.WriteBytes(Encoding.UTF8.GetBytes("mscoree.dll\0")); diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 2293df148..8fc8bdf63 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -405,11 +405,11 @@ void WriteSdataBlob(uint timestamp) { writer.WriteUInt32(0); // AddressOfNameOrdinals sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.Position; - WriteZeroes(writer, funcSize * 4); + writer.WriteZeroes(funcSize * 4); sdataBytesInfo.addressOfNamesStreamOffset = (uint)writer.Position; - WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 4); + writer.WriteZeroes(sdataBytesInfo.MethodNameOffsets.Length * 4); sdataBytesInfo.addressOfNameOrdinalsStreamOffset = (uint)writer.Position; - WriteZeroes(writer, sdataBytesInfo.MethodNameOffsets.Length * 2); + writer.WriteZeroes(sdataBytesInfo.MethodNameOffsets.Length * 2); sdataBytesInfo.namesBlobStreamOffset = (uint)writer.Position; namesBlob.Write(writer); @@ -469,15 +469,6 @@ void PatchSdataBytesBlob() { } } - static void WriteZeroes(DataWriter writer, int count) { - while (count >= 8) { - writer.WriteUInt64(0); - count -= 8; - } - for (int i = 0; i < count; i++) - writer.WriteByte(0); - } - void WriteVtableFixups(DataWriter writer) { if (vtables.Count == 0) return; @@ -514,7 +505,7 @@ void WriteStubs(DataWriter writer) { if (pos + stubSize != writer.Position) throw new InvalidOperationException(); if (zeroes != 0) - WriteZeroes(writer, zeroes); + writer.WriteZeroes(zeroes); expectedOffset = (currentOffset + stubSize + stubAlignment - 1) & ~(stubAlignment - 1); } if (expectedOffset != stubsChunk.length) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index e640134ae..140141536 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3653,7 +3653,7 @@ public void WriteTo(DataWriter writer) { rva2 += metadataHeader.GetFileLength(); foreach (var heap in metadataHeader.Heaps) { - writer.WriteZeros((int)(rva2.AlignUp(HEAP_ALIGNMENT) - rva2)); + writer.WriteZeroes((int)(rva2.AlignUp(HEAP_ALIGNMENT) - rva2)); rva2 = rva2.AlignUp(HEAP_ALIGNMENT); heap.VerifyWriteTo(writer); rva2 += heap.GetFileLength(); diff --git a/src/DotNet/Writer/MetadataHeader.cs b/src/DotNet/Writer/MetadataHeader.cs index 7ad35a0cc..aabcd7372 100644 --- a/src/DotNet/Writer/MetadataHeader.cs +++ b/src/DotNet/Writer/MetadataHeader.cs @@ -144,7 +144,7 @@ public void WriteTo(DataWriter writer) { var s = GetVersionString(); writer.WriteInt32(Utils.AlignUp(s.Length, 4)); writer.WriteBytes(s); - writer.WriteZeros(Utils.AlignUp(s.Length, 4) - s.Length); + writer.WriteZeroes(Utils.AlignUp(s.Length, 4) - s.Length); writer.WriteByte((byte)(options.StorageFlags ?? 0)); writer.WriteByte(options.Reserved2 ?? 0); var heaps = this.heaps; @@ -157,7 +157,7 @@ public void WriteTo(DataWriter writer) { writer.WriteBytes(s = GetAsciizName(heap.Name)); if (s.Length > 32) throw new ModuleWriterException($"Heap name '{heap.Name}' is > 32 bytes"); - writer.WriteZeros(Utils.AlignUp(s.Length, 4) - s.Length); + writer.WriteZeroes(Utils.AlignUp(s.Length, 4) - s.Length); } } diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 2b74dfd9f..35fb31ae3 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -137,7 +137,7 @@ public void WriteTo(DataWriter writer) { writer.WriteBytes(code); if (HasExtraSections) { var rva2 = rva + (uint)code.Length; - writer.WriteZeros((int)rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT) - (int)rva2); + writer.WriteZeroes((int)rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT) - (int)rva2); writer.WriteBytes(extraSections); } } diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index 3b30f0e6e..2abc7a91a 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -167,7 +167,7 @@ public void WriteTo(DataWriter writer) { foreach (var mb in fatMethods) { if (alignFatBodies) { int padding = (int)rva2.AlignUp(FAT_BODY_ALIGNMENT) - (int)rva2; - writer.WriteZeros(padding); + writer.WriteZeroes(padding); rva2 += (uint)padding; } mb.VerifyWriteTo(writer); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 7a664f131..5d4edc8ca 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -809,7 +809,7 @@ protected void WriteChunks(DataWriter writer, List chunks, FileOffset of if (chunk.GetVirtualSize() != 0) { offset += chunk.GetFileLength(); var newOffset = offset.AlignUp(fileAlignment); - writer.WriteZeros((int)(newOffset - offset)); + writer.WriteZeroes((int)(newOffset - offset)); offset = newOffset; } } diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index a1fbb8bc0..e04a9cf6b 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -79,7 +79,7 @@ public void WriteTo(DataWriter writer) { var rva2 = rva; foreach (var resourceData in resources) { int padding = (int)rva2.AlignUp(alignment) - (int)rva2; - writer.WriteZeros(padding); + writer.WriteZeroes(padding); rva2 += (uint)padding; writer.WriteUInt32(resourceData.GetFileLength()); resourceData.VerifyWriteTo(writer); diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index 1802838bd..088f8e3ff 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -39,6 +39,6 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetVirtualSize() => GetFileLength(); /// - public void WriteTo(DataWriter writer) => writer.WriteZeros(size); + public void WriteTo(DataWriter writer) => writer.WriteZeroes(size); } } diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index b7aab5c01..9607a661d 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -452,7 +452,7 @@ public void WriteTo(DataWriter writer) { writer.Write(metadata, ImportScopeTable); writer.Write(metadata, StateMachineMethodTable); writer.Write(metadata, CustomDebugInformationTable); - writer.WriteZeros((int)(Utils.AlignUp(length, HeapBase.ALIGNMENT) - length)); + writer.WriteZeroes((int)(Utils.AlignUp(length, HeapBase.ALIGNMENT) - length)); } MDStreamFlags GetMDStreamFlags() { diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 13fa02cd3..5f8e571e8 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -361,7 +361,7 @@ public void WriteTo(DataWriter writer) { foreach (var dir in dirList) { uint padding = Utils.AlignUp(offset, RESOURCE_DIR_ALIGNMENT) - offset; - writer.WriteZeros((int)padding); + writer.WriteZeroes((int)padding); offset += padding; if (dirDict[dir] != offset) throw new ModuleWriterException("Invalid Win32 resource directory offset"); @@ -370,7 +370,7 @@ public void WriteTo(DataWriter writer) { foreach (var dataHeader in dataHeaderList) { uint padding = Utils.AlignUp(offset, RESOURCE_DATA_HEADER_ALIGNMENT) - offset; - writer.WriteZeros((int)padding); + writer.WriteZeroes((int)padding); offset += padding; if (dataHeaderDict[dataHeader] != offset) throw new ModuleWriterException("Invalid Win32 resource data header offset"); @@ -379,7 +379,7 @@ public void WriteTo(DataWriter writer) { foreach (var s in stringsList) { uint padding = Utils.AlignUp(offset, RESOURCE_STRING_ALIGNMENT) - offset; - writer.WriteZeros((int)padding); + writer.WriteZeroes((int)padding); offset += padding; if (stringsDict[s] != offset) throw new ModuleWriterException("Invalid Win32 resource string offset"); @@ -395,7 +395,7 @@ public void WriteTo(DataWriter writer) { var dataBuffer = new byte[0x2000]; foreach (var data in dataList) { uint padding = Utils.AlignUp(offset, RESOURCE_DATA_ALIGNMENT) - offset; - writer.WriteZeros((int)padding); + writer.WriteZeroes((int)padding); offset += padding; if (dataDict[data] != offset) throw new ModuleWriterException("Invalid Win32 resource data offset"); From 9dc1d09bfcc5b6ad743f182cbb35a6880a99486c Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 3 Apr 2018 20:47:16 +0200 Subject: [PATCH 195/511] Use PDB filename stored in CV debug dir data --- src/DotNet/Pdb/PdbReaderContext.cs | 8 ++++++-- src/DotNet/Pdb/SymbolReaderFactory.cs | 26 ++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs index c5bef1f7b..891154cd4 100644 --- a/src/DotNet/Pdb/PdbReaderContext.cs +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -33,9 +33,12 @@ static ImageDebugDirectory TryGetDebugDirectoryEntry(IPEImage peImage, ImageDebu return null; } - public bool TryGetCodeViewData(out Guid guid, out uint age) { + public bool TryGetCodeViewData(out Guid guid, out uint age) => TryGetCodeViewData(out guid, out age, out _); + + public bool TryGetCodeViewData(out Guid guid, out uint age, out string pdbFilename) { guid = Guid.Empty; age = 0; + pdbFilename = null; var reader = GetCodeViewDataReader(); // magic, guid, age, zero-terminated string if (reader.Length < 4 + 16 + 4 + 1) @@ -44,7 +47,8 @@ public bool TryGetCodeViewData(out Guid guid, out uint age) { return false; guid = reader.ReadGuid(); age = reader.ReadUInt32(); - return true; + pdbFilename = reader.TryReadZeroTerminatedUtf8String(); + return pdbFilename != null; } DataReader GetCodeViewDataReader() { diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index 78bec4d59..ccf314426 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -8,8 +8,30 @@ namespace dnlib.DotNet.Pdb { static class SymbolReaderFactory { - public static SymbolReader CreateFromAssemblyFile(PdbReaderOptions options, Metadata metadata, string assemblyFileName) => - Create(options, metadata, Path.ChangeExtension(assemblyFileName, "pdb")); + public static SymbolReader CreateFromAssemblyFile(PdbReaderOptions options, Metadata metadata, string assemblyFileName) { + var pdbContext = new PdbReaderContext(metadata.PEImage, options); + if (!pdbContext.HasDebugInfo) + return null; + if (!pdbContext.TryGetCodeViewData(out var guid, out uint age, out var pdbWindowsFilename)) + return null; + + string pdbFilename; + int index = pdbWindowsFilename.LastIndexOfAny(windowsPathSepChars); + if (index >= 0) + pdbFilename = pdbWindowsFilename.Substring(index + 1); + else + pdbFilename = pdbWindowsFilename; + + var fileToCheck = Path.Combine(Path.GetDirectoryName(assemblyFileName), pdbFilename); + if (!File.Exists(fileToCheck)) { + var ext = Path.GetExtension(pdbFilename); + if (string.IsNullOrEmpty(ext)) + ext = "pdb"; + fileToCheck = Path.ChangeExtension(assemblyFileName, ext); + } + return Create(options, metadata, fileToCheck); + } + static readonly char[] windowsPathSepChars = new char[] { '\\', '/' }; public static SymbolReader Create(PdbReaderOptions options, Metadata metadata, string pdbFileName) { var pdbContext = new PdbReaderContext(metadata.PEImage, options); From 3e2c81b71497981422cbb062c4cb76c3f31de8d7 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 4 Apr 2018 19:22:26 +0200 Subject: [PATCH 196/511] Rename --- src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs | 4 ++-- src/DotNet/Pdb/Dss/{SymbolWriter.cs => SymbolWriterImpl.cs} | 4 ++-- src/dnlib.csproj | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/DotNet/Pdb/Dss/{SymbolWriter.cs => SymbolWriterImpl.cs} (98%) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 0b531eeba..00823bfa6 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -185,10 +185,10 @@ static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) public static ISymbolWriter2 Create(PdbWriterOptions options, string pdbFileName) { if (File.Exists(pdbFileName)) File.Delete(pdbFileName); - return new SymbolWriter(CreateSymUnmanagedWriter2(options), pdbFileName, File.Create(pdbFileName), options, ownsStream: true); + return new SymbolWriterImpl(CreateSymUnmanagedWriter2(options), pdbFileName, File.Create(pdbFileName), options, ownsStream: true); } public static ISymbolWriter2 Create(PdbWriterOptions options, Stream pdbStream, string pdbFileName) => - new SymbolWriter(CreateSymUnmanagedWriter2(options), pdbFileName, pdbStream, options, ownsStream: false); + new SymbolWriterImpl(CreateSymUnmanagedWriter2(options), pdbFileName, pdbStream, options, ownsStream: false); } } diff --git a/src/DotNet/Pdb/Dss/SymbolWriter.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs similarity index 98% rename from src/DotNet/Pdb/Dss/SymbolWriter.cs rename to src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index 98d68f232..7037469bb 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -10,7 +10,7 @@ using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolWriter : ISymbolWriter2 { + sealed class SymbolWriterImpl : ISymbolWriter2 { readonly ISymUnmanagedWriter2 writer; readonly ISymUnmanagedAsyncMethodPropertiesWriter asyncMethodWriter; readonly string pdbFileName; @@ -22,7 +22,7 @@ sealed class SymbolWriter : ISymbolWriter2 { public bool IsDeterministic => isDeterministic; public bool SupportsAsyncMethods => asyncMethodWriter != null; - public SymbolWriter(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream, PdbWriterOptions options, bool ownsStream) { + public SymbolWriterImpl(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream, PdbWriterOptions options, bool ownsStream) { this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; this.pdbStream = pdbStream ?? throw new ArgumentNullException(nameof(pdbStream)); diff --git a/src/dnlib.csproj b/src/dnlib.csproj index f91a6a6cd..4dbbbc157 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -241,7 +241,7 @@ - + From 8ee5e3dc656b36de227a3bd9cb890630bc8545ea Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 4 Apr 2018 19:22:36 +0200 Subject: [PATCH 197/511] Turn iface into an abstract class --- .../Pdb/Dss/SymbolReaderWriterFactory.cs | 4 +- src/DotNet/Pdb/Dss/SymbolWriterImpl.cs | 96 +++++-------------- src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs | 23 ----- src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs | 36 +++++++ src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 20 ++-- src/DotNet/Writer/ModuleWriterBase.cs | 2 +- src/dnlib.csproj | 2 +- 7 files changed, 73 insertions(+), 110 deletions(-) delete mode 100644 src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs create mode 100644 src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 00823bfa6..138e8a117 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -182,13 +182,13 @@ static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) return null; } - public static ISymbolWriter2 Create(PdbWriterOptions options, string pdbFileName) { + public static SymbolWriter Create(PdbWriterOptions options, string pdbFileName) { if (File.Exists(pdbFileName)) File.Delete(pdbFileName); return new SymbolWriterImpl(CreateSymUnmanagedWriter2(options), pdbFileName, File.Create(pdbFileName), options, ownsStream: true); } - public static ISymbolWriter2 Create(PdbWriterOptions options, Stream pdbStream, string pdbFileName) => + public static SymbolWriter Create(PdbWriterOptions options, Stream pdbStream, string pdbFileName) => new SymbolWriterImpl(CreateSymUnmanagedWriter2(options), pdbFileName, pdbStream, options, ownsStream: false); } } diff --git a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index 7037469bb..06723ab01 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -4,13 +4,12 @@ using System.Diagnostics; using System.Diagnostics.SymbolStore; using System.IO; -using System.Reflection; using System.Runtime.InteropServices; using dnlib.DotNet.Pdb.WindowsPdb; using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolWriterImpl : ISymbolWriter2 { + sealed class SymbolWriterImpl : SymbolWriter { readonly ISymUnmanagedWriter2 writer; readonly ISymUnmanagedAsyncMethodPropertiesWriter asyncMethodWriter; readonly string pdbFileName; @@ -19,8 +18,8 @@ sealed class SymbolWriterImpl : ISymbolWriter2 { readonly bool isDeterministic; bool closeCalled; - public bool IsDeterministic => isDeterministic; - public bool SupportsAsyncMethods => asyncMethodWriter != null; + public override bool IsDeterministic => isDeterministic; + public override bool SupportsAsyncMethods => asyncMethodWriter != null; public SymbolWriterImpl(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream, PdbWriterOptions options, bool ownsStream) { this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); @@ -33,20 +32,17 @@ public SymbolWriterImpl(ISymUnmanagedWriter2 writer, string pdbFileName, Stream isDeterministic = (options & PdbWriterOptions.Deterministic) != 0 && writer is ISymUnmanagedWriter7; } - public void Abort() => writer.Abort(); - - public void Close() { + public override void Close() { if (closeCalled) return; closeCalled = true; writer.Close(); } - public void CloseMethod() => writer.CloseMethod(); - public void CloseNamespace() => writer.CloseNamespace(); - public void CloseScope(int endOffset) => writer.CloseScope((uint)endOffset); + public override void CloseMethod() => writer.CloseMethod(); + public override void CloseScope(int endOffset) => writer.CloseScope((uint)endOffset); - public void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod) { + public override void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod) { if (asyncMethodWriter == null) throw new InvalidOperationException(); if (yieldOffsets.Length != breakpointOffset.Length || yieldOffsets.Length != breakpointMethod.Length) @@ -54,90 +50,44 @@ public void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, ui asyncMethodWriter.DefineAsyncStepInfo((uint)yieldOffsets.Length, yieldOffsets, breakpointOffset, breakpointMethod); } - public void DefineCatchHandlerILOffset(uint catchHandlerOffset) { + public override void DefineCatchHandlerILOffset(uint catchHandlerOffset) { if (asyncMethodWriter == null) throw new InvalidOperationException(); asyncMethodWriter.DefineCatchHandlerILOffset(catchHandlerOffset); } - public void DefineConstant(string name, object value, byte[] signature) => writer.DefineConstant(name, value, (uint)signature.Length, signature); - public void DefineConstant2(string name, object value, uint sigToken) => writer.DefineConstant2(name, value, sigToken); + public override void DefineConstant(string name, object value, uint sigToken) => writer.DefineConstant2(name, value, sigToken); - public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { + public override ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out var unDocWriter); return unDocWriter == null ? null : new SymbolDocumentWriter(unDocWriter); } - public void DefineField(SymbolToken parent, string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) => - writer.DefineField((uint)parent.GetToken(), name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); - - public void DefineGlobalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) => - writer.DefineGlobalVariable(name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); - - public void DefineGlobalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3) => - writer.DefineGlobalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3); - - public void DefineKickoffMethod(uint kickoffMethod) { + public override void DefineKickoffMethod(uint kickoffMethod) { if (asyncMethodWriter == null) throw new InvalidOperationException(); asyncMethodWriter.DefineKickoffMethod(kickoffMethod); } - public void DefineLocalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) => - writer.DefineLocalVariable(name, (uint)attributes, (uint)signature.Length, signature, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3, (uint)startOffset, (uint)endOffset); - - public void DefineParameter(string name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3) => - writer.DefineParameter(name, (uint)attributes, (uint)sequence, (uint)addrKind, (uint)addr1, (uint)addr2, (uint)addr3); - - public void DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) { - var doc = document as SymbolDocumentWriter; - if (doc == null) - throw new ArgumentException("document isn't a non-null SymbolDocumentWriter instance"); - if (offsets == null || lines == null || columns == null || - endLines == null || endColumns == null || - offsets.Length != lines.Length || - offsets.Length != columns.Length || - offsets.Length != endLines.Length || - offsets.Length != endColumns.Length) - throw new ArgumentException("Invalid arrays"); - writer.DefineSequencePoints(doc.SymUnmanagedDocumentWriter, (uint)offsets.Length, offsets, lines, columns, endLines, endColumns); - } - - public void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) { + public override void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) { var doc = document as SymbolDocumentWriter; if (doc == null) throw new ArgumentException("document isn't a non-null SymbolDocumentWriter instance"); writer.DefineSequencePoints(doc.SymUnmanagedDocumentWriter, arraySize, offsets, lines, columns, endLines, endColumns); } - public void Initialize(IntPtr emitter, string filename, bool fFullBuild) => writer.Initialize(emitter, filename, null, fFullBuild); - public void OpenMethod(SymbolToken method) => writer.OpenMethod((uint)method.GetToken()); - public void OpenNamespace(string name) => writer.OpenNamespace(name); + public override void OpenMethod(MDToken method) => writer.OpenMethod(method.Raw); - public int OpenScope(int startOffset) { + public override int OpenScope(int startOffset) { writer.OpenScope((uint)startOffset, out uint result); return (int)result; } - public void RemapToken(uint oldToken, uint newToken) => writer.RemapToken(oldToken, newToken); - - public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn) { - var sdoc = startDoc as SymbolDocumentWriter; - if (sdoc == null) - throw new ArgumentException("startDoc isn't a non-null SymbolDocumentWriter instance"); - var edoc = endDoc as SymbolDocumentWriter; - if (edoc == null) - throw new ArgumentException("endDoc isn't a non-null SymbolDocumentWriter instance"); - writer.SetMethodSourceRange(sdoc.SymUnmanagedDocumentWriter, (uint)startLine, (uint)startColumn, edoc.SymUnmanagedDocumentWriter, (uint)endLine, (uint)endColumn); - } - - public void SetScopeRange(int scopeID, int startOffset, int endOffset) => writer.SetScopeRange((uint)scopeID, (uint)startOffset, (uint)endOffset); - public void SetSymAttribute(SymbolToken parent, string name, byte[] data) => writer.SetSymAttribute((uint)parent.GetToken(), name, (uint)data.Length, data); - public void SetUnderlyingWriter(IntPtr underlyingWriter) => throw new NotSupportedException(); - public void SetUserEntryPoint(SymbolToken entryMethod) => writer.SetUserEntryPoint((uint)entryMethod.GetToken()); - public void UsingNamespace(string fullName) => writer.UsingNamespace(fullName); + public override void SetSymAttribute(MDToken parent, string name, byte[] data) => writer.SetSymAttribute(parent.Raw, name, (uint)data.Length, data); + public override void SetUserEntryPoint(MDToken entryMethod) => writer.SetUserEntryPoint(entryMethod.Raw); + public override void UsingNamespace(string fullName) => writer.UsingNamespace(fullName); - public unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData) { + public override unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData) { pIDD = default; codeViewData = null; @@ -179,17 +129,17 @@ public unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint return false; } - public void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset) => + public override void DefineLocalVariable(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset) => writer.DefineLocalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3, startOffset, endOffset); - public void Initialize(Metadata metadata) { + public override void Initialize(Metadata metadata) { if (isDeterministic) ((ISymUnmanagedWriter6)writer).InitializeDeterministic(new MDEmitter(metadata), new StreamIStream(pdbStream)); else writer.Initialize(new MDEmitter(metadata), pdbFileName, new StreamIStream(pdbStream), true); } - public unsafe void SetSourceServerData(byte[] data) { + public override unsafe void SetSourceServerData(byte[] data) { if (data == null) return; if (writer is ISymUnmanagedWriter8 writer8) { @@ -198,7 +148,7 @@ public unsafe void SetSourceServerData(byte[] data) { } } - public unsafe void SetSourceLinkData(byte[] data) { + public override unsafe void SetSourceLinkData(byte[] data) { if (data == null) return; if (writer is ISymUnmanagedWriter8 writer8) { @@ -207,7 +157,7 @@ public unsafe void SetSourceLinkData(byte[] data) { } } - public void Dispose() { + public override void Dispose() { Marshal.FinalReleaseComObject(writer); if (ownsStream) pdbStream.Dispose(); diff --git a/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs b/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs deleted file mode 100644 index ae038003d..000000000 --- a/src/DotNet/Pdb/WindowsPdb/ISymbolWriter2.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics.SymbolStore; -using dnlib.DotNet.Writer; - -namespace dnlib.DotNet.Pdb.WindowsPdb { - interface ISymbolWriter2 : ISymbolWriter, IDisposable { - bool IsDeterministic { get; } - bool SupportsAsyncMethods { get; } - - void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns); - bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData); - void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset); - void Initialize(Metadata metadata); - void DefineConstant2(string name, object value, uint sigToken); - void DefineKickoffMethod(uint kickoffMethod); - void DefineCatchHandlerILOffset(uint catchHandlerOffset); - void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod); - void SetSourceServerData(byte[] data); - void SetSourceLinkData(byte[] data); - } -} diff --git a/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs b/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs new file mode 100644 index 000000000..44864e75a --- /dev/null +++ b/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs @@ -0,0 +1,36 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Diagnostics.SymbolStore; +using dnlib.DotNet.Writer; + +namespace dnlib.DotNet.Pdb.WindowsPdb { + abstract class SymbolWriter : IDisposable { + public abstract bool IsDeterministic { get; } + public abstract bool SupportsAsyncMethods { get; } + + public abstract void Initialize(Metadata metadata); + public abstract void Close(); + public abstract bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData); + + public abstract void SetUserEntryPoint(MDToken entryMethod); + public abstract ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType); + public abstract void SetSourceServerData(byte[] data); + public abstract void SetSourceLinkData(byte[] data); + + public abstract void OpenMethod(MDToken method); + public abstract void CloseMethod(); + public abstract int OpenScope(int startOffset); + public abstract void CloseScope(int endOffset); + public abstract void SetSymAttribute(MDToken parent, string name, byte[] data); + public abstract void UsingNamespace(string fullName); + public abstract void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns); + public abstract void DefineLocalVariable(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset); + public abstract void DefineConstant(string name, object value, uint sigToken); + public abstract void DefineKickoffMethod(uint kickoffMethod); + public abstract void DefineCatchHandlerILOffset(uint catchHandlerOffset); + public abstract void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod); + + public abstract void Dispose(); + } +} diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 4a2bbbd0b..eb8c44b7c 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.Pdb.WindowsPdb { sealed class WindowsPdbWriter : IDisposable { - ISymbolWriter2 writer; + SymbolWriter writer; readonly PdbState pdbState; readonly ModuleDef module; readonly Metadata metadata; @@ -21,7 +21,7 @@ sealed class WindowsPdbWriter : IDisposable { public ILogger Logger { get; set; } - public WindowsPdbWriter(ISymbolWriter2 writer, PdbState pdbState, Metadata metadata) + public WindowsPdbWriter(SymbolWriter writer, PdbState pdbState, Metadata metadata) : this(pdbState, metadata) { if (pdbState == null) throw new ArgumentNullException(nameof(pdbState)); @@ -65,7 +65,7 @@ static bool TryGetCustomDebugInfo(IHasCustomDebugInformation hci, out TCDI } public void Write() { - writer.SetUserEntryPoint(new SymbolToken(GetUserEntryPointToken())); + writer.SetUserEntryPoint(GetUserEntryPointToken()); var cdiBuilder = new List(); foreach (var type in module.GetTypes()) { @@ -217,7 +217,7 @@ void Write(MethodDef method, List cdiBuilder) { var info = new CurrentMethod(this, method, instrToOffset); var body = method.Body; - var symbolToken = new SymbolToken((int)new MDToken(MD.Table.Method, rid).Raw); + var symbolToken = new MDToken(MD.Table.Method, rid); writer.OpenMethod(symbolToken); seqPointsHelper.Write(this, info.Method.Body.Instructions); @@ -375,7 +375,7 @@ void WriteScope(ref CurrentMethod info, PdbScope scope, int recursionCounter) { var constant = constants[i]; sig.Type = constant.Type; var token = metadata.GetToken(sig); - writer.DefineConstant2(constant.Name, constant.Value ?? boxedZeroInt32, token.Raw); + writer.DefineConstant(constant.Name, constant.Value ?? boxedZeroInt32, token.Raw); } } var scopeNamespaces = scope.Namespaces; @@ -404,7 +404,7 @@ void AddLocals(MethodDef method, IList locals, uint startOffset, uint uint attrs = GetPdbLocalFlags(local.Attributes); if (attrs == 0 && local.Name == null) continue; - writer.DefineLocalVariable2(local.Name ?? string.Empty, attrs, + writer.DefineLocalVariable(local.Name ?? string.Empty, attrs, token, 1, (uint)local.Index, 0, 0, startOffset, endOffset); } } @@ -415,16 +415,16 @@ static uint GetPdbLocalFlags(PdbLocalAttributes attributes) { return 0; } - int GetUserEntryPointToken() { + MDToken GetUserEntryPointToken() { var ep = pdbState.UserEntryPoint; if (ep == null) - return 0; + return default; uint rid = metadata.GetRid(ep); if (rid == 0) { Error("PDB user entry point method {0} ({1:X8}) is not defined in this module ({2})", ep, ep.MDToken.Raw, module); - return 0; + return default; } - return new MDToken(MD.Table.Method, rid).ToInt32(); + return new MDToken(MD.Table.Method, rid); } public bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY idd, out byte[] codeViewData) => diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 5d4edc8ca..7914a8045 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -940,7 +940,7 @@ protected uint GetTimeDateStamp() { return (uint)TheOptions.PEHeadersOptions.TimeDateStamp; } - ISymbolWriter2 GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbFilename) { + SymbolWriter GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbFilename) { if (TheOptions.PdbStream != null) { return Pdb.Dss.SymbolReaderWriterFactory.Create(options, TheOptions.PdbStream, pdbFilename = TheOptions.PdbFileName ?? diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 4dbbbc157..aab97db15 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -223,10 +223,10 @@ - + From 67f42ac6af2b532b07bbc77f4892bddd3485757e Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 4 Apr 2018 19:22:44 +0200 Subject: [PATCH 198/511] Create srcsrv / source link CDI even if empty --- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 1971ea1f0..33155ff80 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -94,8 +94,10 @@ byte[] GetSourceLinkData() { if (reader is ISymUnmanagedReader4 reader4) { // It returns data that it owns. The data is freed once its Destroy() method is called Debug.Assert(reader is ISymUnmanagedDispose); - // Despite its name, it seems to only return source link, and not source server info - if (reader4.GetSourceServerData(out var srcLinkData, out int sizeData) >= 0 && sizeData > 0) { + // Despite its name, it seems to only return source link data, and not source server data + if (reader4.GetSourceServerData(out var srcLinkData, out int sizeData) == 0) { + if (sizeData == 0) + return Array2.Empty(); var data = new byte[sizeData]; Marshal.Copy(srcLinkData, data, 0, data.Length); return data; @@ -108,8 +110,10 @@ byte[] GetSourceServerData() { if (reader is ISymUnmanagedSourceServerModule srcSrvModule) { var srcSrvData = IntPtr.Zero; try { - // This method only returns source server, not source link info - if (srcSrvModule.GetSourceServerData(out int sizeData, out srcSrvData) >= 0 && sizeData > 0) { + // This method only returns source server data, not source link data + if (srcSrvModule.GetSourceServerData(out int sizeData, out srcSrvData) == 0) { + if (sizeData == 0) + return Array2.Empty(); var data = new byte[sizeData]; Marshal.Copy(srcSrvData, data, 0, data.Length); return data; From c46f25c6e982726c5076b0186d39f34370075265 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 4 Apr 2018 19:22:54 +0200 Subject: [PATCH 199/511] Call the same PDB reader factory method --- src/DotNet/ModuleDefMD.cs | 16 ++++------------ src/DotNet/Pdb/SymbolReaderFactory.cs | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 87ebfdd77..9e82c2eb2 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -404,12 +404,8 @@ SymbolReader CreateSymbolReader(ModuleCreationOptions options) { return SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbStream); } - if (options.TryToLoadPdbFromDisk) { - if (!string.IsNullOrEmpty(location)) - return SymbolReaderFactory.CreateFromAssemblyFile(options.PdbOptions, metadata, location); - else - return SymbolReaderFactory.TryCreateEmbeddedPdbReader(options.PdbOptions, metadata); - } + if (options.TryToLoadPdbFromDisk) + return SymbolReaderFactory.CreateFromAssemblyFile(options.PdbOptions, metadata, location ?? string.Empty); return null; } @@ -484,12 +480,8 @@ public void LoadPdb() => /// Loads symbols if a PDB file is available /// /// PDB reader options - public void LoadPdb(PdbReaderOptions options) { - var loc = location; - if (string.IsNullOrEmpty(loc)) - return; - LoadPdb(SymbolReaderFactory.Create(options, metadata, loc)); - } + public void LoadPdb(PdbReaderOptions options) => + LoadPdb(SymbolReaderFactory.CreateFromAssemblyFile(options, metadata, location ?? string.Empty)); internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { var ps = pdbState; diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index ccf314426..dda74f5ff 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -22,7 +22,7 @@ public static SymbolReader CreateFromAssemblyFile(PdbReaderOptions options, Meta else pdbFilename = pdbWindowsFilename; - var fileToCheck = Path.Combine(Path.GetDirectoryName(assemblyFileName), pdbFilename); + var fileToCheck = assemblyFileName == string.Empty ? pdbFilename : Path.Combine(Path.GetDirectoryName(assemblyFileName), pdbFilename); if (!File.Exists(fileToCheck)) { var ext = Path.GetExtension(pdbFilename); if (string.IsNullOrEmpty(ext)) From eec3483a523f9579a76fc129f925bf80853b0b4b Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 4 Apr 2018 19:23:03 +0200 Subject: [PATCH 200/511] Make DotNetStream abstract, add a CustomDotNetStream class --- src/DotNet/MD/CompressedMetadata.cs | 2 +- src/DotNet/MD/CustomDotNetStream.cs | 25 +++++++++++++++++++++++++ src/DotNet/MD/DotNetStream.cs | 6 +++--- src/DotNet/MD/ENCMetadata.cs | 2 +- src/dnlib.csproj | 1 + 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 src/DotNet/MD/CustomDotNetStream.cs diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index a3baa318e..d06a91830 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -79,7 +79,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui } break; } - dns = new DotNetStream(mdReaderFactory, metadataBaseOffset, sh); + dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(dns); dns = null; } diff --git a/src/DotNet/MD/CustomDotNetStream.cs b/src/DotNet/MD/CustomDotNetStream.cs new file mode 100644 index 000000000..8d8882ac6 --- /dev/null +++ b/src/DotNet/MD/CustomDotNetStream.cs @@ -0,0 +1,25 @@ +// dnlib: See LICENSE.txt for more info + +using dnlib.IO; + +namespace dnlib.DotNet.MD { + /// + /// A custom .NET metadata stream + /// + public class CustomDotNetStream : DotNetStream { + /// + /// Constructor + /// + public CustomDotNetStream() { } + + /// + /// Constructor + /// + /// Data reader factory + /// Offset of metadata + /// The stream header + public CustomDotNetStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) + : base(mdReaderFactory, metadataBaseOffset, streamHeader) { + } + } +} diff --git a/src/DotNet/MD/DotNetStream.cs b/src/DotNet/MD/DotNetStream.cs index 892d18ff7..3ca79224f 100644 --- a/src/DotNet/MD/DotNetStream.cs +++ b/src/DotNet/MD/DotNetStream.cs @@ -9,7 +9,7 @@ namespace dnlib.DotNet.MD { /// .NET metadata stream /// [DebuggerDisplay("{dataReader.Length} {streamHeader.Name}")] - public class DotNetStream : IFileSection, IDisposable { + public abstract class DotNetStream : IFileSection, IDisposable { /// /// Reader that can access the whole stream. /// @@ -55,7 +55,7 @@ public class DotNetStream : IFileSection, IDisposable { /// /// Default constructor /// - public DotNetStream() { + protected DotNetStream() { streamHeader = null; dataReader = default; } @@ -66,7 +66,7 @@ public DotNetStream() { /// Data reader factory /// Offset of metadata /// The stream header - public DotNetStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) { + protected DotNetStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) { this.mdReaderFactory = mdReaderFactory; mdReaderFactory.DataReaderInvalidated += DataReaderFactory_DataReaderInvalidated; this.mdReaderFactory = mdReaderFactory; diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 9e263b58a..b3ec15bf4 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -89,7 +89,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui } break; } - dns = new DotNetStream(mdReaderFactory, metadataBaseOffset, sh); + dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(dns); dns = null; } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index aab97db15..561600cee 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -125,6 +125,7 @@ + From 28a07e9648f5d0e7efbe61889e75a4de0f3d8e04 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 4 Apr 2018 19:23:10 +0200 Subject: [PATCH 201/511] Add CoreCLR native image machine types --- src/DotNet/CpuArch.cs | 64 ++++++++++++---- src/DotNet/ModuleDef.cs | 16 ++-- src/DotNet/Writer/ModuleWriter.cs | 2 +- src/PE/Machine.cs | 121 +++++++++++++++++++++++++++++- 4 files changed, 179 insertions(+), 24 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 032b41b76..4b13b4c99 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -14,18 +14,14 @@ enum StubType { } abstract class CpuArch { - static readonly Dictionary toCpuArch = new Dictionary { - // To support a new CPU arch, the easiest way is to check coreclr/src/ilasm/writer.cpp or - // coreclr/src/dlls/mscorpe/stubs.h, eg. ExportStubAMD64Template, ExportStubX86Template, - // ExportStubARMTemplate, ExportStubIA64Template, or use ilasm to generate a file with - // exports and check the stub - { Machine.I386, new X86CpuArch() }, - { Machine.AMD64, new X64CpuArch() }, - { Machine.IA64, new ItaniumCpuArch() }, - { Machine.ARMNT, new ArmCpuArch() }, - //TODO: Support ARM64 - // { Machine.ARM64, new Arm64CpuArch() }, - }; + // To support a new CPU arch, the easiest way is to check coreclr/src/ilasm/writer.cpp or + // coreclr/src/dlls/mscorpe/stubs.h, eg. ExportStubAMD64Template, ExportStubX86Template, + // ExportStubARMTemplate, ExportStubIA64Template, or use ilasm to generate a file with + // exports and check the stub + static readonly X86CpuArch x86CpuArch = new X86CpuArch(); + static readonly X64CpuArch x64CpuArch = new X64CpuArch(); + static readonly ItaniumCpuArch itaniumCpuArch = new ItaniumCpuArch(); + static readonly ArmCpuArch armCpuArch = new ArmCpuArch(); /// /// Gets the required alignment for the stubs, must be a power of 2 @@ -48,7 +44,49 @@ abstract class CpuArch { /// public abstract uint GetStubCodeOffset(StubType stubType); - public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) => toCpuArch.TryGetValue(machine, out cpuArch); + public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { + switch (machine) { + case Machine.I386: + case Machine.I386_Native_Apple: + case Machine.I386_Native_FreeBSD: + case Machine.I386_Native_Linux: + case Machine.I386_Native_NetBSD: + cpuArch = x86CpuArch; + return true; + + case Machine.AMD64: + case Machine.AMD64_Native_Apple: + case Machine.AMD64_Native_FreeBSD: + case Machine.AMD64_Native_Linux: + case Machine.AMD64_Native_NetBSD: + cpuArch = x64CpuArch; + return true; + + case Machine.IA64: + cpuArch = itaniumCpuArch; + return true; + + case Machine.ARMNT: + case Machine.ARMNT_Native_Apple: + case Machine.ARMNT_Native_FreeBSD: + case Machine.ARMNT_Native_Linux: + case Machine.ARMNT_Native_NetBSD: + cpuArch = armCpuArch; + return true; + + case Machine.ARM64: + case Machine.ARM64_Native_Apple: + case Machine.ARM64_Native_FreeBSD: + case Machine.ARM64_Native_Linux: + case Machine.ARM64_Native_NetBSD: + //TODO: Support ARM64 + goto default; + + default: + cpuArch = null; + return false; + } + } /// /// Gets the RVA of the func field that the stub jumps to diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index c8ace7fed..d64300dd0 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -727,24 +727,24 @@ public bool IsClr10 { public Machine Machine { get; set; } /// - /// true if is + /// true if is , , ... /// - public bool IsI386 => Machine == Machine.I386; + public bool IsI386 => Machine.IsI386(); /// - /// true if is + /// true if is /// public bool IsIA64 => Machine == Machine.IA64; /// - /// true if is + /// true if is , , ... /// - public bool IsAMD64 => Machine == Machine.AMD64; + public bool IsAMD64 => Machine.IsAMD64(); /// - /// true if is + /// true if is , , ... /// - public bool IsARM64 => Machine == Machine.ARM64; + public bool IsARM64 => Machine.IsARM64(); /// /// Gets/sets the (from .NET header) @@ -1117,7 +1117,7 @@ public int GetPointerSize(int defaultPointerSize, int prefer32bitPointerSize) { var machine = Machine; if (machine.Is64Bit()) return 8; - if (machine != Machine.I386) + if (!machine.IsI386()) return 4; // Machine is I386 so it's either x86 or platform neutral diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index bf20cf454..b1d90cf9b 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -170,7 +170,7 @@ void CreateChunks() { var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; bool is64bit = machine.Is64Bit(); relocDirectory = new RelocDirectory(machine); - if (machine == Machine.I386) + if (machine.IsI386()) needStartupStub = true; importAddressTable = new ImportAddressTable(is64bit); diff --git a/src/PE/Machine.cs b/src/PE/Machine.cs index 0b563d46f..6a08cb885 100644 --- a/src/PE/Machine.cs +++ b/src/PE/Machine.cs @@ -65,6 +65,32 @@ public enum Machine : ushort { ARM64 = 0xAA64, /// CEE = 0xC0EE, + + // Search for IMAGE_FILE_MACHINE_NATIVE and IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE here: + // https://github.com/dotnet/coreclr/blob/master/src/inc/pedecoder.h + // Note that IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE == 0 if it's Windows + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + I386_Native_Apple = I386 ^ 0x4644, + AMD64_Native_Apple = AMD64 ^ 0x4644, + ARMNT_Native_Apple = ARMNT ^ 0x4644, + ARM64_Native_Apple = ARM64 ^ 0x4644, + + I386_Native_FreeBSD = I386 ^ 0xADC4, + AMD64_Native_FreeBSD = AMD64 ^ 0xADC4, + ARMNT_Native_FreeBSD = ARMNT ^ 0xADC4, + ARM64_Native_FreeBSD = ARM64 ^ 0xADC4, + + I386_Native_Linux = I386 ^ 0x7B79, + AMD64_Native_Linux = AMD64 ^ 0x7B79, + ARMNT_Native_Linux = ARMNT ^ 0x7B79, + ARM64_Native_Linux = ARM64 ^ 0x7B79, + + I386_Native_NetBSD = I386 ^ 0x1993, + AMD64_Native_NetBSD = AMD64 ^ 0x1993, + ARMNT_Native_NetBSD = ARMNT ^ 0x1993, + ARM64_Native_NetBSD = ARM64 ^ 0x1993, +#pragma warning restore 1591 // Missing XML comment for publicly visible type or member } /// @@ -76,7 +102,98 @@ public static class MachineExtensions { /// /// Machine /// - public static bool Is64Bit(this Machine machine) => - machine == Machine.AMD64 || machine == Machine.IA64 || machine == Machine.ARM64; + public static bool Is64Bit(this Machine machine) { + switch (machine) { + case Machine.IA64: + + case Machine.AMD64: + case Machine.AMD64_Native_Apple: + case Machine.AMD64_Native_FreeBSD: + case Machine.AMD64_Native_Linux: + case Machine.AMD64_Native_NetBSD: + + case Machine.ARM64: + case Machine.ARM64_Native_Apple: + case Machine.ARM64_Native_FreeBSD: + case Machine.ARM64_Native_Linux: + case Machine.ARM64_Native_NetBSD: + return true; + + default: + return false; + } + } + + /// + /// Checks if is , , etc... + /// + /// Machine + /// + public static bool IsI386(this Machine machine) { + switch (machine) { + case Machine.I386: + case Machine.I386_Native_Apple: + case Machine.I386_Native_FreeBSD: + case Machine.I386_Native_Linux: + case Machine.I386_Native_NetBSD: + return true; + default: + return false; + } + } + + /// + /// Checks if is , , etc... + /// + /// Machine + /// + public static bool IsAMD64(this Machine machine) { + switch (machine) { + case Machine.AMD64: + case Machine.AMD64_Native_Apple: + case Machine.AMD64_Native_FreeBSD: + case Machine.AMD64_Native_Linux: + case Machine.AMD64_Native_NetBSD: + return true; + default: + return false; + } + } + + /// + /// Checks if is , , etc... + /// + /// Machine + /// + public static bool IsARMNT(this Machine machine) { + switch (machine) { + case Machine.ARMNT: + case Machine.ARMNT_Native_Apple: + case Machine.ARMNT_Native_FreeBSD: + case Machine.ARMNT_Native_Linux: + case Machine.ARMNT_Native_NetBSD: + return true; + default: + return false; + } + } + + /// + /// Checks if is , , etc... + /// + /// Machine + /// + public static bool IsARM64(this Machine machine) { + switch (machine) { + case Machine.ARM64: + case Machine.ARM64_Native_Apple: + case Machine.ARM64_Native_FreeBSD: + case Machine.ARM64_Native_Linux: + case Machine.ARM64_Native_NetBSD: + return true; + default: + return false; + } + } } } From 9f0be3def86fb1346fed1d7ee7d6edcebf0599f2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 5 Apr 2018 19:43:04 +0200 Subject: [PATCH 202/511] Add IsARM prop --- src/DotNet/ModuleDef.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index d64300dd0..ed9c78c16 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -741,6 +741,11 @@ public bool IsClr10 { /// public bool IsAMD64 => Machine.IsAMD64(); + /// + /// true if is , , ... + /// + public bool IsARM => Machine.IsARMNT(); + /// /// true if is , , ... /// From 956c7a5833246c554f31e2ef603b90d096a18db6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 8 Apr 2018 13:10:37 +0200 Subject: [PATCH 203/511] Support deterministic even if it's v6 --- src/DotNet/Pdb/Dss/SymbolWriterImpl.cs | 7 ++----- src/DotNet/Writer/ModuleWriterBase.cs | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index 06723ab01..893a7b1b5 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -27,9 +27,7 @@ public SymbolWriterImpl(ISymUnmanagedWriter2 writer, string pdbFileName, Stream this.pdbStream = pdbStream ?? throw new ArgumentNullException(nameof(pdbStream)); this.pdbFileName = pdbFileName; this.ownsStream = ownsStream; - // If it's deterministic, we should call UpdateSignatureByHashingContent() or UpdateSignature(), - // but that requires v7 or v8. InitializeDeterministic() is v6. - isDeterministic = (options & PdbWriterOptions.Deterministic) != 0 && writer is ISymUnmanagedWriter7; + isDeterministic = (options & PdbWriterOptions.Deterministic) != 0 && writer is ISymUnmanagedWriter6; } public override void Close() { @@ -102,8 +100,7 @@ public override unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, writer8.UpdateSignature(guid, stamp, pdbAge); return true; } - else { - var writer7 = (ISymUnmanagedWriter7)writer; + else if (writer is ISymUnmanagedWriter7 writer7) { fixed (byte* p = checksumBytes) writer7.UpdateSignatureByHashingContent(new IntPtr(p), (uint)checksumBytes.Length); } diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 7914a8045..2c949e958 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -328,7 +328,7 @@ public bool Is64Bit { public Stream PdbStream { get; set; } /// - /// Gets the PDB content id. The argument is the PDB stream with the PDB ID zeroed out, + /// Gets the PDB content id (portable PDBs). The argument is the PDB stream with the PDB ID zeroed out, /// and the 2nd argument is the default timestamp. /// This property is ignored if a deterministic PDB file is created or if the PDB checksum is calculated. /// From c09ebf33b2d82b3ab94cfa6850d754ddae54be6b Mon Sep 17 00:00:00 2001 From: HoLLy Date: Mon, 9 Apr 2018 18:26:18 +0200 Subject: [PATCH 204/511] Target both .NET Fx 3.5 and .NET Std 2.0 in dnlib.netstandard.csproj (#178) --- src/dnlib.netstandard.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index a0000ba7b..eb97ff781 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + net35;netstandard2.0 dnlib dnlib true @@ -16,11 +16,11 @@ true portable - + - + From 546f11857971d60c9dbaf8fcd52b41a603710b4a Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 11 Apr 2018 14:59:24 +0200 Subject: [PATCH 205/511] Optimize #Strings stream before SetOffset() is called --- src/DotNet/Writer/Metadata.cs | 10 ++++++++-- src/DotNet/Writer/ModuleWriter.cs | 1 + src/DotNet/Writer/NativeModuleWriter.cs | 1 + src/DotNet/Writer/StringsHeap.cs | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 140141536..964c0ef35 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3456,6 +3456,7 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdb debugMetadata.tablesHeap.MethodDebugInformationTable.Reset(); pdbHeap.ReferencedTypeSystemTables = systemTablesMask; var writer = new DataWriter(output); + debugMetadata.OnBeforeSetOffset(); debugMetadata.SetOffset(0, 0); debugMetadata.GetFileLength(); debugMetadata.VerifyWriteTo(writer); @@ -3557,6 +3558,12 @@ bool IReuseChunk.CanReuse(RVA origRva, uint origSize) { return length <= origSize; } + /// + /// Should be called before all chunks get an RVA + /// + internal void OnBeforeSetOffset() => + stringsHeap.AddOptimizedStringsAndSetReadOnly(); + /// public void SetOffset(FileOffset offset, RVA rva) { // This method can be called twice by NativeModuleWriter. It needs to know the size @@ -3568,8 +3575,7 @@ public void SetOffset(FileOffset offset, RVA rva) { this.rva = rva; if (initAll) { - stringsHeap.AddOptimizedStrings(); - stringsHeap.SetReadOnly(); + // #Strings heap is initialized in OnBeforeSetOffset() blobHeap.SetReadOnly(); guidHeap.SetReadOnly(); tablesHeap.SetReadOnly(); diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index b1d90cf9b..722f84d0e 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -222,6 +222,7 @@ long WriteFile() { WritePdbFile(); OnWriterEvent(ModuleWriterEvent.EndWritePdb); + metadata.OnBeforeSetOffset(); OnWriterEvent(ModuleWriterEvent.BeginCalculateRvasAndFileOffsets); var chunks = new List(); chunks.Add(peHeaders); diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 677dbd93d..95694de23 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -364,6 +364,7 @@ long WriteFile() { WritePdbFile(); OnWriterEvent(ModuleWriterEvent.EndWritePdb); + metadata.OnBeforeSetOffset(); OnWriterEvent(ModuleWriterEvent.BeginCalculateRvasAndFileOffsets); if (Options.OptimizeImageSize) { diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index 95ad5cd2d..ff65928d9 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -76,9 +76,10 @@ void Populate(ref DataReader reader) { } } - internal void AddOptimizedStrings() { + internal void AddOptimizedStringsAndSetReadOnly() { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); + SetReadOnly(); stringsOffsetInfos.Sort(Comparison_StringsOffsetInfoSorter); From c484e3bd8a6b59411fe576667404d49634860ee8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 17 Apr 2018 22:18:03 +0200 Subject: [PATCH 206/511] Use System.Runtime.InteropServices.RuntimeInformation to get CPU arch --- src/PE/ProcessorArchUtils.cs | 49 ++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index 55617c130..2ffa1a67e 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; +using System.Reflection; namespace dnlib.PE { static class ProcessorArchUtils { @@ -13,9 +14,54 @@ public static Machine GetProcessCpuArchitecture() { return cachedMachine; } + static class RuntimeInformationUtils { + // .NET Framework 4.7.1: mscorlib + // .NET Core: System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + static Assembly RuntimeInformationAssembly => + Assembly.Load("System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") ?? + typeof(object).Assembly; + static Type System_Runtime_InteropServices_RuntimeInformation => RuntimeInformationAssembly.GetType("System.Runtime.InteropServices.RuntimeInformation", throwOnError: false); + + public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) { + machine = 0; + var processArchitectureMethod = System_Runtime_InteropServices_RuntimeInformation?.GetMethod("get_ProcessArchitecture", Array2.Empty()); + if ((object)processArchitectureMethod == null) + return false; + + var result = processArchitectureMethod.Invoke(null, Array2.Empty()); + switch ((int)result) { + case 0: // Architecture.X86 + Debug.Assert(IntPtr.Size == 4); + machine = Machine.I386; + return true; + + case 1: // Architecture.X64 + Debug.Assert(IntPtr.Size == 8); + machine = Machine.AMD64; + return true; + + case 2: // Architecture.Arm + Debug.Assert(IntPtr.Size == 4); + machine = Machine.ARMNT; + return true; + + case 3: // Architecture.Arm64 + Debug.Assert(IntPtr.Size == 8); + machine = Machine.ARM64; + return true; + + default: + return false; + } + } + } + static Machine GetProcessCpuArchitectureCore() { + if (RuntimeInformationUtils.TryGet_RuntimeInformation_Architecture(out var machine)) + return machine; + bool isWindows = true;//TODO: - if (isWindows && TryGetProcessCpuArchitecture_Windows(out var machine)) + if (isWindows && TryGetProcessCpuArchitecture_Windows(out machine)) return machine; Debug.WriteLine("Couldn't detect CPU arch, assuming x86 or x64"); @@ -23,7 +69,6 @@ static Machine GetProcessCpuArchitectureCore() { } static bool TryGetProcessCpuArchitecture_Windows(out Machine machine) { - //TODO: We shouldn't trust the environment string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); if (arch != null) { // https://msdn.microsoft.com/en-us/library/aa384274.aspx ("WOW64 Implementation Details / Environment Variables") From 88a1a7e77687ad9bf7fc9306183a6424be557027 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 17 Apr 2018 23:39:47 +0200 Subject: [PATCH 207/511] Use System.Runtime.InteropServices.RuntimeInformation nuget pkg if netstandard 2.0 --- src/PE/ProcessorArchUtils.cs | 12 +++++++++++- src/dnlib.netstandard.csproj | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index 2ffa1a67e..49d28eb75 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -15,6 +15,10 @@ public static Machine GetProcessCpuArchitecture() { } static class RuntimeInformationUtils { +#if NETSTANDARD2_0 + public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => + TryGetArchitecture((int)System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture, out machine); +#else // .NET Framework 4.7.1: mscorlib // .NET Core: System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a static Assembly RuntimeInformationAssembly => @@ -29,7 +33,12 @@ public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) { return false; var result = processArchitectureMethod.Invoke(null, Array2.Empty()); - switch ((int)result) { + return TryGetArchitecture((int)result, out machine); + } +#endif + + static bool TryGetArchitecture(int architecture, out Machine machine) { + switch (architecture) { case 0: // Architecture.X86 Debug.Assert(IntPtr.Size == 4); machine = Machine.I386; @@ -51,6 +60,7 @@ public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) { return true; default: + machine = 0; return false; } } diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index eb97ff781..723be7d9d 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -23,5 +23,6 @@ + From f2ccbcb0906d7f37b10772dd938bcf5edbb0464d Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Apr 2018 16:30:41 +0200 Subject: [PATCH 208/511] Update param check --- src/IO/DataReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 9847c3986..a6d3ed149 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -398,7 +398,7 @@ public string ReadUtf16String(int chars) { /// Destination pointer /// Number of bytes to read public unsafe void ReadBytes(void* destination, int length) { - if (destination == null) + if (destination == null && length != 0) ThrowArgumentNullException(nameof(destination)); if (length < 0) ThrowInvalidArgument(nameof(length)); From 0dd1e7e5a7737b95ac3e6d2248a7356a92dc5f9b Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Apr 2018 16:31:49 +0200 Subject: [PATCH 209/511] Don't use assembly load, fixes #188 --- src/PE/ProcessorArchUtils.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index 49d28eb75..efe61adba 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -20,10 +20,7 @@ public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) = TryGetArchitecture((int)System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture, out machine); #else // .NET Framework 4.7.1: mscorlib - // .NET Core: System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - static Assembly RuntimeInformationAssembly => - Assembly.Load("System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") ?? - typeof(object).Assembly; + static Assembly RuntimeInformationAssembly => typeof(object).Assembly; static Type System_Runtime_InteropServices_RuntimeInformation => RuntimeInformationAssembly.GetType("System.Runtime.InteropServices.RuntimeInformation", throwOnError: false); public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) { From bb88ae249c0ed4135cf0c1fc4c01ca8f33b12135 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Apr 2018 16:34:10 +0200 Subject: [PATCH 210/511] Add an empty Directory.Build.props --- Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..d014f64c6 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,3 @@ + + + \ No newline at end of file From e7915ea37db64633738f8cac6a1664bb028a4fbb Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Apr 2018 17:47:10 +0200 Subject: [PATCH 211/511] Call GetSystemInfo() --- src/PE/ProcessorArchUtils.cs | 127 +++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 50 deletions(-) diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index efe61adba..2817cce7f 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.Reflection; +using System.Runtime.InteropServices; namespace dnlib.PE { static class ProcessorArchUtils { @@ -17,9 +18,8 @@ public static Machine GetProcessCpuArchitecture() { static class RuntimeInformationUtils { #if NETSTANDARD2_0 public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => - TryGetArchitecture((int)System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture, out machine); + TryGetArchitecture((int)RuntimeInformation.ProcessArchitecture, out machine); #else - // .NET Framework 4.7.1: mscorlib static Assembly RuntimeInformationAssembly => typeof(object).Assembly; static Type System_Runtime_InteropServices_RuntimeInformation => RuntimeInformationAssembly.GetType("System.Runtime.InteropServices.RuntimeInformation", throwOnError: false); @@ -57,6 +57,7 @@ static bool TryGetArchitecture(int architecture, out Machine machine) { return true; default: + Debug.Fail($"Unknown process architecture: {architecture}"); machine = 0; return false; } @@ -64,67 +65,93 @@ static bool TryGetArchitecture(int architecture, out Machine machine) { } static Machine GetProcessCpuArchitectureCore() { - if (RuntimeInformationUtils.TryGet_RuntimeInformation_Architecture(out var machine)) - return machine; - - bool isWindows = true;//TODO: - if (isWindows && TryGetProcessCpuArchitecture_Windows(out machine)) + if (WindowsUtils.TryGetProcessCpuArchitecture(out var machine)) return machine; + try { + if (RuntimeInformationUtils.TryGet_RuntimeInformation_Architecture(out machine)) + return machine; + } + catch (PlatformNotSupportedException) { + } Debug.WriteLine("Couldn't detect CPU arch, assuming x86 or x64"); return IntPtr.Size == 4 ? Machine.I386 : Machine.AMD64; } - static bool TryGetProcessCpuArchitecture_Windows(out Machine machine) { - string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); - if (arch != null) { - // https://msdn.microsoft.com/en-us/library/aa384274.aspx ("WOW64 Implementation Details / Environment Variables") - switch (arch.ToUpperInvariant()) { - case "AMD64": - if (IntPtr.Size == 8) { - machine = Machine.AMD64; - return true; - } - Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); - break; + static class WindowsUtils { + [DllImport("kernel32")] + static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo); + + struct SYSTEM_INFO { + public ushort wProcessorArchitecture; + public ushort wReserved; + public uint dwPageSize; + public IntPtr lpMinimumApplicationAddress; + public IntPtr lpMaximumApplicationAddress; + public IntPtr dwActiveProcessorMask; + public uint dwNumberOfProcessors; + public uint dwProcessorType; + public uint dwAllocationGranularity; + public ushort wProcessorLevel; + public ushort wProcessorRevision; + } - case "X86": - if (IntPtr.Size == 4) { - machine = Machine.I386; - return true; - } - Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); - break; + enum ProcessorArchitecture : ushort { + INTEL = 0, + ARM = 5, + IA64 = 6, + AMD64 = 9, + ARM64 = 12, + UNKNOWN = 0xFFFF, + } - case "IA64": - if (IntPtr.Size == 8) { - machine = Machine.IA64; - return true; + public static bool TryGetProcessCpuArchitecture(out Machine machine) { + if (canTryGetSystemInfo) { + try { + GetSystemInfo(out var sysInfo); + switch ((ProcessorArchitecture)sysInfo.wProcessorArchitecture) { + case ProcessorArchitecture.INTEL: + Debug.Assert(IntPtr.Size == 4); + machine = Machine.I386; + return true; + + case ProcessorArchitecture.ARM: + Debug.Assert(IntPtr.Size == 4); + machine = Machine.ARMNT; + return true; + + case ProcessorArchitecture.IA64: + Debug.Assert(IntPtr.Size == 8); + machine = Machine.IA64; + return true; + + case ProcessorArchitecture.AMD64: + Debug.Assert(IntPtr.Size == 8); + machine = Machine.AMD64; + return true; + + case ProcessorArchitecture.ARM64: + Debug.Assert(IntPtr.Size == 8); + machine = Machine.ARM64; + return true; + + case ProcessorArchitecture.UNKNOWN: + default: + break; + } } - Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); - break; - - //TODO: This string hasn't been tested - case "ARM": - if (IntPtr.Size == 4) { - machine = Machine.ARMNT; - return true; + catch (EntryPointNotFoundException) { + canTryGetSystemInfo = false; } - Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); - break; - - case "ARM64": - if (IntPtr.Size == 8) { - machine = Machine.ARM64; - return true; + catch (DllNotFoundException) { + canTryGetSystemInfo = false; } - Debug.Fail($"Bad PROCESSOR_ARCHITECTURE env var"); - break; } - } - machine = default; - return false; + machine = 0; + return false; + } + static bool canTryGetSystemInfo = true; } } } From 7ae4ce76b0b7205976237c75e905507e5d3eee00 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Apr 2018 17:50:07 +0200 Subject: [PATCH 212/511] Change order of target frameworks --- src/dnlib.netstandard.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index 723be7d9d..d3a4aa6cd 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -1,7 +1,7 @@ - net35;netstandard2.0 + netstandard2.0;net35 dnlib dnlib true From 9b86179d221191dce1519a531478071b758461da Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 18 Apr 2018 19:48:46 +0200 Subject: [PATCH 213/511] Use other overload if module has no known address --- src/DotNet/ModuleDefMD.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 9e82c2eb2..7e8cdd82a 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -212,14 +212,10 @@ static IntPtr GetModuleHandle(System.Reflection.Module mod) { if (GetHINSTANCE == null) throw new NotSupportedException("System.Reflection.Module loading is not supported on current platform"); - var addr = (IntPtr)GetHINSTANCE.Invoke(null, new[] { mod }); + return (IntPtr)GetHINSTANCE.Invoke(null, new[] { mod }); #else - var addr = Marshal.GetHINSTANCE(mod); + return Marshal.GetHINSTANCE(mod); #endif - if (addr == IntPtr.Zero || addr == new IntPtr(-1)) - throw new ArgumentException("It is not possible to get address of module"); - - return addr; } /// @@ -231,9 +227,12 @@ static IntPtr GetModuleHandle(System.Reflection.Module mod) { /// A new instance public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptions options, ImageLayout imageLayout) { var addr = GetModuleHandle(mod); - if (addr == new IntPtr(-1)) + if (addr != IntPtr.Zero && addr != new IntPtr(-1)) + return Load(addr, options, imageLayout); + var location = mod.FullyQualifiedName; + if (string.IsNullOrEmpty(location) || location[0] == '<') throw new InvalidOperationException($"Module {mod} has no HINSTANCE"); - return Load(addr, options, imageLayout); + return Load(location, options); } /// @@ -1375,7 +1374,7 @@ internal ModuleDefMD ReadModule(uint fileRid, AssemblyDef owner) { return null; ModuleDefMD module; try { - module = ModuleDefMD.Load(fileName); + module = Load(fileName); } catch { module = null; From c40e1480662201af1a683dbe00656270c8b27a5a Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 20 Apr 2018 00:59:07 +0200 Subject: [PATCH 214/511] Mono MD reader fixes --- src/DotNet/MD/MetadataFactory.cs | 11 ++++------- src/DotNet/MD/MetadataHeader.cs | 11 +++++++---- src/DotNet/MD/StreamHeader.cs | 21 +++++++++++++++++---- src/DotNet/MD/TablesStream.cs | 2 ++ src/PE/IImageOptionalHeader.cs | 2 +- src/PE/ImageNTHeaders.cs | 3 ++- src/PE/PEImage.cs | 2 -- src/PE/PEInfo.cs | 10 +++++++++- 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/DotNet/MD/MetadataFactory.cs b/src/DotNet/MD/MetadataFactory.cs index bc7acee36..e307381f7 100644 --- a/src/DotNet/MD/MetadataFactory.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -128,23 +128,20 @@ static MetadataBase Create(IPEImage peImage, bool verify) { MetadataBase md = null; try { var dotNetDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14]; + // Mono doesn't check that the Size field is >= 0x48 if (dotNetDir.VirtualAddress == 0) throw new BadImageFormatException(".NET data directory RVA is 0"); - if (dotNetDir.Size < 0x48) - throw new BadImageFormatException(".NET data directory size < 0x48"); var cor20HeaderReader = peImage.CreateReader(dotNetDir.VirtualAddress, 0x48); var cor20Header = new ImageCor20Header(ref cor20HeaderReader, verify); if (cor20Header.Metadata.VirtualAddress == 0) throw new BadImageFormatException(".NET metadata RVA is 0"); - if (cor20Header.Metadata.Size < 16) - throw new BadImageFormatException(".NET metadata size is too small"); - var mdSize = cor20Header.Metadata.Size; var mdRva = cor20Header.Metadata.VirtualAddress; - var mdHeaderReader = peImage.CreateReader(mdRva, mdSize); + // Don't use the size field, Mono ignores it. Create a reader that can read to EOF. + var mdHeaderReader = peImage.CreateReader(mdRva); var mdHeader = new MetadataHeader(ref mdHeaderReader, verify); if (verify) { foreach (var sh in mdHeader.StreamHeaders) { - if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > mdSize) + if ((ulong)sh.Offset + sh.StreamSize > mdHeaderReader.EndOffset) throw new BadImageFormatException("Invalid stream header"); } } diff --git a/src/DotNet/MD/MetadataHeader.cs b/src/DotNet/MD/MetadataHeader.cs index 8d24754e6..e3d7f1831 100644 --- a/src/DotNet/MD/MetadataHeader.cs +++ b/src/DotNet/MD/MetadataHeader.cs @@ -91,8 +91,6 @@ public MetadataHeader(ref DataReader reader, bool verify) { throw new BadImageFormatException("Invalid metadata header signature"); majorVersion = reader.ReadUInt16(); minorVersion = reader.ReadUInt16(); - if (verify && !((majorVersion == 1 && minorVersion == 1) || (majorVersion == 0 && minorVersion >= 19))) - throw new BadImageFormatException($"Unknown metadata header version: {majorVersion}.{minorVersion}"); reserved1 = reader.ReadUInt32(); stringLength = reader.ReadUInt32(); versionString = ReadString(ref reader, stringLength); @@ -101,8 +99,13 @@ public MetadataHeader(ref DataReader reader, bool verify) { reserved2 = reader.ReadByte(); streams = reader.ReadUInt16(); streamHeaders = new StreamHeader[streams]; - for (int i = 0; i < streamHeaders.Count; i++) - streamHeaders[i] = new StreamHeader(ref reader, verify); + for (int i = 0; i < streamHeaders.Count; i++) { + // Mono doesn't verify all of these so we can't either + var sh = new StreamHeader(ref reader, throwOnError: false, verify, out bool failedVerification); + if (failedVerification || (ulong)sh.Offset + sh.StreamSize > reader.EndOffset) + sh = new StreamHeader(0, 0, ""); + streamHeaders[i] = sh; + } SetEndoffset(ref reader); } diff --git a/src/DotNet/MD/StreamHeader.cs b/src/DotNet/MD/StreamHeader.cs index 29265fceb..0f1252976 100644 --- a/src/DotNet/MD/StreamHeader.cs +++ b/src/DotNet/MD/StreamHeader.cs @@ -36,17 +36,30 @@ public sealed class StreamHeader : FileSection { /// PE file reader pointing to the start of this section /// Verify section /// Thrown if verification fails - public StreamHeader(ref DataReader reader, bool verify) { + public StreamHeader(ref DataReader reader, bool verify) + : this(ref reader, verify, verify, out _) { + } + + internal StreamHeader(ref DataReader reader, bool throwOnError, bool verify, out bool failedVerification) { + failedVerification = false; SetStartOffset(ref reader); offset = reader.ReadUInt32(); streamSize = reader.ReadUInt32(); - name = ReadString(ref reader, 32, verify); + name = ReadString(ref reader, 32, verify, ref failedVerification); SetEndoffset(ref reader); if (verify && offset + size < offset) + failedVerification = true; + if (throwOnError && failedVerification) throw new BadImageFormatException("Invalid stream header"); } - static string ReadString(ref DataReader reader, int maxLen, bool verify) { + internal StreamHeader(uint offset, uint streamSize, string name) { + this.offset = offset; + this.streamSize = streamSize; + this.name = name ?? throw new ArgumentNullException(nameof(name)); + } + + static string ReadString(ref DataReader reader, int maxLen, bool verify, ref bool failedVerification) { var origPos = reader.Position; var sb = new StringBuilder(maxLen); int i; @@ -57,7 +70,7 @@ static string ReadString(ref DataReader reader, int maxLen, bool verify) { sb.Append((char)b); } if (verify && i == maxLen) - throw new BadImageFormatException("Invalid stream name string"); + failedVerification = true; if (i != maxLen) reader.Position = origPos + (((uint)i + 1 + 3) & ~3U); return sb.ToString(); diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index ba017d45c..b39f9bd90 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -204,6 +204,8 @@ public void Initialize(uint[] typeSystemTableRows) { var sizes = new uint[64]; for (int i = 0; i < 64; valid >>= 1, i++) { uint rows = (valid & 1) == 0 ? 0 : reader.ReadUInt32(); + // Mono ignores the high byte + rows &= 0x00FFFFFF; if (i >= maxPresentTables) rows = 0; sizes[i] = rows; diff --git a/src/PE/IImageOptionalHeader.cs b/src/PE/IImageOptionalHeader.cs index 21ea4b480..7d2d23e7c 100644 --- a/src/PE/IImageOptionalHeader.cs +++ b/src/PE/IImageOptionalHeader.cs @@ -158,7 +158,7 @@ public interface IImageOptionalHeader : IFileSection { uint NumberOfRvaAndSizes { get; } /// - /// Returns the DataDirectories field + /// Returns the DataDirectories field. This array contains exactly 16 elements. /// ImageDataDirectory[] DataDirectories { get; } } diff --git a/src/PE/ImageNTHeaders.cs b/src/PE/ImageNTHeaders.cs index b98ad31e6..f397b2157 100644 --- a/src/PE/ImageNTHeaders.cs +++ b/src/PE/ImageNTHeaders.cs @@ -36,7 +36,8 @@ public sealed class ImageNTHeaders : FileSection { public ImageNTHeaders(ref DataReader reader, bool verify) { SetStartOffset(ref reader); signature = reader.ReadUInt32(); - if (verify && signature != 0x4550) + // Mono only checks the low 2 bytes + if (verify && (ushort)signature != 0x4550) throw new BadImageFormatException("Invalid NT headers signature"); imageFileHeader = new ImageFileHeader(ref reader, verify); imageOptionalHeader = CreateImageOptionalHeader(ref reader, verify); diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index d02ea6fca..6d8b8e0db 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -347,8 +347,6 @@ bool IInternalPEImage.IsMemoryMappedIO { ImageDebugDirectory[] ReadImageDebugDirectories() { try { - if (6 >= ImageNTHeaders.OptionalHeader.DataDirectories.Length) - return Array2.Empty(); var dataDir = ImageNTHeaders.OptionalHeader.DataDirectories[6]; if (dataDir.VirtualAddress == 0) return Array2.Empty(); diff --git a/src/PE/PEInfo.cs b/src/PE/PEInfo.cs index 228eb0dfe..02e0d35f9 100644 --- a/src/PE/PEInfo.cs +++ b/src/PE/PEInfo.cs @@ -43,7 +43,15 @@ public PEInfo(ref DataReader reader, bool verify) { imageNTHeaders = new ImageNTHeaders(ref reader, verify); reader.Position = (uint)imageNTHeaders.OptionalHeader.StartOffset + imageNTHeaders.FileHeader.SizeOfOptionalHeader; - imageSectionHeaders = new ImageSectionHeader[imageNTHeaders.FileHeader.NumberOfSections]; + int numSections = imageNTHeaders.FileHeader.NumberOfSections; + if (numSections > 0) { + // Mono doesn't verify the section count + var tempReader = reader; + tempReader.Position += 0x14; + uint firstSectionOffset = tempReader.ReadUInt32(); + numSections = Math.Min(numSections, (int)((firstSectionOffset - reader.Position) / 0x28)); + } + imageSectionHeaders = new ImageSectionHeader[numSections]; for (int i = 0; i < imageSectionHeaders.Length; i++) imageSectionHeaders[i] = new ImageSectionHeader(ref reader, verify); } From c175744cfde9bef632608b00020af65f56c815bb Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 20 Apr 2018 08:04:09 +0200 Subject: [PATCH 215/511] Remove assert, fixes #189 --- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index eb8c44b7c..fbd7d9046 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -243,7 +243,7 @@ void Write(MethodDef method, List cdiBuilder) { } } else { - Debug.Fail("Root scope isn't empty"); + // C++/.NET (some methods) WriteScope(ref info, scope, 0); } From a99b72cc5a4fbb88d2d823c010d3da790b5e43c8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 20 Apr 2018 08:06:58 +0200 Subject: [PATCH 216/511] Remove unnecessary usings --- src/DotNet/CpuArch.cs | 1 - src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 4b13b4c99..f13d2220b 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.Collections.Generic; using System.Diagnostics; using dnlib.DotNet.Writer; using dnlib.IO; diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index fbd7d9046..1e95fde21 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Emit; using dnlib.DotNet.Writer; From 63101360e4b5af930a4dfa48f4b9167b4b20e5c8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 28 Apr 2018 11:11:15 +0200 Subject: [PATCH 217/511] Add features strict, and change lang version to latest --- src/dnlib.csproj | 3 ++- src/dnlib.netstandard.csproj | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 561600cee..5a068c266 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -13,7 +13,8 @@ 512 true ..\dnlib.snk - 7.2 + strict + latest Client diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj index d3a4aa6cd..034d66c97 100644 --- a/src/dnlib.netstandard.csproj +++ b/src/dnlib.netstandard.csproj @@ -12,7 +12,8 @@ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml false 512 - 7.2 + strict + latest true portable From 2b96f88cb26d547e04cbb2684c987490f5548845 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 28 Apr 2018 11:14:35 +0200 Subject: [PATCH 218/511] Update README, fixes #191 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 023e666c8..d843657b4 100644 --- a/README.md +++ b/README.md @@ -529,7 +529,8 @@ cache. ```csharp ModuleDefMD mod = ModuleDefMD.Load(...); mod.Context = modCtx; // Use the previously created (and shared) context - mod.Context.AssemblyResolver.AddToCache(mod); + // This code assumes you're using the default assembly resolver + ((AssemblyResolver)mod.Context.AssemblyResolver).AddToCache(mod); ``` Resolving types, methods, etc from metadata tokens From 68e7006a9d47cfa8a068da30c004fbb55e26f257 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 3 Jun 2018 17:04:30 +0200 Subject: [PATCH 219/511] readonly field --- src/DotNet/Writer/MethodBody.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 35fb31ae3..eaf76dc88 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -17,7 +17,7 @@ public sealed class MethodBody : IChunk { uint length; FileOffset offset; RVA rva; - uint localVarSigTok; + readonly uint localVarSigTok; /// public FileOffset FileOffset => offset; From 30e4eed23f18bd15808f5a0d2403115150b0b562 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 16 Jul 2018 14:06:22 +0200 Subject: [PATCH 220/511] Update README.md, fixes #203 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d843657b4..138c2262a 100644 --- a/README.md +++ b/README.md @@ -604,4 +604,4 @@ To get a list of all valid TypeDef rids (row IDs), use this code: Console.WriteLine("rid: {0}", typeDefRids[i]); ``` -You don't need to create a `ModuleDefMD`, though. See `DotNetFile`. +You don't need to create a `ModuleDefMD`, though. See `MetadataFactory`. From aa660d5234e83f60a25b3463e22c75919615e7de Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 21 Jul 2018 11:56:21 +0200 Subject: [PATCH 221/511] Add AddSection() --- src/DotNet/Writer/ModuleWriter.cs | 16 +++++++++++++++- src/DotNet/Writer/ModuleWriterBase.cs | 8 +++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 722f84d0e..138987d45 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -59,10 +59,21 @@ public ModuleWriterOptions Options { } /// - /// Gets all s + /// Gets all s. The reloc section must be the last section, so use if you need to append a section /// public override List Sections => sections; + /// + /// Adds to the sections list, but before the reloc section which must be last + /// + /// New section to add to the list + public override void AddSection(PESection section) { + if (sections.Count > 0 && sections[sections.Count - 1] == relocSection) + sections.Insert(sections.Count - 1, section); + else + sections.Add(section); + } + /// /// Gets the .text section /// @@ -238,6 +249,9 @@ long WriteFile() { foreach (var section in sections) chunks.Add(section); peHeaders.PESections = sections; + int relocIndex = sections.IndexOf(relocSection); + if (relocIndex >= 0 && relocIndex != sections.Count - 1) + throw new InvalidOperationException("Reloc section must be the last section, use AddSection() to add a section"); CalculateRvasAndFileOffsets(chunks, 0, 0, peHeaders.FileAlignment, peHeaders.SectionAlignment); OnWriterEvent(ModuleWriterEvent.EndCalculateRvasAndFileOffsets); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 2c949e958..9150e1a94 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -611,10 +611,16 @@ public abstract class ModuleWriterBase : ILogger { public StrongNameSignature StrongNameSignature => strongNameSignature; /// - /// Gets all s + /// Gets all s. The reloc section must be the last section, so use if you need to append a section /// public abstract List Sections { get; } + /// + /// Adds to the sections list, but before the reloc section which must be last + /// + /// New section to add to the list + public virtual void AddSection(PESection section) => Sections.Add(section); + /// /// Gets the .text section /// From 3996b9ede07dfe29511a2a5da49896664e2f341c Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 14 Aug 2018 14:58:35 +0200 Subject: [PATCH 222/511] Don't resolve the type ref, use the asm def to find the type, fixes #210 --- src/DotNet/TypeNameParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index e0f7f8dfe..06f99f99b 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -596,7 +596,7 @@ TypeDef Resolve(AssemblyRef asmRef, TypeRef typeRef) { return null; if (!(AssemblyNameComparer.CompareAll.Equals(asmRef, asm) && asmRef.IsRetargetable == asm.IsRetargetable)) return null; - var td = typeRef.Resolve(); + var td = asm.Find(typeRef); return td != null && td.Module == ownerModule ? td : null; } From 3dc4caa43ef37a29e0260d0d0fa961a7a0a785e8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 14 Aug 2018 15:04:17 +0200 Subject: [PATCH 223/511] Prevent resolving types early if there's a PDB file --- src/DotNet/Pdb/PdbState.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 90d98a98a..8727a0c62 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -226,11 +226,14 @@ static Compiler CalculateCompiler(ModuleDef module) { return Compiler.VisualBasic; } +// Disable this for now, we shouldn't be resolving types this early since we could be called by the ModuleDefMD ctor +#if false // The VB runtime can also be embedded, and if so, it seems that "Microsoft.VisualBasic.Embedded" // attribute is added to the assembly's custom attributes. var asm = module.Assembly; if (asm != null && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) return Compiler.VisualBasic; +#endif return Compiler.Other; } From 4fbb11e6dc762dc26788c1d999cb585038e2b83e Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 3 Oct 2018 19:05:01 +0200 Subject: [PATCH 224/511] Add MethodImplAttributes.AggressiveOptimization --- src/DotNet/MethodDef.cs | 8 ++++++++ src/DotNet/MethodImplAttributes.cs | 32 ++++++++++++++++-------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 43172cd91..77ad3b28a 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -843,6 +843,14 @@ public bool IsNoOptimization { set => ModifyImplAttributes(value, MethodImplAttributes.NoOptimization); } + /// + /// Gets/sets the bit + /// + public bool IsAggressiveOptimization { + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.AggressiveOptimization) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.AggressiveOptimization); + } + /// /// Gets/sets the bit /// diff --git a/src/DotNet/MethodImplAttributes.cs b/src/DotNet/MethodImplAttributes.cs index 06b1b45e4..e7f9ed93f 100644 --- a/src/DotNet/MethodImplAttributes.cs +++ b/src/DotNet/MethodImplAttributes.cs @@ -9,38 +9,40 @@ namespace dnlib.DotNet { [Flags] public enum MethodImplAttributes : ushort { /// Flags about code type. - CodeTypeMask = 0x0003, + CodeTypeMask = 0x0003, /// Method impl is IL. - IL = 0x0000, + IL = 0x0000, /// Method impl is native. - Native = 0x0001, + Native = 0x0001, /// Method impl is OPTIL - OPTIL = 0x0002, + OPTIL = 0x0002, /// Method impl is provided by the runtime. - Runtime = 0x0003, + Runtime = 0x0003, /// Flags specifying whether the code is managed or unmanaged. - ManagedMask = 0x0004, + ManagedMask = 0x0004, /// Method impl is unmanaged, otherwise managed. - Unmanaged = 0x0004, + Unmanaged = 0x0004, /// Method impl is managed. - Managed = 0x0000, + Managed = 0x0000, /// Indicates method is defined; used primarily in merge scenarios. - ForwardRef = 0x0010, + ForwardRef = 0x0010, /// Indicates method sig is not to be mangled to do HRESULT conversion. - PreserveSig = 0x0080, + PreserveSig = 0x0080, /// Reserved for internal use. - InternalCall = 0x1000, + InternalCall = 0x1000, /// Method is single threaded through the body. - Synchronized = 0x0020, + Synchronized = 0x0020, /// Method may not be inlined. - NoInlining = 0x0008, + NoInlining = 0x0008, /// Method should be inlined if possible. - AggressiveInlining = 0x0100, + AggressiveInlining = 0x0100, /// Method may not be optimized. - NoOptimization = 0x0040, + NoOptimization = 0x0040, + /// Method may contain hot code and should be aggressively optimized. + AggressiveOptimization = 0x0200, } } From 74f940cb89555e0e8a72b20fe64b53b0d51946ed Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 16 Oct 2018 19:50:19 +0200 Subject: [PATCH 225/511] Use new SDK project --- .gitignore | 5 +- Examples/Examples.csproj | 56 +-- Examples/Properties/AssemblyInfo.cs | 14 - Examples/app.config | 3 - dnlib.netstandard.sln | 25 - dnlib.sln | 29 +- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/Properties/AssemblyInfo.cs | 20 - src/Threading/Lock.cs | 2 +- src/dnlib.csproj | 475 ++---------------- src/dnlib.netstandard.csproj | 29 -- 11 files changed, 78 insertions(+), 582 deletions(-) delete mode 100644 Examples/Properties/AssemblyInfo.cs delete mode 100644 Examples/app.config delete mode 100644 dnlib.netstandard.sln delete mode 100644 src/Properties/AssemblyInfo.cs delete mode 100644 src/dnlib.netstandard.csproj diff --git a/.gitignore b/.gitignore index d1f665933..5a46c7018 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ *.opensdf *.suo /.vs/ -/Debug/ -/Release/ -/Examples/bin/ +bin/ +obj/ *.tmp_proj diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index ca3625492..f1da7ccc2 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,54 +1,12 @@ - - - + + - Debug - x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872} + net35;net46;netcoreapp2.0 Exe - dnlib.Examples - dnlib.Examples - v3.5 - 512 - Client - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - {FDFC1237-143F-4919-8318-4926901F4639} - dnlib - - + - + - - \ No newline at end of file + + diff --git a/Examples/Properties/AssemblyInfo.cs b/Examples/Properties/AssemblyInfo.cs deleted file mode 100644 index 556b997b6..000000000 --- a/Examples/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("dnlib.Examples")] -[assembly: AssemblyDescription("dnlib examples")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("dnlib.Examples")] -[assembly: AssemblyCopyright("Copyright (C) 2012-2014 de4dot@gmail.com")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: ComVisible(false)] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Examples/app.config b/Examples/app.config deleted file mode 100644 index 5044c9820..000000000 --- a/Examples/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/dnlib.netstandard.sln b/dnlib.netstandard.sln deleted file mode 100644 index f724bc63f..000000000 --- a/dnlib.netstandard.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 -MinimumVisualStudioVersion = 15.0.26206.0 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib.netstandard", "src\dnlib.netstandard.csproj", "{80695BC3-65CA-403E-B161-57D4F6EC5CC3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {80695BC3-65CA-403E-B161-57D4F6EC5CC3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {DA3B4267-5AB5-4A1D-A0D5-CF49A2882567} - EndGlobalSection -EndGlobal diff --git a/dnlib.sln b/dnlib.sln index 9127821ce..87236a6c1 100644 --- a/dnlib.sln +++ b/dnlib.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 15.0.26206.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dnlib", "src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib", "src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples", "Examples\Examples.csproj", "{F27E72B5-C4BD-40BF-AD19-4C8A99B55872}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples", "Examples\Examples.csproj", "{F27E72B5-C4BD-40BF-AD19-4C8A99B55872}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,18 +27,23 @@ Global {FDFC1237-143F-4919-8318-4926901F4639}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {FDFC1237-143F-4919-8318-4926901F4639}.Release|Mixed Platforms.Build.0 = Release|Any CPU {FDFC1237-143F-4919-8318-4926901F4639}.Release|x86.ActiveCfg = Release|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Any CPU.ActiveCfg = Debug|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.ActiveCfg = Debug|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.Build.0 = Debug|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Any CPU.ActiveCfg = Release|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.Build.0 = Release|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.ActiveCfg = Release|x86 - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.Build.0 = Release|x86 + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.ActiveCfg = Debug|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.Build.0 = Debug|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Any CPU.Build.0 = Release|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.ActiveCfg = Release|Any CPU + {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {49902A67-E85B-44E8-9C4F-26F8854AA894} + EndGlobalSection EndGlobal diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index 36776ce43..c0a6ac89f 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -27,7 +27,7 @@ static class MethodTableToTypeConverter { static MethodTableToTypeConverter() { if (ptrFieldInfo == null) { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETCOREAPP2_0 var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); #else var asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs deleted file mode 100644 index 26dcfd33f..000000000 --- a/src/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Reflection; -using System.Runtime.InteropServices; - -#if THREAD_SAFE -[assembly: AssemblyTitle("dnlib (thread safe)")] -#else -[assembly: AssemblyTitle("dnlib")] -#endif -[assembly: AssemblyDescription(".NET assembly reader/writer")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("dnlib")] -[assembly: AssemblyCopyright("Copyright (C) 2012-2018 de4dot@gmail.com")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: ComVisible(false)] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] diff --git a/src/Threading/Lock.cs b/src/Threading/Lock.cs index 2d21c6b08..c6f58b2b6 100644 --- a/src/Threading/Lock.cs +++ b/src/Threading/Lock.cs @@ -21,7 +21,7 @@ protected LockException(SerializationInfo info, StreamingContext context) } /// - /// Simple class using and + /// Simple class using Monitor.Enter() and Monitor.Exit() /// and just like ReaderWriterLockSlim it prevents recursive locks. It doesn't support /// multiple readers. A reader lock is the same as a writer lock. /// diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 5a068c266..94c9f977d 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,440 +1,65 @@ - - - + + + - Debug - AnyCPU - {FDFC1237-143F-4919-8318-4926901F4639} - Library - dnlib + netstandard2.0;net35;net46;netcoreapp2.0 + + $(DefineConstants);$(MoreDefineConstants) + .NET assembly reader/writer + $(Description) + Copyright (C) 2012-2018 de4dot@gmail.com + dnlib + $(AssemblyTitle) (thread safe) dnlib - v3.5 - 512 - true - ..\dnlib.snk + en + 3.0.0 + $(Version) + 0xd4d + strict latest - Client - - - true - - /usr/lib/mono/2.0-api - /usr/local/lib/mono/2.0-api - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.0-api - /usr/local/Cellar/mono/4.6.2.16/lib/mono/2.0-api - - - true - portable - false - ..\Debug\bin\ - TRACE;DEBUG;$(MoreDefineConstants) - prompt - 4 - ..\Debug\bin\dnlib.xml - true - - - true - portable - true - ..\Release\bin\ - TRACE;$(MoreDefineConstants) - prompt - 4 - ..\Release\bin\dnlib.xml true + true + ..\dnlib.snk + true + true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + LICENSE.txt - - README.md - - \ No newline at end of file + + + + + + + + + + + + + + $(DefineConstants);DEBUG;TRACE + + + $(DefineConstants);TRACE + + + + true + + /usr/lib/mono/2.0-api + /usr/local/lib/mono/2.0-api + /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.0-api + /usr/local/Cellar/mono/4.6.2.16/lib/mono/2.0-api + + + diff --git a/src/dnlib.netstandard.csproj b/src/dnlib.netstandard.csproj deleted file mode 100644 index 034d66c97..000000000 --- a/src/dnlib.netstandard.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - netstandard2.0;net35 - dnlib - dnlib - true - true - ..\dnlib.snk - true - ..\$(Configuration)\bin - $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml - false - 512 - strict - latest - true - portable - - - - - - - - - - - From 000ea86848e71c7202c7220a7f6b5a0203bf0e02 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 17 Oct 2018 06:40:31 +0200 Subject: [PATCH 226/511] Remove assert --- src/DotNet/CpuArch.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index f13d2220b..6814f59a4 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info using System; -using System.Diagnostics; using dnlib.DotNet.Writer; using dnlib.IO; using dnlib.PE; @@ -94,11 +93,8 @@ public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { /// PE image /// Updated with RVA of func field /// - public bool TryGetExportedRvaFromStub(ref DataReader reader, IPEImage peImage, out uint funcRva) { - bool b = TryGetExportedRvaFromStubCore(ref reader, peImage, out funcRva); - Debug.Assert(b); - return b; - } + public bool TryGetExportedRvaFromStub(ref DataReader reader, IPEImage peImage, out uint funcRva) => + TryGetExportedRvaFromStubCore(ref reader, peImage, out funcRva); protected abstract bool TryGetExportedRvaFromStubCore(ref DataReader reader, IPEImage peImage, out uint funcRva); From 6a7b324706415a70cb8b1dd365c3020c3ff827e1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 17 Oct 2018 07:43:54 +0200 Subject: [PATCH 227/511] Update README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 138c2262a..66244abae 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,6 @@ v3.0 requires VS2017 (C#7.2) or later to build it. See below for breaking change An [older v2.1 branch](https://github.com/0xd4d/dnlib/tree/v2.1_VS2010) can be used to build with older VS versions. This branch won't get any new updates. -There are two project files, one for .NET Framework 3.5 or later (`src/dnlib.csproj`) and another one for netstandard 2.0 (`src/dnlib.netstandard.csproj`). - v3.0 breaking changes --------------------- - VS2017, C# 7.2 is required to compile it From 4e0ce0094624bd399d474a4600d392431600023a Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 17 Oct 2018 10:17:40 +0200 Subject: [PATCH 228/511] net46 -> net461 --- Examples/Examples.csproj | 2 +- src/dnlib.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index f1da7ccc2..3ee5bf726 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,7 +1,7 @@  - net35;net46;netcoreapp2.0 + net35;net461;netcoreapp2.0 Exe diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 94c9f977d..6393b1a94 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -3,7 +3,7 @@ - netstandard2.0;net35;net46;netcoreapp2.0 + netstandard2.0;net35;net461;netcoreapp2.0 $(DefineConstants);$(MoreDefineConstants) .NET assembly reader/writer From 5886f7f7fff8fb8cfc1e37ce48b6734a150825d8 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Fri, 26 Oct 2018 00:27:12 +0800 Subject: [PATCH 229/511] Remove assert (#219) --- src/DotNet/MethodExportInfoProvider.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/DotNet/MethodExportInfoProvider.cs b/src/DotNet/MethodExportInfoProvider.cs index f56d86c0b..7d18193eb 100644 --- a/src/DotNet/MethodExportInfoProvider.cs +++ b/src/DotNet/MethodExportInfoProvider.cs @@ -54,12 +54,8 @@ void Initialize(ModuleDefMD module) { while (numSlots-- > 0 && reader.CanRead(slotSize)) { var tokenPos = reader.Position; uint token = reader.ReadUInt32(); - bool b = offsetToInfo.TryGetValue(tokenPos, out var exportInfo); - Debug.Assert(token == 0 || b); - if (b) { - exportInfo = new MethodExportInfo(exportInfo.Name, exportInfo.Ordinal, exportOptions); - toInfo[token] = exportInfo; - } + if (offsetToInfo.TryGetValue(tokenPos, out var exportInfo)) + toInfo[token] = new MethodExportInfo(exportInfo.Name, exportInfo.Ordinal, exportOptions); if (slotSize == 8) reader.ReadUInt32(); } From e4fe68d5b4d5776f1f8e737b88ee092f5df83040 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 2 Nov 2018 20:36:47 +0100 Subject: [PATCH 230/511] Update #ifs --- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/PE/ProcessorArchUtils.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index c0a6ac89f..2b6314b33 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -27,7 +27,7 @@ static class MethodTableToTypeConverter { static MethodTableToTypeConverter() { if (ptrFieldInfo == null) { -#if NETSTANDARD2_0 || NETCOREAPP2_0 +#if NETSTANDARD2_0 || NETCOREAPP var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); #else var asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index 2817cce7f..8fad2555f 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -16,7 +16,7 @@ public static Machine GetProcessCpuArchitecture() { } static class RuntimeInformationUtils { -#if NETSTANDARD2_0 +#if NETSTANDARD2_0 || NETCOREAPP public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => TryGetArchitecture((int)RuntimeInformation.ProcessArchitecture, out machine); #else From d4afc560c978fa46d4b4cb4f2fb6bfe6fd6fdbd9 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 5 Nov 2018 20:49:45 +0100 Subject: [PATCH 231/511] Misc --- src/DefaultDllImportSearchPathsAttribute.cs | 2 ++ ...ndleProcessCorruptedStateExceptionsAttribute.cs | 2 ++ src/IO/DataReader.cs | 10 +++++----- src/IO/DataReaderFactory.cs | 14 ++++++++++---- src/dnlib.csproj | 9 ++------- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/DefaultDllImportSearchPathsAttribute.cs b/src/DefaultDllImportSearchPathsAttribute.cs index 0c0d17266..3c8628c79 100644 --- a/src/DefaultDllImportSearchPathsAttribute.cs +++ b/src/DefaultDllImportSearchPathsAttribute.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +#if NET35 namespace System.Runtime.InteropServices { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method, AllowMultiple = false)] sealed class DefaultDllImportSearchPathsAttribute : Attribute { @@ -19,3 +20,4 @@ enum DllImportSearchPath { SafeDirectories = 0x1000, } } +#endif diff --git a/src/HandleProcessCorruptedStateExceptionsAttribute.cs b/src/HandleProcessCorruptedStateExceptionsAttribute.cs index cb3f54202..82c75e2af 100644 --- a/src/HandleProcessCorruptedStateExceptionsAttribute.cs +++ b/src/HandleProcessCorruptedStateExceptionsAttribute.cs @@ -1,7 +1,9 @@ // dnlib: See LICENSE.txt for more info +#if NET35 namespace System.Runtime.ExceptionServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] sealed class HandleProcessCorruptedStateExceptionsAttribute : Attribute { } } +#endif diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index a6d3ed149..4c2875a4d 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -101,11 +101,11 @@ void VerifyState() { Debug.Assert(currentOffset <= endOffset); } - void ThrowNoMoreBytesLeft() => throw new DataReaderException("There's not enough bytes left to read"); - void ThrowDataReaderException(string message) => throw new DataReaderException(message); - void ThrowInvalidOperationException() => throw new InvalidOperationException(); - void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName); - void ThrowInvalidArgument(string paramName) => throw new DataReaderException("Invalid argument value"); + static void ThrowNoMoreBytesLeft() => throw new DataReaderException("There's not enough bytes left to read"); + static void ThrowDataReaderException(string message) => throw new DataReaderException(message); + static void ThrowInvalidOperationException() => throw new InvalidOperationException(); + static void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName); + static void ThrowInvalidArgument(string paramName) => throw new DataReaderException("Invalid argument value"); /// /// Resets the reader so it points to the start of the data diff --git a/src/IO/DataReaderFactory.cs b/src/IO/DataReaderFactory.cs index cb52bacfe..1cca2f230 100644 --- a/src/IO/DataReaderFactory.cs +++ b/src/IO/DataReaderFactory.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Diagnostics; namespace dnlib.IO { /// @@ -36,6 +37,13 @@ public abstract class DataReaderFactory : IDisposable { static void ThrowArgumentOutOfRangeException(string paramName) => throw new ArgumentOutOfRangeException(paramName); + static void Throw_CreateReader_2(int offset, int length) { + if (offset < 0) + throw new ArgumentOutOfRangeException(nameof(offset)); + Debug.Assert(length < 0); + throw new ArgumentOutOfRangeException(nameof(length)); + } + /// /// Creates a data reader /// @@ -67,10 +75,8 @@ public DataReader CreateReader(int offset, uint length) { /// Length of data /// public DataReader CreateReader(int offset, int length) { - if (offset < 0) - ThrowArgumentOutOfRangeException(nameof(offset)); - if (length < 0) - ThrowArgumentOutOfRangeException(nameof(length)); + if (offset < 0 || length < 0) + Throw_CreateReader_2(offset, length); return CreateReader((uint)offset, (uint)length); } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 6393b1a94..a20053618 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,4 +1,4 @@ - + @@ -35,11 +35,6 @@ - - - - - @@ -53,7 +48,7 @@ $(DefineConstants);TRACE - + true /usr/lib/mono/2.0-api From 6a52e50333486af740f098735dd39c0876e1fbee Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 10 Nov 2018 23:11:25 +0100 Subject: [PATCH 232/511] Remove unused nuget package ref --- src/dnlib.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a20053618..29168e55c 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -38,7 +38,6 @@ - From 49c3cd62965d58351bc747cde9129ff72d76ec42 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 14 Nov 2018 15:45:25 +0100 Subject: [PATCH 233/511] Update .gitignore --- .gitignore | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 5a46c7018..4b82ccd91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,3 @@ -*~ -*/obj/ -*.csproj.user -*.sdf -*.opensdf -*.suo -/.vs/ +.vs/ bin/ obj/ -*.tmp_proj From e4b746d96a11b5d6b0e317d538566509c1e7210c Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 16 Nov 2018 01:27:36 +0100 Subject: [PATCH 234/511] netcoreapp2.0 -> netcoreapp2.1 since MS doesn't support 2.0 anymore --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 29168e55c..ac816ed0a 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -3,7 +3,7 @@ - netstandard2.0;net35;net461;netcoreapp2.0 + netstandard2.0;net35;net461;netcoreapp2.1 $(DefineConstants);$(MoreDefineConstants) .NET assembly reader/writer From 4841b5dc8531475958c3686cd27c7766cd986c38 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 16 Nov 2018 11:26:41 +0100 Subject: [PATCH 235/511] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66244abae..12f7cfd09 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Want to say thanks? Click the star at the top of the page. Compiling --------- -v3.0 requires VS2017 (C#7.2) or later to build it. See below for breaking changes going from 2.1 to 3.0 +v3.0 requires VS2017 (C#7.3) or later to build it. .NET Core SDK 2.1 or later is also required. See below for breaking changes going from 2.1 to 3.0 An [older v2.1 branch](https://github.com/0xd4d/dnlib/tree/v2.1_VS2010) can be used to build with older VS versions. This branch won't get any new updates. From 67c321d7a4219415492a910d22c95f5efb0c30b8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 17 Nov 2018 07:21:08 +0100 Subject: [PATCH 236/511] Disable net35 target if prop is defined --- src/dnlib.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index ac816ed0a..ca8b54532 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -3,7 +3,8 @@ - netstandard2.0;net35;net461;netcoreapp2.1 + netstandard2.0;net461;netcoreapp2.1 + $(TargetFrameworks);net35 $(DefineConstants);$(MoreDefineConstants) .NET assembly reader/writer From c5a232a775223661766029760801d7b3b2e541cf Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 9 Dec 2018 17:00:22 +0100 Subject: [PATCH 237/511] Update csproj, add appveyor.yml, add credits to readme --- Directory.Build.props | 3 --- LICENSE.txt | 13 ------------- README.md | 25 ++++++++++++------------- appveyor.yml | 27 +++++++++++++++++++++++++++ src/dnlib.csproj | 41 +++++++++++++++++++++++++++-------------- 5 files changed, 66 insertions(+), 43 deletions(-) delete mode 100644 Directory.Build.props create mode 100644 appveyor.yml diff --git a/Directory.Build.props b/Directory.Build.props deleted file mode 100644 index d014f64c6..000000000 --- a/Directory.Build.props +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt index 6b8c1eacf..bc03458ac 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,18 +1,5 @@ -dnlib: .NET assembly library -https://github.com/0xd4d/dnlib - Copyright (C) 2012-2018 de4dot@gmail.com -Contributors ------------- - -Ki, "yck1509 ", https://github.com/yck1509 -kiootic, "kiootic ", https://github.com/kiootic -SlowLogicBoy, https://github.com/SlowLogicBoy - -MIT LICENSE ------------ - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including diff --git a/README.md b/README.md index 12f7cfd09..0eb94789e 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,11 @@ -.NET module/assembly reader/writer library written for [de4dot](https://github.com/0xd4d/de4dot/). +# dnlib [![Build status](https://ci.appveyor.com/api/projects/status/h7dqmfac6qjh4hap/branch/master?svg=true)](https://ci.appveyor.com/project/0xd4d/dnlib/branch/master) +.NET module/assembly reader/writer library -dnlib was created because de4dot needed a robust .NET assembly library that -could handle all types of obfuscated assemblies. de4dot used to use Mono.Cecil -but since Mono.Cecil can't handle obfuscated assemblies, doesn't fully support -mixed mode assemblies, doesn't read .NET assemblies the same way the [CLR](http://en.wikipedia.org/wiki/Common_Language_Runtime) does -and many other missing features de4dot needed, dnlib was a necessity. The API -is similar because it made porting de4dot to dnlib a lot easier. +NuGet +----- -For other applications using dnlib, see [dnSpy](https://github.com/0xd4d/dnSpy) and -[ConfuserEx](https://github.com/yck1509/ConfuserEx/) (a .NET obfuscator). They use -many of the more advanced features of dnlib. Have a look at ConfuserEx' writer code -which gets executed during the assembly writing process. - -Want to say thanks? Click the star at the top of the page. +Soon... Compiling --------- @@ -603,3 +595,10 @@ To get a list of all valid TypeDef rids (row IDs), use this code: ``` You don't need to create a `ModuleDefMD`, though. See `MetadataFactory`. + +Credits +------- + +Big thanks to [Ki](https://github.com/yck1509) for writing the managed Windows PDB reader! + +[List of all contributors](https://github.com/0xd4d/dnlib/graphs/contributors) diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..63eff0cfd --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,27 @@ +version: x.x.{build} +image: Visual Studio 2017 +configuration: Release +before_build: +- cmd: appveyor-retry nuget restore +build: + project: dnlib.sln + parallel: true + verbosity: normal +before_package: +- cmd: msbuild /p:Configuration=Release /t:Pack dnlib.sln +artifacts: +- path: src\bin\Release\*.nupkg + name: dnlib NuGet Packages +notifications: +- provider: Email + to: + - de4dot@gmail.com + on_build_success: false + on_build_failure: true + on_build_status_changed: false +deploy: +- provider: NuGet + on: + APPVEYOR_REPO_TAG: true + api_key: + secure: en/ChGrnyp08i9CgI/8WXLKhl0OHCpPsuBSRv9wt286kvKlI9P4732egbzq+ycfx diff --git a/src/dnlib.csproj b/src/dnlib.csproj index ca8b54532..a03108be5 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -3,37 +3,50 @@ + $(DefineConstants);$(MoreDefineConstants) + $(DefineConstants);THREAD_SAFE netstandard2.0;net461;netcoreapp2.1 + $(TargetFrameworks);net35 - $(DefineConstants);$(MoreDefineConstants) - .NET assembly reader/writer + Reads and writes .NET assemblies and modules $(Description) Copyright (C) 2012-2018 de4dot@gmail.com dnlib $(AssemblyTitle) (thread safe) dnlib - en + dnlib + en-US 3.0.0 $(Version) 0xd4d - + https://github.com/0xd4d/dnlib + https://github.com/0xd4d/dnlib/blob/master/LICENSE.txt + $(InformationalVersion) + dotnet;assembly;module;reader;writer;PDB;PortablePdb;WindowsPdb;IL;CIL;MSIL;metadata strict + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. + + + ..\dnlib.snk + true + latest true - true - ..\dnlib.snk - true - true - - LICENSE.txt - - - README.md - + + + + + + From 2863836bc8de65d662594f9b1237ed215c7e1a8e Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 9 Dec 2018 17:06:28 +0100 Subject: [PATCH 238/511] Add /m msbuild switch --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 63eff0cfd..d5b3ae7f5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ build: parallel: true verbosity: normal before_package: -- cmd: msbuild /p:Configuration=Release /t:Pack dnlib.sln +- cmd: msbuild /m /p:Configuration=Release /t:Pack dnlib.sln artifacts: - path: src\bin\Release\*.nupkg name: dnlib NuGet Packages From 78c9ed036a3b37d453e6b6fa3afeb4140843d363 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 10 Dec 2018 02:38:30 +0100 Subject: [PATCH 239/511] Rename property --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a03108be5..5c445d064 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -4,7 +4,7 @@ $(DefineConstants);$(MoreDefineConstants) - $(DefineConstants);THREAD_SAFE + $(DefineConstants);THREAD_SAFE netstandard2.0;net461;netcoreapp2.1 From 12ed69f434ebe81ec552c35e564e7fd3ca1a411e Mon Sep 17 00:00:00 2001 From: user Date: Wed, 12 Dec 2018 19:31:32 +0200 Subject: [PATCH 240/511] avoid throwing exception when parsing invalid CustomMarshaler attribute --- src/DotNet/MarshalBlobReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/MarshalBlobReader.cs b/src/DotNet/MarshalBlobReader.cs index f37f2f01b..3ab6325d8 100644 --- a/src/DotNet/MarshalBlobReader.cs +++ b/src/DotNet/MarshalBlobReader.cs @@ -108,7 +108,7 @@ MarshalType Read() { var guid = ReadUTF8String(); var nativeTypeName = ReadUTF8String(); var custMarshalerName = ReadUTF8String(); - var cmRef = TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(custMarshalerName), new CAAssemblyRefFinder(module), gpContext); + var cmRef = custMarshalerName.DataLength == 0 ? null : TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(custMarshalerName), new CAAssemblyRefFinder(module), gpContext); var cookie = ReadUTF8String(); returnValue = new CustomMarshalType(guid, nativeTypeName, cmRef, cookie); break; From 3a956d3c86fefcc111bc91cc0211402fa2cbe564 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 13 Dec 2018 10:50:05 +0100 Subject: [PATCH 241/511] Ignore params --- src/DotNet/Pdb/Managed/DbiScope.cs | 4 ++-- src/DotNet/Pdb/Managed/DbiVariable.cs | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 4ff85e8ca..2baca5474 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -97,8 +97,8 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) break; case SymbolType.S_MANSLOT: { var variable = new DbiVariable(); - variable.Read(ref reader); - localsList.Add(variable); + if (variable.Read(ref reader)) + localsList.Add(variable); break; } case SymbolType.S_OEM: diff --git a/src/DotNet/Pdb/Managed/DbiVariable.cs b/src/DotNet/Pdb/Managed/DbiVariable.cs index 669aaef4a..8aa1537c0 100644 --- a/src/DotNet/Pdb/Managed/DbiVariable.cs +++ b/src/DotNet/Pdb/Managed/DbiVariable.cs @@ -17,11 +17,15 @@ sealed class DbiVariable : SymbolVariable { public override PdbCustomDebugInfo[] CustomDebugInfos => Array2.Empty(); - public void Read(ref DataReader reader) { + public bool Read(ref DataReader reader) { index = reader.ReadInt32(); reader.Position += 10; - attributes = GetAttributes(reader.ReadUInt16()); + ushort flags = reader.ReadUInt16(); + attributes = GetAttributes(flags); name = PdbReader.ReadCString(ref reader); + + const int fIsParam = 1; + return (flags & fIsParam) == 0; } static PdbLocalAttributes GetAttributes(uint flags) { From 3fa15ab8a1c9bcb03845768ccb1ebff385e69d7c Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 13 Dec 2018 23:00:55 +0100 Subject: [PATCH 242/511] Remove addOtherSearchPaths option, move that code to de4dot where it belongs --- src/DotNet/AssemblyResolver.cs | 159 +-------------------------------- src/DotNet/ModuleDef.cs | 6 +- 2 files changed, 4 insertions(+), 161 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 9a0f6bc43..d87dda8e3 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -197,28 +197,16 @@ public bool UseGAC { /// Default constructor /// public AssemblyResolver() - : this(null, true) { + : this(null) { } /// /// Constructor /// /// Module context for all resolved assemblies - public AssemblyResolver(ModuleContext defaultModuleContext) - : this(defaultModuleContext, true) { - } - - /// - /// Constructor - /// - /// Module context for all resolved assemblies - /// If true, add other common assembly search - /// paths, not just the module search paths and the GAC. - public AssemblyResolver(ModuleContext defaultModuleContext, bool addOtherSearchPaths) { + public AssemblyResolver(ModuleContext defaultModuleContext) { this.defaultModuleContext = defaultModuleContext; enableFrameworkRedirect = true; - if (addOtherSearchPaths) - AddOtherSearchPaths(postSearchPaths); } /// @@ -770,148 +758,5 @@ IEnumerable GetPrivatePaths(string baseDir, string configFileName) { return searchPaths; } - - /// - /// Add other common search paths - /// - /// A list that gets updated with the new paths - protected static void AddOtherSearchPaths(IList paths) { - var dirPF = Environment.GetEnvironmentVariable("ProgramFiles"); - AddOtherAssemblySearchPaths(paths, dirPF); - var dirPFx86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); - if (!StringComparer.OrdinalIgnoreCase.Equals(dirPF, dirPFx86)) - AddOtherAssemblySearchPaths(paths, dirPFx86); - - var windir = Environment.GetEnvironmentVariable("WINDIR"); - if (!string.IsNullOrEmpty(windir)) { - AddIfExists(paths, windir, @"Microsoft.NET\Framework\v1.1.4322"); - AddIfExists(paths, windir, @"Microsoft.NET\Framework\v1.0.3705"); - } - } - - static void AddOtherAssemblySearchPaths(IList paths, string path) { - if (string.IsNullOrEmpty(path)) - return; - AddSilverlightDirs(paths, Path.Combine(path, @"Microsoft Silverlight")); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v2.0\Libraries\Client"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v2.0\Libraries\Server"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v2.0\Reference Assemblies"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Client"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Server"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Client"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Server"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v5.0\Libraries\Client"); - AddIfExists(paths, path, @"Microsoft SDKs\Silverlight\v5.0\Libraries\Server"); - AddIfExists(paths, path, @"Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE"); - AddIfExists(paths, path, @"Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETCore\v5.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETMicroFramework\v3.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETMicroFramework\v4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETMicroFramework\v4.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETMicroFramework\v4.2"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETMicroFramework\v4.3"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v4.6"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\.NETPortable\v5.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\v3.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\v3.5"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v3.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v5.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\Framework\WindowsPhoneApp\v8.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETCore\3.259.4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETCore\3.259.3.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETCore\3.78.4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETCore\3.78.3.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETCore\3.7.4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETCore\3.3.1.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETFramework\v2.0\2.3.0.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.4.0.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETPortable\2.3.5.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETPortable\2.3.5.1"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\.NETPortable\3.47.4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\2.0\Runtime\v2.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\2.0\Runtime\v4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\3.0\Runtime\.NETPortable"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\3.0\Runtime\v2.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\FSharp\3.0\Runtime\v4.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\WindowsPowerShell\v1.0"); - AddIfExists(paths, path, @"Reference Assemblies\Microsoft\WindowsPowerShell\3.0"); - AddIfExists(paths, path, @"Microsoft Visual Studio .NET\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio .NET\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio .NET 2003\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio .NET 2003\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 8\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies"); - AddIfExists(paths, path, @"Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v2.0\References\Windows\x86"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v2.0\References\Xbox360"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v3.0\References\Windows\x86"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v3.0\References\Xbox360"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v3.0\References\Zune"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v3.1\References\Windows\x86"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v3.1\References\Xbox360"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v3.1\References\Zune"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v4.0\References\Windows\x86"); - AddIfExists(paths, path, @"Microsoft XNA\XNA Game Studio\v4.0\References\Xbox360"); - AddIfExists(paths, path, @"Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Designtimereferences"); - AddIfExists(paths, path, @"Windows CE Tools\wce500\Windows Mobile 5.0 Smartphone SDK\Designtimereferences"); - AddIfExists(paths, path, @"Windows Mobile 5.0 SDK R2\Managed Libraries"); - AddIfExists(paths, path, @"Windows Mobile 6 SDK\Managed Libraries"); - AddIfExists(paths, path, @"Windows Mobile 6.5.3 DTK\Managed Libraries"); - AddIfExists(paths, path, @"Microsoft SQL Server\90\SDK\Assemblies"); - AddIfExists(paths, path, @"Microsoft SQL Server\100\SDK\Assemblies"); - AddIfExists(paths, path, @"Microsoft SQL Server\110\SDK\Assemblies"); - AddIfExists(paths, path, @"Microsoft SQL Server\120\SDK\Assemblies"); - AddIfExists(paths, path, @"Microsoft ASP.NET\ASP.NET MVC 2\Assemblies"); - AddIfExists(paths, path, @"Microsoft ASP.NET\ASP.NET MVC 3\Assemblies"); - AddIfExists(paths, path, @"Microsoft ASP.NET\ASP.NET MVC 4\Assemblies"); - AddIfExists(paths, path, @"Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies"); - AddIfExists(paths, path, @"Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies"); - AddIfExists(paths, path, @"Microsoft SDKs\F#\3.0\Framework\v4.0"); - } - - static void AddSilverlightDirs(IList paths, string basePath) { - if (!Directory.Exists(basePath)) - return; - try { - var di = new DirectoryInfo(basePath); - foreach (var dir in di.GetDirectories()) { - if (Regex.IsMatch(dir.Name, @"^\d+(?:\.\d+){3}$")) - AddIfExists(paths, basePath, dir.Name); - } - } - catch { - } - } - - static void AddIfExists(IList paths, string basePath, string extraPath) { - var path = Path.Combine(basePath, extraPath); - if (Directory.Exists(path)) - paths.Add(path); - } } } diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index ed9c78c16..57517c3d2 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1244,12 +1244,10 @@ public TypeDef Find(ITypeDefOrRef typeRef) { /// Creates a new instance. There should normally only be one /// instance shared by all s. /// - /// If true, add other common assembly search - /// paths, not just the module search paths and the GAC. /// A new instance - public static ModuleContext CreateModuleContext(bool addOtherSearchPaths = true) { + public static ModuleContext CreateModuleContext() { var ctx = new ModuleContext(); - var asmRes = new AssemblyResolver(ctx, addOtherSearchPaths); + var asmRes = new AssemblyResolver(ctx); var res = new Resolver(asmRes); ctx.AssemblyResolver = asmRes; ctx.Resolver = res; From 4eff4c5e9f093fef80005120bedd0e1d6e951823 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 15 Dec 2018 09:14:36 +0100 Subject: [PATCH 243/511] Verify length --- src/DotNet/Pdb/Managed/DbiFunction.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index 2a0973b7c..d5d518819 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -68,7 +68,7 @@ public override IList SequencePoints { public int AsyncKickoffMethod { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data == null) + if (data == null || data.Length < 4) return 0; return BitConverter.ToInt32(data, 0); } @@ -77,7 +77,7 @@ public int AsyncKickoffMethod { public uint? AsyncCatchHandlerILOffset { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data == null) + if (data == null || data.Length < 8) return null; uint token = BitConverter.ToUInt32(data, 4); return token == uint.MaxValue ? (uint?)null : token; @@ -95,7 +95,7 @@ public IList AsyncStepInfos { SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data == null) + if (data == null || data.Length < 12) return Array2.Empty(); int pos = 8; int count = BitConverter.ToInt32(data, pos); From 9308667025133a652cbcb4d392748afeeaf3fbe2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Dec 2018 06:46:19 +0100 Subject: [PATCH 244/511] Use ignore case key comparer --- src/DotNet/AssemblyResolver.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index d87dda8e3..25851cb3f 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text.RegularExpressions; using System.Xml; using dnlib.Threading; @@ -29,7 +28,7 @@ public class AssemblyResolver : IAssemblyResolver { ModuleContext defaultModuleContext; readonly Dictionary> moduleSearchPaths = new Dictionary>(); - readonly Dictionary cachedAssemblies = new Dictionary(StringComparer.Ordinal); + readonly Dictionary cachedAssemblies = new Dictionary(StringComparer.OrdinalIgnoreCase); readonly IList preSearchPaths = new List(); readonly IList postSearchPaths = new List(); bool findExactMatch; @@ -368,7 +367,7 @@ public void Clear() { static string GetAssemblyNameKey(IAssembly asmName) { // Make sure the name contains PublicKeyToken= and not PublicKey= - return asmName.FullNameToken.ToUpperInvariant(); + return asmName.FullNameToken; } AssemblyDef Resolve2(IAssembly assembly, ModuleDef sourceModule) { From e61b19f2a71b3f0c7df4c5dd17522b6b050d83dc Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Dec 2018 06:50:21 +0100 Subject: [PATCH 245/511] Update DebuggerTypeProxy attrs --- src/DotNet/Emit/LocalList.cs | 2 +- src/DotNet/ParameterList.cs | 2 +- src/Utils/CollectionDebugView.cs | 16 +++++++++++++++- src/Utils/LazyList.cs | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Emit/LocalList.cs b/src/DotNet/Emit/LocalList.cs index 3a8aebf5b..700f557d3 100644 --- a/src/DotNet/Emit/LocalList.cs +++ b/src/DotNet/Emit/LocalList.cs @@ -10,7 +10,7 @@ namespace dnlib.DotNet.Emit { /// A collection of s /// [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(CollectionDebugView<>))] + [DebuggerTypeProxy(typeof(LocalList_CollectionDebugView))] public sealed class LocalList : IListListener, IList { readonly LazyList locals; diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index d76b7b278..12221d9ce 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -11,7 +11,7 @@ namespace dnlib.DotNet { /// A list of all method parameters /// [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(CollectionDebugView<>))] + [DebuggerTypeProxy(typeof(ParameterList_CollectionDebugView))] public sealed class ParameterList : IList { readonly MethodDef method; readonly List parameters; diff --git a/src/Utils/CollectionDebugView.cs b/src/Utils/CollectionDebugView.cs index e2a68207f..60f417e1d 100644 --- a/src/Utils/CollectionDebugView.cs +++ b/src/Utils/CollectionDebugView.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using dnlib.DotNet; +using dnlib.DotNet.Emit; namespace dnlib.Utils { - sealed class CollectionDebugView { + class CollectionDebugView { readonly ICollection list; public CollectionDebugView(ICollection list) => this.list = list ?? throw new ArgumentNullException(nameof(list)); @@ -18,4 +20,16 @@ public TValue[] Items { } } } + + class CollectionDebugView : CollectionDebugView { + public CollectionDebugView(ICollection list) : base(list) { } + } + + sealed class LocalList_CollectionDebugView : CollectionDebugView { + public LocalList_CollectionDebugView(LocalList list) : base(list) { } + } + + sealed class ParameterList_CollectionDebugView : CollectionDebugView { + public ParameterList_CollectionDebugView(ParameterList list) : base(list) { } + } } diff --git a/src/Utils/LazyList.cs b/src/Utils/LazyList.cs index 79b6b8606..e79114ab9 100644 --- a/src/Utils/LazyList.cs +++ b/src/Utils/LazyList.cs @@ -430,7 +430,7 @@ internal IEnumerable GetEnumerable_NoLock() { /// Type to store in list /// Type of the context passed to the read-value delegate [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(CollectionDebugView<>))] + [DebuggerTypeProxy(typeof(CollectionDebugView<,>))] public class LazyList : LazyList, ILazyList where TValue : class { /*readonly*/ TContext context; readonly Func readOriginalValue; From e6c64e456345a19bb7daa0096d545f663d9a308b Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Dec 2018 06:53:24 +0100 Subject: [PATCH 246/511] Update VB asm check --- src/DotNet/Pdb/PdbState.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 8727a0c62..95f907239 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -222,7 +222,7 @@ static Compiler CalculateCompiler(ModuleDef module) { return Compiler.Other; foreach (var asmRef in module.GetAssemblyRefs()) { - if (asmRef.Name == nameAssemblyVisualBasic) + if (asmRef.Name == nameAssemblyVisualBasic || asmRef.Name == nameAssemblyVisualBasicCore) return Compiler.VisualBasic; } @@ -238,6 +238,8 @@ static Compiler CalculateCompiler(ModuleDef module) { return Compiler.Other; } static readonly UTF8String nameAssemblyVisualBasic = new UTF8String("Microsoft.VisualBasic"); + // .NET Core 3.0 has this assembly because Microsoft.VisualBasic contains WinForms refs + static readonly UTF8String nameAssemblyVisualBasicCore = new UTF8String("Microsoft.VisualBasic.Core"); void AddSequencePoints(CilBody body, SymbolMethod method) { int instrIndex = 0; From 6521c180fb24a3ae25009ba4d2c7ce68b326d69f Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Dec 2018 06:54:32 +0100 Subject: [PATCH 247/511] Add two more netf asm redir APIs --- src/DotNet/FrameworkRedirect.cs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/DotNet/FrameworkRedirect.cs b/src/DotNet/FrameworkRedirect.cs index 616504aff..c4900fc14 100644 --- a/src/DotNet/FrameworkRedirect.cs +++ b/src/DotNet/FrameworkRedirect.cs @@ -295,7 +295,7 @@ static void InitFrameworkRedirectV4() { } /// - /// Redirects a .NET framework assembly from an older version to the correct version + /// Redirects a .NET Framework assembly from an older version to the correct version /// loaded at runtime. /// /// Current assembly reference that might get updated @@ -318,5 +318,36 @@ public static void ApplyFrameworkRedirect(ref IAssembly assembly, ModuleDef sour assembly = new AssemblyNameInfo(assembly); assembly.Version = redirect.redirectVersion; } + + /// + /// Redirects a .NET Framework 2.0-3.5 assembly from an older version to the correct version + /// loaded at runtime. + /// + /// Current assembly reference that might get updated + public static void ApplyFrameworkRedirectV2(ref IAssembly assembly) => + ApplyFrameworkRedirect(ref assembly, frmRedir2); + + /// + /// Redirects a .NET Framework 4.0+ assembly from an older version to the correct version + /// loaded at runtime. + /// + /// Current assembly reference that might get updated + public static void ApplyFrameworkRedirectV4(ref IAssembly assembly) => + ApplyFrameworkRedirect(ref assembly, frmRedir4); + + static void ApplyFrameworkRedirect(ref IAssembly assembly, Dictionary frmRedir) { + if (!Utils.LocaleEquals(assembly.Culture, "")) + return; + + if (!frmRedir.TryGetValue(assembly.Name, out var redirect)) + return; + if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) + return; + if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) + return; + + assembly = new AssemblyNameInfo(assembly); + assembly.Version = redirect.redirectVersion; + } } } From edd4323b4a47d09fc4796f274dc018f8a9da9340 Mon Sep 17 00:00:00 2001 From: dyarkovoy Date: Mon, 17 Dec 2018 18:12:10 +0200 Subject: [PATCH 248/511] remap types in dnlib.DotNet.Importer (#227) * remap types when importing * change Import(ITypeDefOrRef type) to public method * mapping imported entities, further enhancements * Minor typo * recursion counter decrements were missing in the entity mapping code * reversed some changes made in prev. commit --- src/DotNet/Importer.cs | 89 +++++++++++++++++-- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 2 +- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 77e19cdf9..ade1bde41 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -43,6 +43,40 @@ public enum ImporterOptions { FixSignature = int.MinValue, } + /// + /// Re-maps entities that were renamed in the target module + /// + public abstract class ImportMapper { + + /// + /// Matches source to the one that is already present in the target module under a different name. + /// + /// referenced by the entity that is being imported. + /// matching or null if there's no match. + public virtual ITypeDefOrRef Map(ITypeDefOrRef source) => null; + + /// + /// Matches source to the one that is already present in the target module under a different name. + /// + /// referenced by the entity that is being imported. + /// matching or null if there's no match. + public virtual IField Map(FieldDef source) => null; + + /// + /// Matches source to the one that is already present in the target module under a different name. + /// + /// referenced by the entity that is being imported. + /// matching or null if there's no match. + public virtual IMethod Map(MethodDef source) => null; + + /// + /// Matches source to the one that is already present in the target module under a different name. + /// + /// referenced by the entity that is being imported. + /// matching or null if there's no match. + public virtual MemberRef Map(MemberRef source) => null; + } + /// /// Imports s, s, s /// and s as references @@ -50,6 +84,7 @@ public enum ImporterOptions { public struct Importer { readonly ModuleDef module; readonly GenericParamContext gpContext; + readonly ImportMapper mapper; RecursionCounter recursionCounter; ImporterOptions options; @@ -72,7 +107,7 @@ bool FixSignature { /// /// The module that will own all references public Importer(ModuleDef module) - : this(module, 0, new GenericParamContext()) { + : this(module, 0, new GenericParamContext(), null) { } /// @@ -81,7 +116,7 @@ public Importer(ModuleDef module) /// The module that will own all references /// Generic parameter context public Importer(ModuleDef module, GenericParamContext gpContext) - : this(module, 0, gpContext) { + : this(module, 0, gpContext, null) { } /// @@ -90,7 +125,17 @@ public Importer(ModuleDef module, GenericParamContext gpContext) /// The module that will own all references /// Importer options public Importer(ModuleDef module, ImporterOptions options) - : this(module, options, new GenericParamContext()) { + : this(module, options, new GenericParamContext(), null) { + } + + /// + /// Constructor + /// + /// The module that will own all references + /// Importer options + /// Generic parameter context + public Importer(ModuleDef module, ImporterOptions options, GenericParamContext gpContext) + : this(module, options, new GenericParamContext(), null) { } /// @@ -99,11 +144,13 @@ public Importer(ModuleDef module, ImporterOptions options) /// The module that will own all references /// Importer options /// Generic parameter context - public Importer(ModuleDef module, ImporterOptions options, GenericParamContext gpContext) { + /// Mapper for renamed entities + public Importer(ModuleDef module, ImporterOptions options, GenericParamContext gpContext, ImportMapper mapper) { this.module = module; recursionCounter = new RecursionCounter(); this.options = options; this.gpContext = gpContext; + this.mapper = mapper; } /// @@ -615,6 +662,9 @@ public ITypeDefOrRef Import(TypeDef type) { return null; if (TryToUseTypeDefs && type.Module == module) return type; + var mapped = mapper?.Map(type); + if (mapped != null) + return mapped; return Import2(type); } @@ -623,6 +673,7 @@ TypeRef Import2(TypeDef type) { return null; if (!recursionCounter.Increment()) return null; + TypeRef result; var declType = type.DeclaringType; @@ -657,7 +708,13 @@ IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { /// /// The type /// The imported type or null - public ITypeDefOrRef Import(TypeRef type) => TryResolve(Import2(type)); + public ITypeDefOrRef Import(TypeRef type) { + var mapped = mapper?.Map(type); + if (mapped != null) + return mapped; + + return TryResolve(Import2(type)); + } TypeRef Import2(TypeRef type) { if (type == null) @@ -760,7 +817,12 @@ public TypeSig Import(TypeSig type) { return result; } - ITypeDefOrRef Import(ITypeDefOrRef type) => (ITypeDefOrRef)Import((IType)type); + /// + /// Imports a + /// + /// The type + /// The imported type or null + public ITypeDefOrRef Import(ITypeDefOrRef type) => (ITypeDefOrRef)Import((IType)type); TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); @@ -971,6 +1033,11 @@ public IField Import(FieldDef field) { return field; if (!recursionCounter.Increment()) return null; + var mapped = mapper?.Map(field); + if (mapped != null) { + recursionCounter.Decrement(); + return mapped; + } MemberRef result = module.UpdateRowId(new MemberRefUser(module, field.Name)); result.Signature = Import(field.Signature); @@ -1000,6 +1067,11 @@ public IMethod Import(MethodDef method) { return method; if (!recursionCounter.Increment()) return null; + var mapped = mapper?.Map(method); + if (mapped != null) { + recursionCounter.Decrement(); + return mapped; + } MemberRef result = module.UpdateRowId(new MemberRefUser(module, method.Name)); result.Signature = Import(method.Signature); @@ -1037,6 +1109,11 @@ public MemberRef Import(MemberRef memberRef) { return null; if (!recursionCounter.Increment()) return null; + var mapped = mapper?.Map(memberRef); + if (mapped != null) { + recursionCounter.Decrement(); + return mapped; + } MemberRef result = module.UpdateRowId(new MemberRefUser(module, memberRef.Name)); result.Signature = Import(memberRef.Signature); diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 1e95fde21..50c26b412 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -320,7 +320,7 @@ void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyn return; } if (stepInfo.BreakpointMethod == null) { - Error("BreakpointInstruction is null"); + Error("BreakpointMethod is null"); return; } if (stepInfo.BreakpointInstruction == null) { From 5037f4290782fed335be340e23704537d3cdb76d Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 17 Dec 2018 17:14:36 +0100 Subject: [PATCH 249/511] Remove lines with only tabs --- src/DotNet/Importer.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index ade1bde41..4cd9b9daa 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -47,7 +47,6 @@ public enum ImporterOptions { /// Re-maps entities that were renamed in the target module /// public abstract class ImportMapper { - /// /// Matches source to the one that is already present in the target module under a different name. /// @@ -673,7 +672,6 @@ TypeRef Import2(TypeDef type) { return null; if (!recursionCounter.Increment()) return null; - TypeRef result; var declType = type.DeclaringType; From 83b4eaa999fab374f28697c8900d51a60a366658 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 21 Dec 2018 04:56:13 +0100 Subject: [PATCH 250/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 5c445d064..04a7c4347 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -18,7 +18,7 @@ dnlib dnlib en-US - 3.0.0 + 3.1.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 5a2a98a3bdd251dbfc97740c5cbed5ad154c0eca Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 21 Dec 2018 05:37:00 +0100 Subject: [PATCH 251/511] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0eb94789e..ec1f6246b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# dnlib [![Build status](https://ci.appveyor.com/api/projects/status/h7dqmfac6qjh4hap/branch/master?svg=true)](https://ci.appveyor.com/project/0xd4d/dnlib/branch/master) +# dnlib [![Build status](https://ci.appveyor.com/api/projects/status/h7dqmfac6qjh4hap/branch/master?svg=true)](https://ci.appveyor.com/project/0xd4d/dnlib/branch/master) [![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) .NET module/assembly reader/writer library NuGet ----- -Soon... +[![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) Compiling --------- From 8539b6f8eda020896c88d798b9a81be3446f49bf Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 21 Dec 2018 11:58:40 +0100 Subject: [PATCH 252/511] Update nuget desc --- src/dnlib.csproj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 04a7c4347..240230c66 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -30,7 +30,10 @@ true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. + Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. + +For better *Windows PDB* writer support, you should add a reference to `Microsoft.DiaSymReader.Native` nuget package too, see the dnlib README for more info: https://github.com/0xd4d/dnlib#windows-pdbs . You don't need to do anything special for *Portable PDB* support. + ..\dnlib.snk From 90409db7b9965adc5176de63f593007da17e6f7c Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 22 Dec 2018 09:56:55 +0100 Subject: [PATCH 253/511] Add TryApplyFrameworkRedirect() --- src/DotNet/FrameworkRedirect.cs | 90 +++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/src/DotNet/FrameworkRedirect.cs b/src/DotNet/FrameworkRedirect.cs index c4900fc14..404764f68 100644 --- a/src/DotNet/FrameworkRedirect.cs +++ b/src/DotNet/FrameworkRedirect.cs @@ -301,22 +301,31 @@ static void InitFrameworkRedirectV4() { /// Current assembly reference that might get updated /// Module using the assembly reference public static void ApplyFrameworkRedirect(ref IAssembly assembly, ModuleDef sourceModule) { - if (sourceModule == null) - return; - if (!Utils.LocaleEquals(assembly.Culture, "")) - return; - if (!sourceModule.IsClr20 && !sourceModule.IsClr40) - return; + if (TryApplyFrameworkRedirectCore(assembly, sourceModule, out var redirectedAssembly)) + assembly = redirectedAssembly; + } - if (!(sourceModule.IsClr20 ? frmRedir2 : frmRedir4).TryGetValue(assembly.Name, out var redirect)) - return; - if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) - return; - if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) - return; + /// + /// Tries to redirect a .NET Framework assembly from an older version to the correct version + /// loaded at runtime. + /// + /// Assembly reference + /// Module using the assembly reference + /// Updated with the redirected assembly if successful + /// + public static bool TryApplyFrameworkRedirect(IAssembly assembly, ModuleDef sourceModule, out IAssembly redirectedAssembly) => + TryApplyFrameworkRedirectCore(assembly, sourceModule, out redirectedAssembly); + + static bool TryApplyFrameworkRedirectCore(IAssembly assembly, ModuleDef sourceModule, out IAssembly redirectedAssembly) { + if (sourceModule != null) { + if (sourceModule.IsClr40) + return TryApplyFrameworkRedirect(assembly, frmRedir4, out redirectedAssembly); + if (sourceModule.IsClr20) + return TryApplyFrameworkRedirect(assembly, frmRedir2, out redirectedAssembly); + } - assembly = new AssemblyNameInfo(assembly); - assembly.Version = redirect.redirectVersion; + redirectedAssembly = null; + return false; } /// @@ -324,30 +333,57 @@ public static void ApplyFrameworkRedirect(ref IAssembly assembly, ModuleDef sour /// loaded at runtime. /// /// Current assembly reference that might get updated - public static void ApplyFrameworkRedirectV2(ref IAssembly assembly) => - ApplyFrameworkRedirect(ref assembly, frmRedir2); + public static void ApplyFrameworkRedirectV2(ref IAssembly assembly) { + if (TryApplyFrameworkRedirect(assembly, frmRedir2, out var redirectedAssembly)) + assembly = redirectedAssembly; + } /// /// Redirects a .NET Framework 4.0+ assembly from an older version to the correct version /// loaded at runtime. /// /// Current assembly reference that might get updated - public static void ApplyFrameworkRedirectV4(ref IAssembly assembly) => - ApplyFrameworkRedirect(ref assembly, frmRedir4); + public static void ApplyFrameworkRedirectV4(ref IAssembly assembly) { + if (TryApplyFrameworkRedirect(assembly, frmRedir4, out var redirectedAssembly)) + assembly = redirectedAssembly; + } - static void ApplyFrameworkRedirect(ref IAssembly assembly, Dictionary frmRedir) { - if (!Utils.LocaleEquals(assembly.Culture, "")) - return; + /// + /// Tries to redirect a .NET Framework 2.0-3.5 assembly from an older version to the correct version + /// loaded at runtime. + /// + /// Assembly reference + /// Updated with the redirected assembly if successful + /// + public static bool TryApplyFrameworkRedirectV2(IAssembly assembly, out IAssembly redirectedAssembly) => + TryApplyFrameworkRedirect(assembly, frmRedir2, out redirectedAssembly); + + /// + /// Tries to redirect a .NET Framework 4.0+ assembly from an older version to the correct version + /// loaded at runtime. + /// + /// Assembly reference + /// Updated with the redirected assembly if successful + /// + public static bool TryApplyFrameworkRedirectV4(IAssembly assembly, out IAssembly redirectedAssembly) => + TryApplyFrameworkRedirect(assembly, frmRedir4, out redirectedAssembly); + static bool TryApplyFrameworkRedirect(IAssembly assembly, Dictionary frmRedir, out IAssembly redirectedAssembly) { + redirectedAssembly = null; + if (!Utils.LocaleEquals(assembly.Culture, "")) + return false; if (!frmRedir.TryGetValue(assembly.Name, out var redirect)) - return; + return false; if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) - return; - if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) - return; + return false; - assembly = new AssemblyNameInfo(assembly); - assembly.Version = redirect.redirectVersion; + if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) + redirectedAssembly = assembly; + else { + redirectedAssembly = new AssemblyNameInfo(assembly); + redirectedAssembly.Version = redirect.redirectVersion; + } + return true; } } } From 070dec476afafed68d642ee2c916cd19b1d6b6b5 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 22 Dec 2018 10:04:53 +0100 Subject: [PATCH 254/511] Fix field types --- src/DotNet/AssemblyResolver.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 25851cb3f..60d909155 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -27,10 +27,10 @@ public class AssemblyResolver : IAssemblyResolver { }; ModuleContext defaultModuleContext; - readonly Dictionary> moduleSearchPaths = new Dictionary>(); + readonly Dictionary> moduleSearchPaths = new Dictionary>(); readonly Dictionary cachedAssemblies = new Dictionary(StringComparer.OrdinalIgnoreCase); - readonly IList preSearchPaths = new List(); - readonly IList postSearchPaths = new List(); + readonly List preSearchPaths = new List(); + readonly List postSearchPaths = new List(); bool findExactMatch; bool enableFrameworkRedirect; bool enableTypeDefCache = true; @@ -43,9 +43,9 @@ sealed class GacInfo { public readonly int Version; public readonly string Path; public readonly string Prefix; - public readonly IList SubDirs; + public readonly string[] SubDirs; - public GacInfo(int version, string prefix, string path, IList subDirs) { + public GacInfo(int version, string prefix, string path, string[] subDirs) { Version = version; Prefix = prefix; Path = path; @@ -96,7 +96,7 @@ static AssemblyResolver() { if (!string.IsNullOrEmpty(windir)) { string path; - // .NET 1.x and 2.x + // .NET Framework 1.x and 2.x path = Path.Combine(windir, "assembly"); if (Directory.Exists(path)) { gacInfos.Add(new GacInfo(2, "", path, new string[] { @@ -104,7 +104,7 @@ static AssemblyResolver() { })); } - // .NET 4.x + // .NET Framework 4.x path = Path.Combine(Path.Combine(windir, "Microsoft.NET"), "assembly"); if (Directory.Exists(path)) { gacInfos.Add(new GacInfo(4, "v4.0_", path, new string[] { From 104abf91e13eeffb737a8745724af971488dcfb5 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 29 Dec 2018 13:28:27 +0100 Subject: [PATCH 255/511] Update invalid mscorlib version check --- src/DotNet/WinMDHelpers.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index 8d6f68c70..303bc6ea8 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -172,7 +172,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { var mscorlib = module?.CorLibTypes.AssemblyRef; var asm = new AssemblyRefUser(GetName(clrAsm), contractAsmVersion, new PublicKeyToken(GetPublicKeyToken(clrAsm)), UTF8String.Empty); - if (mscorlib != null && mscorlib.Name == mscorlibName && mscorlib.Version != invalidWinMDVersion) + if (mscorlib != null && mscorlib.Name == mscorlibName && IsValidMscorlibVersion(mscorlib.Version)) asm.Version = mscorlib.Version; if (module is ModuleDefMD mod) { Version ver = null; @@ -185,7 +185,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { continue; if (!PublicKeyBase.TokenEquals(asmRef.PublicKeyOrToken, asm.PublicKeyOrToken)) continue; - if (asmRef.Version == invalidWinMDVersion) + if (!IsValidMscorlibVersion(asmRef.Version)) continue; if (ver == null || asmRef.Version > ver) @@ -198,9 +198,11 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { return asm; } static readonly Version contractAsmVersion = new Version(4, 0, 0, 0); - static readonly Version invalidWinMDVersion = new Version(255, 255, 255, 255); static readonly UTF8String mscorlibName = new UTF8String("mscorlib"); + // Silverlight uses 5.0.5.0 + static bool IsValidMscorlibVersion(Version version) => version != null && (uint)version.Major <= 5; + static UTF8String GetName(ClrAssembly clrAsm) { switch (clrAsm) { case ClrAssembly.Mscorlib: return clrAsmName_Mscorlib; From bb6cdc5f270eefd704db4043564eb24f170e7139 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 1 Jan 2019 12:06:45 +0100 Subject: [PATCH 256/511] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ec1f6246b..06e49a0ee 100644 --- a/README.md +++ b/README.md @@ -175,8 +175,8 @@ dnlib will use `Microsoft.DiaSymReader.Native` if it exists and fall back to `di `Microsoft.DiaSymReader.Native` is a NuGet package with 32-bit and 64-bit native DLLs. You have to add a reference to this NuGet package if you want dnlib to use it. dnlib doesn't add a reference to it. -Strong name sign an assembly ----------------------------- +Strong name signing an assembly +------------------------------- Use the following code to strong name sign the assembly when saving it: From 868c3ce491487922ac35c96e7b632ec3cf1f689c Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 1 Jan 2019 12:07:42 +0100 Subject: [PATCH 257/511] Update copyright years --- LICENSE.txt | 2 +- src/dnlib.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index bc03458ac..74858b859 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 2012-2018 de4dot@gmail.com +Copyright (C) 2012-2019 de4dot@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 240230c66..a38f22b7f 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -12,7 +12,7 @@ Reads and writes .NET assemblies and modules $(Description) - Copyright (C) 2012-2018 de4dot@gmail.com + Copyright (C) 2012-2019 de4dot@gmail.com dnlib $(AssemblyTitle) (thread safe) dnlib From 05899bff1169456d6dfd1cb46a50169645394eb6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 1 Jan 2019 12:53:19 +0100 Subject: [PATCH 258/511] Remove utf8 bom --- Examples/Example1.cs | 2 +- Examples/Example2.cs | 2 +- Examples/Example3.cs | 2 +- Examples/Example4.cs | 2 +- Examples/Example5.cs | 2 +- Examples/Example6.cs | 2 +- Examples/Program.cs | 2 +- src/DefaultDllImportSearchPathsAttribute.cs | 2 +- src/DotNet/CpuArch.cs | 2 +- src/DotNet/DeclSecurityReader.cs | 2 +- src/DotNet/Emit/DynamicMethodBodyReader.cs | 2 +- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/DotNet/FrameworkRedirect.cs | 2 +- src/DotNet/GenericParamContext.cs | 2 +- src/DotNet/ICustomAttribute.cs | 2 +- src/DotNet/ITokenResolver.cs | 2 +- src/DotNet/MD/CustomDotNetStream.cs | 2 +- src/DotNet/MD/HeapType.cs | 2 +- src/DotNet/MD/Metadata.cs | 2 +- src/DotNet/MD/PdbStream.cs | 2 +- src/DotNet/MarshalBlobReader.cs | 2 +- src/DotNet/MarshalType.cs | 2 +- src/DotNet/MemberFinder.cs | 2 +- src/DotNet/MemberMDInitializer.cs | 2 +- src/DotNet/MethodExportInfo.cs | 2 +- src/DotNet/MethodExportInfoProvider.cs | 2 +- src/DotNet/ModuleCreationOptions.cs | 2 +- src/DotNet/ModuleLoader.cs | 2 +- src/DotNet/NativeType.cs | 2 +- src/DotNet/Pdb/CustomDebugInfoGuids.cs | 2 +- src/DotNet/Pdb/DataReaderFactoryUtils.cs | 2 +- src/DotNet/Pdb/Dss/ComInterfaces.cs | 2 +- src/DotNet/Pdb/Dss/DataReaderIStream.cs | 2 +- src/DotNet/Pdb/Dss/MDEmitter.cs | 2 +- src/DotNet/Pdb/Dss/MetaDataImport.cs | 2 +- src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs | 2 +- src/DotNet/Pdb/Dss/StreamIStream.cs | 2 +- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs | 2 +- src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs | 2 +- src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolVariableImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolWriterImpl.cs | 2 +- src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs | 2 +- src/DotNet/Pdb/Managed/DbiDocument.cs | 2 +- src/DotNet/Pdb/Managed/DbiFunction.cs | 2 +- src/DotNet/Pdb/Managed/DbiModule.cs | 2 +- src/DotNet/Pdb/Managed/DbiNamespace.cs | 2 +- src/DotNet/Pdb/Managed/DbiScope.cs | 2 +- src/DotNet/Pdb/Managed/DbiVariable.cs | 2 +- src/DotNet/Pdb/Managed/ModuleStreamType.cs | 4 ++-- src/DotNet/Pdb/Managed/MsfStream.cs | 2 +- src/DotNet/Pdb/Managed/NumericLeaf.cs | 2 +- src/DotNet/Pdb/Managed/NumericReader.cs | 2 +- src/DotNet/Pdb/Managed/PdbAddress.cs | 2 +- src/DotNet/Pdb/Managed/PdbException.cs | 2 +- src/DotNet/Pdb/Managed/PdbReader.cs | 2 +- src/DotNet/Pdb/Managed/SymbolReaderFactory.cs | 2 +- src/DotNet/Pdb/Managed/SymbolType.cs | 4 ++-- src/DotNet/Pdb/PdbConstant.cs | 2 +- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 2 +- src/DotNet/Pdb/PdbDocument.cs | 2 +- src/DotNet/Pdb/PdbDocumentConstants.cs | 2 +- src/DotNet/Pdb/PdbFileKind.cs | 2 +- src/DotNet/Pdb/PdbImport.cs | 2 +- src/DotNet/Pdb/PdbLocal.cs | 2 +- src/DotNet/Pdb/PdbLocalAttributes.cs | 2 +- src/DotNet/Pdb/PdbMethod.cs | 2 +- src/DotNet/Pdb/PdbReaderContext.cs | 2 +- src/DotNet/Pdb/PdbReaderOptions.cs | 2 +- src/DotNet/Pdb/PdbScope.cs | 2 +- src/DotNet/Pdb/PdbState.cs | 2 +- src/DotNet/Pdb/PdbUtils.cs | 2 +- src/DotNet/Pdb/Portable/DocumentNameReader.cs | 2 +- src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs | 2 +- src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs | 2 +- src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs | 2 +- src/DotNet/Pdb/Portable/ListCache.cs | 2 +- src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs | 2 +- src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs | 2 +- src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs | 2 +- src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs | 2 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 2 +- src/DotNet/Pdb/Portable/SequencePointConstants.cs | 2 +- src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs | 2 +- src/DotNet/Pdb/Portable/SymbolMethodImpl.cs | 2 +- src/DotNet/Pdb/Portable/SymbolReaderFactory.cs | 2 +- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 2 +- src/DotNet/Pdb/Portable/SymbolVariableImpl.cs | 2 +- src/DotNet/Pdb/SequencePoint.cs | 2 +- src/DotNet/Pdb/SymbolReaderFactory.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolDocument.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolMethod.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolNamespace.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolReader.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolScope.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolVariable.cs | 2 +- src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs | 2 +- src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs | 2 +- src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs | 2 +- src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs | 2 +- src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs | 2 +- src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs | 2 +- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 2 +- src/DotNet/ResourceCollection.cs | 2 +- src/DotNet/Resources/BuiltInResourceData.cs | 2 +- src/DotNet/Resources/IResourceData.cs | 2 +- src/DotNet/Resources/ResourceDataFactory.cs | 2 +- src/DotNet/Resources/ResourceElement.cs | 2 +- src/DotNet/Resources/ResourceElementSet.cs | 2 +- src/DotNet/Resources/ResourceReader.cs | 2 +- src/DotNet/Resources/ResourceTypeCode.cs | 2 +- src/DotNet/Resources/ResourceWriter.cs | 2 +- src/DotNet/Resources/UserResourceData.cs | 2 +- src/DotNet/Resources/UserResourceType.cs | 2 +- src/DotNet/SecurityAttribute.cs | 2 +- src/DotNet/TIAHelper.cs | 2 +- src/DotNet/TypeHelper.cs | 2 +- src/DotNet/VariantType.cs | 2 +- src/DotNet/WinMDHelpers.cs | 2 +- src/DotNet/WinMDStatus.cs | 2 +- src/DotNet/Writer/ArrayWriter.cs | 2 +- src/DotNet/Writer/ChecksumAlgorithm.cs | 2 +- src/DotNet/Writer/DataReaderChunk.cs | 2 +- src/DotNet/Writer/DataReaderHeap.cs | 2 +- src/DotNet/Writer/DataWriter.cs | 2 +- src/DotNet/Writer/DeclSecurityWriter.cs | 2 +- src/DotNet/Writer/Hasher.cs | 2 +- src/DotNet/Writer/IOffsetHeap.cs | 2 +- src/DotNet/Writer/IWriterError.cs | 2 +- src/DotNet/Writer/MDTableWriter.cs | 2 +- src/DotNet/Writer/ManagedExportsWriter.cs | 2 +- src/DotNet/Writer/MarshalBlobWriter.cs | 2 +- src/DotNet/Writer/MetadataEvent.cs | 2 +- src/DotNet/Writer/ModuleWriterEvent.cs | 2 +- src/DotNet/Writer/PdbHeap.cs | 2 +- src/DotNet/Writer/PortablePdbConstants.cs | 2 +- src/DotNet/Writer/RoslynContentIdProvider.cs | 2 +- src/DotNet/Writer/SerializerMethodContext.cs | 2 +- src/DotNet/Writer/WriterUtils.cs | 2 +- src/HandleProcessCorruptedStateExceptionsAttribute.cs | 2 +- src/IO/AlignedByteArrayDataStream.cs | 2 +- src/IO/AlignedNativeMemoryDataStream.cs | 2 +- src/IO/ByteArrayDataReaderFactory.cs | 2 +- src/IO/DataReader.cs | 2 +- src/IO/DataReaderFactory.cs | 2 +- src/IO/DataReaderFactoryFactory.cs | 2 +- src/IO/DataReaderStream.cs | 2 +- src/IO/DataStream.cs | 2 +- src/IO/DataStreamFactory.cs | 2 +- src/IO/EmptyDataStream.cs | 2 +- src/IO/MemoryMappedDataReaderFactory.cs | 2 +- src/IO/NativeMemoryDataReaderFactory.cs | 2 +- src/IO/UnalignedByteArrayDataStream.cs | 2 +- src/IO/UnalignedNativeMemoryDataStream.cs | 2 +- src/PE/ImageDebugDirectory.cs | 2 +- src/PE/ImageDebugType.cs | 2 +- src/PE/ProcessorArchUtils.cs | 2 +- src/Settings.cs | 2 +- src/Threading/ICancellationToken.cs | 2 +- src/Threading/Lock.cs | 2 +- src/Utils/ArrayEmpty.cs | 2 +- src/Utils/CollectionDebugView.cs | 2 +- 168 files changed, 170 insertions(+), 170 deletions(-) diff --git a/Examples/Example1.cs b/Examples/Example1.cs index d74762fd3..62c8fd9b5 100644 --- a/Examples/Example1.cs +++ b/Examples/Example1.cs @@ -1,4 +1,4 @@ -using System; +using System; using dnlib.DotNet; namespace dnlib.Examples { diff --git a/Examples/Example2.cs b/Examples/Example2.cs index d73df4843..97926d504 100644 --- a/Examples/Example2.cs +++ b/Examples/Example2.cs @@ -1,4 +1,4 @@ -using dnlib.DotNet; +using dnlib.DotNet; using dnlib.DotNet.Emit; namespace dnlib.Examples { diff --git a/Examples/Example3.cs b/Examples/Example3.cs index 741adb7bc..30e919d74 100644 --- a/Examples/Example3.cs +++ b/Examples/Example3.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using dnlib.DotNet; using dnlib.DotNet.Emit; diff --git a/Examples/Example4.cs b/Examples/Example4.cs index 04f6de693..a2dd34005 100644 --- a/Examples/Example4.cs +++ b/Examples/Example4.cs @@ -1,4 +1,4 @@ -using System; +using System; using dnlib.DotNet; using dnlib.DotNet.Emit; diff --git a/Examples/Example5.cs b/Examples/Example5.cs index a530fd5ad..30e8c79f4 100644 --- a/Examples/Example5.cs +++ b/Examples/Example5.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using dnlib.DotNet; using dnlib.PE; diff --git a/Examples/Example6.cs b/Examples/Example6.cs index 35677f8f5..f00adb5a3 100644 --- a/Examples/Example6.cs +++ b/Examples/Example6.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using dnlib.DotNet; using dnlib.DotNet.MD; diff --git a/Examples/Program.cs b/Examples/Program.cs index 434e24627..69280ea7f 100644 --- a/Examples/Program.cs +++ b/Examples/Program.cs @@ -1,4 +1,4 @@ -namespace dnlib.Examples { +namespace dnlib.Examples { class Program { static void Main(string[] args) { // Just uncomment whatever you want to debug diff --git a/src/DefaultDllImportSearchPathsAttribute.cs b/src/DefaultDllImportSearchPathsAttribute.cs index 3c8628c79..ad4b10d2a 100644 --- a/src/DefaultDllImportSearchPathsAttribute.cs +++ b/src/DefaultDllImportSearchPathsAttribute.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info #if NET35 namespace System.Runtime.InteropServices { diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 6814f59a4..508500943 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.DotNet.Writer; diff --git a/src/DotNet/DeclSecurityReader.cs b/src/DotNet/DeclSecurityReader.cs index fffaaba0d..86f01ed7a 100644 --- a/src/DotNet/DeclSecurityReader.cs +++ b/src/DotNet/DeclSecurityReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index fba319f77..67f5550b8 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index 2b6314b33..e43a07d27 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/FrameworkRedirect.cs b/src/DotNet/FrameworkRedirect.cs index 404764f68..69ee0cb83 100644 --- a/src/DotNet/FrameworkRedirect.cs +++ b/src/DotNet/FrameworkRedirect.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/GenericParamContext.cs b/src/DotNet/GenericParamContext.cs index f6d6d87a9..8ac14394a 100644 --- a/src/DotNet/GenericParamContext.cs +++ b/src/DotNet/GenericParamContext.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet { /// diff --git a/src/DotNet/ICustomAttribute.cs b/src/DotNet/ICustomAttribute.cs index 18f317506..e80b4aa36 100644 --- a/src/DotNet/ICustomAttribute.cs +++ b/src/DotNet/ICustomAttribute.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/ITokenResolver.cs b/src/DotNet/ITokenResolver.cs index 0fab0a59a..495aaa3cd 100644 --- a/src/DotNet/ITokenResolver.cs +++ b/src/DotNet/ITokenResolver.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet { /// diff --git a/src/DotNet/MD/CustomDotNetStream.cs b/src/DotNet/MD/CustomDotNetStream.cs index 8d8882ac6..d7a914261 100644 --- a/src/DotNet/MD/CustomDotNetStream.cs +++ b/src/DotNet/MD/CustomDotNetStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.IO; diff --git a/src/DotNet/MD/HeapType.cs b/src/DotNet/MD/HeapType.cs index c185d1599..cf3f3ed1b 100644 --- a/src/DotNet/MD/HeapType.cs +++ b/src/DotNet/MD/HeapType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.MD { /// diff --git a/src/DotNet/MD/Metadata.cs b/src/DotNet/MD/Metadata.cs index fa97a74f2..7359cad75 100644 --- a/src/DotNet/MD/Metadata.cs +++ b/src/DotNet/MD/Metadata.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/MD/PdbStream.cs b/src/DotNet/MD/PdbStream.cs index 9efa40d9d..d5734ae94 100644 --- a/src/DotNet/MD/PdbStream.cs +++ b/src/DotNet/MD/PdbStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.IO; diff --git a/src/DotNet/MarshalBlobReader.cs b/src/DotNet/MarshalBlobReader.cs index 3ab6325d8..efa36fe2c 100644 --- a/src/DotNet/MarshalBlobReader.cs +++ b/src/DotNet/MarshalBlobReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.IO; diff --git a/src/DotNet/MarshalType.cs b/src/DotNet/MarshalType.cs index bec6c4e7e..f42a23160 100644 --- a/src/DotNet/MarshalType.cs +++ b/src/DotNet/MarshalType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index 42978843a..6239c0b7e 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/MemberMDInitializer.cs b/src/DotNet/MemberMDInitializer.cs index 8610b20fb..927cec4f9 100644 --- a/src/DotNet/MemberMDInitializer.cs +++ b/src/DotNet/MemberMDInitializer.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/MethodExportInfo.cs b/src/DotNet/MethodExportInfo.cs index a170d7270..3a22aee38 100644 --- a/src/DotNet/MethodExportInfo.cs +++ b/src/DotNet/MethodExportInfo.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/MethodExportInfoProvider.cs b/src/DotNet/MethodExportInfoProvider.cs index 7d18193eb..592f45fc6 100644 --- a/src/DotNet/MethodExportInfoProvider.cs +++ b/src/DotNet/MethodExportInfoProvider.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 550506f18..72a76f860 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.IO; using dnlib.DotNet.Pdb; diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index acb543417..44ca5ba97 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/NativeType.cs b/src/DotNet/NativeType.cs index d390d595e..b1a78e4a4 100644 --- a/src/DotNet/NativeType.cs +++ b/src/DotNet/NativeType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet { /// diff --git a/src/DotNet/Pdb/CustomDebugInfoGuids.cs b/src/DotNet/Pdb/CustomDebugInfoGuids.cs index d56cb9641..f4dcf06c3 100644 --- a/src/DotNet/Pdb/CustomDebugInfoGuids.cs +++ b/src/DotNet/Pdb/CustomDebugInfoGuids.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Pdb/DataReaderFactoryUtils.cs b/src/DotNet/Pdb/DataReaderFactoryUtils.cs index c143fb336..8009714e2 100644 --- a/src/DotNet/Pdb/DataReaderFactoryUtils.cs +++ b/src/DotNet/Pdb/DataReaderFactoryUtils.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Pdb/Dss/ComInterfaces.cs b/src/DotNet/Pdb/Dss/ComInterfaces.cs index 9a61f7e9d..a57c84672 100644 --- a/src/DotNet/Pdb/Dss/ComInterfaces.cs +++ b/src/DotNet/Pdb/Dss/ComInterfaces.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/DotNet/Pdb/Dss/DataReaderIStream.cs b/src/DotNet/Pdb/Dss/DataReaderIStream.cs index 1387f9b28..1733c53f2 100644 --- a/src/DotNet/Pdb/Dss/DataReaderIStream.cs +++ b/src/DotNet/Pdb/Dss/DataReaderIStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/DotNet/Pdb/Dss/MDEmitter.cs b/src/DotNet/Pdb/Dss/MDEmitter.cs index 6e7ebb0f2..984ccc89e 100644 --- a/src/DotNet/Pdb/Dss/MDEmitter.cs +++ b/src/DotNet/Pdb/Dss/MDEmitter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Dss/MetaDataImport.cs b/src/DotNet/Pdb/Dss/MetaDataImport.cs index a1d7a041a..b41440e7c 100644 --- a/src/DotNet/Pdb/Dss/MetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/MetaDataImport.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs index 3c13192b5..3a4bea139 100644 --- a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/DotNet/Pdb/Dss/StreamIStream.cs b/src/DotNet/Pdb/Dss/StreamIStream.cs index 45b621ec9..be1b60e0b 100644 --- a/src/DotNet/Pdb/Dss/StreamIStream.cs +++ b/src/DotNet/Pdb/Dss/StreamIStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index 88a8d91ac..af4cd620f 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs index 9c10c818e..0101d28f3 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics.SymbolStore; diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index 1f75488e4..c0785305e 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Diagnostics.SymbolStore; diff --git a/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs b/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs index ec5750de6..2b279780f 100644 --- a/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 33155ff80..e0c6cbb3d 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 138e8a117..1d06b94b2 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs index 383f38862..3992aab41 100644 --- a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs index a1e9fd976..62347c661 100644 --- a/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolVariableImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index 893a7b1b5..bbc24e2de 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs b/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs index 7b38564e9..c69e14f84 100644 --- a/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs +++ b/src/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.PE; diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index f35b53bd1..71611f343 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index d5d518819..26d31d39d 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index df5a25119..181f3d150 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Managed/DbiNamespace.cs b/src/DotNet/Pdb/Managed/DbiNamespace.cs index 961c75c6c..abe3a888c 100644 --- a/src/DotNet/Pdb/Managed/DbiNamespace.cs +++ b/src/DotNet/Pdb/Managed/DbiNamespace.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 2baca5474..00ef8f5ca 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Managed/DbiVariable.cs b/src/DotNet/Pdb/Managed/DbiVariable.cs index 8aa1537c0..46d655663 100644 --- a/src/DotNet/Pdb/Managed/DbiVariable.cs +++ b/src/DotNet/Pdb/Managed/DbiVariable.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Managed/ModuleStreamType.cs b/src/DotNet/Pdb/Managed/ModuleStreamType.cs index 4354af428..c326068c8 100644 --- a/src/DotNet/Pdb/Managed/ModuleStreamType.cs +++ b/src/DotNet/Pdb/Managed/ModuleStreamType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Managed { enum ModuleStreamType : uint { @@ -15,4 +15,4 @@ enum ModuleStreamType : uint { TypeMDTokenMap = 0xFB, MergedAssemblyInput = 0xFC, } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/Managed/MsfStream.cs b/src/DotNet/Pdb/Managed/MsfStream.cs index 0915d1c83..b43fa8cb3 100644 --- a/src/DotNet/Pdb/Managed/MsfStream.cs +++ b/src/DotNet/Pdb/Managed/MsfStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.IO; diff --git a/src/DotNet/Pdb/Managed/NumericLeaf.cs b/src/DotNet/Pdb/Managed/NumericLeaf.cs index 730d843ef..acedd24ec 100644 --- a/src/DotNet/Pdb/Managed/NumericLeaf.cs +++ b/src/DotNet/Pdb/Managed/NumericLeaf.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Managed { enum NumericLeaf : ushort { diff --git a/src/DotNet/Pdb/Managed/NumericReader.cs b/src/DotNet/Pdb/Managed/NumericReader.cs index 959a63f0b..566a85427 100644 --- a/src/DotNet/Pdb/Managed/NumericReader.cs +++ b/src/DotNet/Pdb/Managed/NumericReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.IO; diff --git a/src/DotNet/Pdb/Managed/PdbAddress.cs b/src/DotNet/Pdb/Managed/PdbAddress.cs index 6b4a97681..91ad32a02 100644 --- a/src/DotNet/Pdb/Managed/PdbAddress.cs +++ b/src/DotNet/Pdb/Managed/PdbAddress.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Pdb/Managed/PdbException.cs b/src/DotNet/Pdb/Managed/PdbException.cs index 390e498a0..c382b340c 100644 --- a/src/DotNet/Pdb/Managed/PdbException.cs +++ b/src/DotNet/Pdb/Managed/PdbException.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.Serialization; diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 0a9d765d8..db8ff0142 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections; diff --git a/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs index 49d26727b..ec3e8137e 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.IO; using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Managed/SymbolType.cs b/src/DotNet/Pdb/Managed/SymbolType.cs index 831f77f03..66a1becd5 100644 --- a/src/DotNet/Pdb/Managed/SymbolType.cs +++ b/src/DotNet/Pdb/Managed/SymbolType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Managed { enum SymbolType : ushort { @@ -198,4 +198,4 @@ enum SymbolType : ushort { S_RECTYPE_MAX, } -} \ No newline at end of file +} diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs index 64e5a9ca0..4b6da6836 100644 --- a/src/DotNet/Pdb/PdbConstant.cs +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 3d8c71c78..73cf8e404 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index fb2ce43bc..a6f663b5d 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/PdbDocumentConstants.cs b/src/DotNet/Pdb/PdbDocumentConstants.cs index 8775cbb66..4002545d1 100644 --- a/src/DotNet/Pdb/PdbDocumentConstants.cs +++ b/src/DotNet/Pdb/PdbDocumentConstants.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Pdb/PdbFileKind.cs b/src/DotNet/Pdb/PdbFileKind.cs index 72f7ce47a..1ec945f0f 100644 --- a/src/DotNet/Pdb/PdbFileKind.cs +++ b/src/DotNet/Pdb/PdbFileKind.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb { /// diff --git a/src/DotNet/Pdb/PdbImport.cs b/src/DotNet/Pdb/PdbImport.cs index 5eabf9c4e..d300d9130 100644 --- a/src/DotNet/Pdb/PdbImport.cs +++ b/src/DotNet/Pdb/PdbImport.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Diagnostics; diff --git a/src/DotNet/Pdb/PdbLocal.cs b/src/DotNet/Pdb/PdbLocal.cs index 7f7fd22f4..52e406de0 100644 --- a/src/DotNet/Pdb/PdbLocal.cs +++ b/src/DotNet/Pdb/PdbLocal.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using dnlib.DotNet.Emit; diff --git a/src/DotNet/Pdb/PdbLocalAttributes.cs b/src/DotNet/Pdb/PdbLocalAttributes.cs index 8953d2fb8..e126c28ca 100644 --- a/src/DotNet/Pdb/PdbLocalAttributes.cs +++ b/src/DotNet/Pdb/PdbLocalAttributes.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Pdb/PdbMethod.cs b/src/DotNet/Pdb/PdbMethod.cs index 619dfdf1b..c364a5b00 100644 --- a/src/DotNet/Pdb/PdbMethod.cs +++ b/src/DotNet/Pdb/PdbMethod.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb { /// diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs index 891154cd4..1ac5a0d73 100644 --- a/src/DotNet/Pdb/PdbReaderContext.cs +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.IO; diff --git a/src/DotNet/Pdb/PdbReaderOptions.cs b/src/DotNet/Pdb/PdbReaderOptions.cs index 2c36df1f1..4ee55d868 100644 --- a/src/DotNet/Pdb/PdbReaderOptions.cs +++ b/src/DotNet/Pdb/PdbReaderOptions.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Pdb/PdbScope.cs b/src/DotNet/Pdb/PdbScope.cs index 7da85a4f7..1537dc8de 100644 --- a/src/DotNet/Pdb/PdbScope.cs +++ b/src/DotNet/Pdb/PdbScope.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Diagnostics; diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 95f907239..ed26bb3ea 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/PdbUtils.cs b/src/DotNet/Pdb/PdbUtils.cs index 777485300..d5a2181fa 100644 --- a/src/DotNet/Pdb/PdbUtils.cs +++ b/src/DotNet/Pdb/PdbUtils.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb { static class PdbUtils { diff --git a/src/DotNet/Pdb/Portable/DocumentNameReader.cs b/src/DotNet/Pdb/Portable/DocumentNameReader.cs index ae03645a5..ee63d76a0 100644 --- a/src/DotNet/Pdb/Portable/DocumentNameReader.cs +++ b/src/DotNet/Pdb/Portable/DocumentNameReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Text; diff --git a/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs b/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs index 6e92e3f0c..a0fbe6e65 100644 --- a/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs +++ b/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Diagnostics; diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index 7ce632f24..18c036b02 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Diagnostics; diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index f249cd144..ac1880745 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Text; diff --git a/src/DotNet/Pdb/Portable/ListCache.cs b/src/DotNet/Pdb/Portable/ListCache.cs index 97b40b287..a1e9dcdb9 100644 --- a/src/DotNet/Pdb/Portable/ListCache.cs +++ b/src/DotNet/Pdb/Portable/ListCache.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Threading; diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index df4e879fb..dcf32f581 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index c1c6c3d4b..ef2d7f952 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Text; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index ea21df1f5..78b41f555 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info // See Roslyn files: MethodDebugInfo.Portable.cs, MetadataWriter.PortablePdb.cs diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index a6ab6a5f1..63700cbae 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.IO; using System.Text; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 28f5151ec..ab3eef414 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md diff --git a/src/DotNet/Pdb/Portable/SequencePointConstants.cs b/src/DotNet/Pdb/Portable/SequencePointConstants.cs index 159e559dd..23aa54370 100644 --- a/src/DotNet/Pdb/Portable/SequencePointConstants.cs +++ b/src/DotNet/Pdb/Portable/SequencePointConstants.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Portable { static class SequencePointConstants { diff --git a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs index b1c6a674b..7168d3c85 100644 --- a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs index 10385fa6b..933d3266f 100644 --- a/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolMethodImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using dnlib.DotNet.Emit; diff --git a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs index 94a18d114..dc615d643 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Diagnostics; using System.IO; diff --git a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs index 5f639e2c7..b815eb654 100644 --- a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs index 1762fb1b2..111c35a4d 100644 --- a/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolVariableImpl.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/SequencePoint.cs b/src/DotNet/Pdb/SequencePoint.cs index 0536d6fb7..916c24979 100644 --- a/src/DotNet/Pdb/SequencePoint.cs +++ b/src/DotNet/Pdb/SequencePoint.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Diagnostics; diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index dda74f5ff..97349d009 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.IO; using System.Text; diff --git a/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs b/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs index 5a6514808..65c9a1c25 100644 --- a/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs +++ b/src/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Symbols { /// diff --git a/src/DotNet/Pdb/Symbols/SymbolDocument.cs b/src/DotNet/Pdb/Symbols/SymbolDocument.cs index d401fcb56..ec12ded6b 100644 --- a/src/DotNet/Pdb/Symbols/SymbolDocument.cs +++ b/src/DotNet/Pdb/Symbols/SymbolDocument.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Pdb/Symbols/SymbolMethod.cs b/src/DotNet/Pdb/Symbols/SymbolMethod.cs index 6943621fb..801cfd996 100644 --- a/src/DotNet/Pdb/Symbols/SymbolMethod.cs +++ b/src/DotNet/Pdb/Symbols/SymbolMethod.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using dnlib.DotNet.Emit; diff --git a/src/DotNet/Pdb/Symbols/SymbolNamespace.cs b/src/DotNet/Pdb/Symbols/SymbolNamespace.cs index 1b2bcff97..a556b0fb8 100644 --- a/src/DotNet/Pdb/Symbols/SymbolNamespace.cs +++ b/src/DotNet/Pdb/Symbols/SymbolNamespace.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Symbols { /// diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index d10797892..40a1e39d5 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Symbols/SymbolScope.cs b/src/DotNet/Pdb/Symbols/SymbolScope.cs index 80f08c638..b24b03f4a 100644 --- a/src/DotNet/Pdb/Symbols/SymbolScope.cs +++ b/src/DotNet/Pdb/Symbols/SymbolScope.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs index 49ff6380b..a358735d3 100644 --- a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs +++ b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Diagnostics; using System.Text; diff --git a/src/DotNet/Pdb/Symbols/SymbolVariable.cs b/src/DotNet/Pdb/Symbols/SymbolVariable.cs index 89818ff5a..dc9eb6442 100644 --- a/src/DotNet/Pdb/Symbols/SymbolVariable.cs +++ b/src/DotNet/Pdb/Symbols/SymbolVariable.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.Symbols { /// diff --git a/src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs b/src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs index ef1458847..5869ec5d3 100644 --- a/src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs +++ b/src/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs b/src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs index 90def58ee..d4aed7ebf 100644 --- a/src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs +++ b/src/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Pdb.WindowsPdb { static class CustomDebugInfoConstants { diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index f11fa6c66..5855a28c7 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info // C# & Visual Basic compiler's Custom Debug Info is "documented" in source code only, see Roslyn classes: // CustomDebugInfoReader, CustomDebugInfoWriter, CustomDebugInfoEncoder diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs index 03b5e8035..4a41f6bb3 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info // C# & Visual Basic compiler's Custom Debug Info is "documented" in source code only, see Roslyn classes: // CustomDebugInfoReader, CustomDebugInfoWriter, CustomDebugInfoEncoder diff --git a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs index edbc17748..7cba6c42e 100644 --- a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs +++ b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Diagnostics; diff --git a/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs b/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs index 44864e75a..48fc59db7 100644 --- a/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/SymbolWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics.SymbolStore; diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 50c26b412..52c4f89dd 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/ResourceCollection.cs b/src/DotNet/ResourceCollection.cs index 4387a09da..afaabd1f2 100644 --- a/src/DotNet/ResourceCollection.cs +++ b/src/DotNet/ResourceCollection.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.Utils; using System; diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index f87bd3b48..032e040dd 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Resources/IResourceData.cs b/src/DotNet/Resources/IResourceData.cs index c9df95d20..e6062de25 100644 --- a/src/DotNet/Resources/IResourceData.cs +++ b/src/DotNet/Resources/IResourceData.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.IO; using System.Runtime.Serialization; diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index 6f2cc8322..be99f5de6 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Resources/ResourceElement.cs b/src/DotNet/Resources/ResourceElement.cs index 210eaae53..4a4f1dc98 100644 --- a/src/DotNet/Resources/ResourceElement.cs +++ b/src/DotNet/Resources/ResourceElement.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Resources { /// diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index 60984308e..cee357b3e 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 0c0a181cc..148d5272a 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Resources/ResourceTypeCode.cs b/src/DotNet/Resources/ResourceTypeCode.cs index 10839c924..ececc65a2 100644 --- a/src/DotNet/Resources/ResourceTypeCode.cs +++ b/src/DotNet/Resources/ResourceTypeCode.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Resources { /// diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index 2a35eaa0e..e10f7a608 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Resources/UserResourceData.cs b/src/DotNet/Resources/UserResourceData.cs index d8633cc34..9129559b5 100644 --- a/src/DotNet/Resources/UserResourceData.cs +++ b/src/DotNet/Resources/UserResourceData.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.IO; using System.Runtime.Serialization; diff --git a/src/DotNet/Resources/UserResourceType.cs b/src/DotNet/Resources/UserResourceType.cs index 7ab40c948..fde5524f1 100644 --- a/src/DotNet/Resources/UserResourceType.cs +++ b/src/DotNet/Resources/UserResourceType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Resources { /// diff --git a/src/DotNet/SecurityAttribute.cs b/src/DotNet/SecurityAttribute.cs index 19db0ae8b..4053bf5f6 100644 --- a/src/DotNet/SecurityAttribute.cs +++ b/src/DotNet/SecurityAttribute.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/TIAHelper.cs b/src/DotNet/TIAHelper.cs index 92addbb64..857701cfd 100644 --- a/src/DotNet/TIAHelper.cs +++ b/src/DotNet/TIAHelper.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info // See coreclr/src/vm/siginfo.cpp diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index 05e61ac57..01f750f88 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/VariantType.cs b/src/DotNet/VariantType.cs index 9b0f6b9de..5c80ee97e 100644 --- a/src/DotNet/VariantType.cs +++ b/src/DotNet/VariantType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet { /// diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index 303bc6ea8..279a2887f 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/WinMDStatus.cs b/src/DotNet/WinMDStatus.cs index e285ce368..d60cb7ee5 100644 --- a/src/DotNet/WinMDStatus.cs +++ b/src/DotNet/WinMDStatus.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet { /// diff --git a/src/DotNet/Writer/ArrayWriter.cs b/src/DotNet/Writer/ArrayWriter.cs index 1e717accb..721c0b46f 100644 --- a/src/DotNet/Writer/ArrayWriter.cs +++ b/src/DotNet/Writer/ArrayWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/DotNet/Writer/ChecksumAlgorithm.cs b/src/DotNet/Writer/ChecksumAlgorithm.cs index c247797e0..c0094189e 100644 --- a/src/DotNet/Writer/ChecksumAlgorithm.cs +++ b/src/DotNet/Writer/ChecksumAlgorithm.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Writer { /// diff --git a/src/DotNet/Writer/DataReaderChunk.cs b/src/DotNet/Writer/DataReaderChunk.cs index f94b70e78..defaa43ec 100644 --- a/src/DotNet/Writer/DataReaderChunk.cs +++ b/src/DotNet/Writer/DataReaderChunk.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.IO; diff --git a/src/DotNet/Writer/DataReaderHeap.cs b/src/DotNet/Writer/DataReaderHeap.cs index c2906eaf3..8a4f2b40c 100644 --- a/src/DotNet/Writer/DataReaderHeap.cs +++ b/src/DotNet/Writer/DataReaderHeap.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.DotNet.MD; diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs index 9cef1aba7..dd5bacdf6 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/DataWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 575892d8c..3905ad4dd 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Writer/Hasher.cs b/src/DotNet/Writer/Hasher.cs index 01749aa06..2c472e369 100644 --- a/src/DotNet/Writer/Hasher.cs +++ b/src/DotNet/Writer/Hasher.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Writer/IOffsetHeap.cs b/src/DotNet/Writer/IOffsetHeap.cs index 1e47faeeb..3c104dcff 100644 --- a/src/DotNet/Writer/IOffsetHeap.cs +++ b/src/DotNet/Writer/IOffsetHeap.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; diff --git a/src/DotNet/Writer/IWriterError.cs b/src/DotNet/Writer/IWriterError.cs index 2b88a65f3..4a0fb1881 100644 --- a/src/DotNet/Writer/IWriterError.cs +++ b/src/DotNet/Writer/IWriterError.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Writer { /// diff --git a/src/DotNet/Writer/MDTableWriter.cs b/src/DotNet/Writer/MDTableWriter.cs index 7c6dd1ca3..be57119b6 100644 --- a/src/DotNet/Writer/MDTableWriter.cs +++ b/src/DotNet/Writer/MDTableWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using dnlib.DotNet.MD; diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 8fc8bdf63..cdee8bd79 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 63895ee13..0f2b71dd2 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/DotNet/Writer/MetadataEvent.cs b/src/DotNet/Writer/MetadataEvent.cs index 20b28dd78..63acdd72e 100644 --- a/src/DotNet/Writer/MetadataEvent.cs +++ b/src/DotNet/Writer/MetadataEvent.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Writer { /// diff --git a/src/DotNet/Writer/ModuleWriterEvent.cs b/src/DotNet/Writer/ModuleWriterEvent.cs index 59899fdef..2845e8f88 100644 --- a/src/DotNet/Writer/ModuleWriterEvent.cs +++ b/src/DotNet/Writer/ModuleWriterEvent.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Writer { /// diff --git a/src/DotNet/Writer/PdbHeap.cs b/src/DotNet/Writer/PdbHeap.cs index f24aea426..c13652d03 100644 --- a/src/DotNet/Writer/PdbHeap.cs +++ b/src/DotNet/Writer/PdbHeap.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using dnlib.IO; diff --git a/src/DotNet/Writer/PortablePdbConstants.cs b/src/DotNet/Writer/PortablePdbConstants.cs index 4866f90a7..3bd5f143d 100644 --- a/src/DotNet/Writer/PortablePdbConstants.cs +++ b/src/DotNet/Writer/PortablePdbConstants.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Writer { static class PortablePdbConstants { diff --git a/src/DotNet/Writer/RoslynContentIdProvider.cs b/src/DotNet/Writer/RoslynContentIdProvider.cs index 68ca4b946..f8f466566 100644 --- a/src/DotNet/Writer/RoslynContentIdProvider.cs +++ b/src/DotNet/Writer/RoslynContentIdProvider.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/DotNet/Writer/SerializerMethodContext.cs b/src/DotNet/Writer/SerializerMethodContext.cs index 2e90b80d6..64f42a494 100644 --- a/src/DotNet/Writer/SerializerMethodContext.cs +++ b/src/DotNet/Writer/SerializerMethodContext.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Collections.Generic; using System.Diagnostics; diff --git a/src/DotNet/Writer/WriterUtils.cs b/src/DotNet/Writer/WriterUtils.cs index 4e791e425..52ea2cf0b 100644 --- a/src/DotNet/Writer/WriterUtils.cs +++ b/src/DotNet/Writer/WriterUtils.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.DotNet.Writer { static class WriterUtils { diff --git a/src/HandleProcessCorruptedStateExceptionsAttribute.cs b/src/HandleProcessCorruptedStateExceptionsAttribute.cs index 82c75e2af..a1cdf67e7 100644 --- a/src/HandleProcessCorruptedStateExceptionsAttribute.cs +++ b/src/HandleProcessCorruptedStateExceptionsAttribute.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info #if NET35 namespace System.Runtime.ExceptionServices { diff --git a/src/IO/AlignedByteArrayDataStream.cs b/src/IO/AlignedByteArrayDataStream.cs index ae707157c..bad123ab0 100644 --- a/src/IO/AlignedByteArrayDataStream.cs +++ b/src/IO/AlignedByteArrayDataStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/IO/AlignedNativeMemoryDataStream.cs b/src/IO/AlignedNativeMemoryDataStream.cs index 12d500c06..6f9392c90 100644 --- a/src/IO/AlignedNativeMemoryDataStream.cs +++ b/src/IO/AlignedNativeMemoryDataStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/IO/ByteArrayDataReaderFactory.cs b/src/IO/ByteArrayDataReaderFactory.cs index 8fda651eb..a452b28c9 100644 --- a/src/IO/ByteArrayDataReaderFactory.cs +++ b/src/IO/ByteArrayDataReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 4c2875a4d..f97968575 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/IO/DataReaderFactory.cs b/src/IO/DataReaderFactory.cs index 1cca2f230..a224011d5 100644 --- a/src/IO/DataReaderFactory.cs +++ b/src/IO/DataReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/IO/DataReaderFactoryFactory.cs b/src/IO/DataReaderFactoryFactory.cs index e0c26061b..aa72044b7 100644 --- a/src/IO/DataReaderFactoryFactory.cs +++ b/src/IO/DataReaderFactoryFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/IO/DataReaderStream.cs b/src/IO/DataReaderStream.cs index 3732c1fdc..86073c623 100644 --- a/src/IO/DataReaderStream.cs +++ b/src/IO/DataReaderStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.IO; diff --git a/src/IO/DataStream.cs b/src/IO/DataStream.cs index 8775cd5ba..654374a3b 100644 --- a/src/IO/DataStream.cs +++ b/src/IO/DataStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Text; diff --git a/src/IO/DataStreamFactory.cs b/src/IO/DataStreamFactory.cs index 7a914b180..af204c5f4 100644 --- a/src/IO/DataStreamFactory.cs +++ b/src/IO/DataStreamFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/IO/EmptyDataStream.cs b/src/IO/EmptyDataStream.cs index 55fa44dba..5c83c51da 100644 --- a/src/IO/EmptyDataStream.cs +++ b/src/IO/EmptyDataStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System.Text; diff --git a/src/IO/MemoryMappedDataReaderFactory.cs b/src/IO/MemoryMappedDataReaderFactory.cs index 28b69b276..0a4c117bb 100644 --- a/src/IO/MemoryMappedDataReaderFactory.cs +++ b/src/IO/MemoryMappedDataReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/IO/NativeMemoryDataReaderFactory.cs b/src/IO/NativeMemoryDataReaderFactory.cs index 2b337a9e4..83aa796a9 100644 --- a/src/IO/NativeMemoryDataReaderFactory.cs +++ b/src/IO/NativeMemoryDataReaderFactory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/IO/UnalignedByteArrayDataStream.cs b/src/IO/UnalignedByteArrayDataStream.cs index 5a05e8127..9b7d49723 100644 --- a/src/IO/UnalignedByteArrayDataStream.cs +++ b/src/IO/UnalignedByteArrayDataStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/IO/UnalignedNativeMemoryDataStream.cs b/src/IO/UnalignedNativeMemoryDataStream.cs index fed08f046..3cbffd82e 100644 --- a/src/IO/UnalignedNativeMemoryDataStream.cs +++ b/src/IO/UnalignedNativeMemoryDataStream.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.InteropServices; diff --git a/src/PE/ImageDebugDirectory.cs b/src/PE/ImageDebugDirectory.cs index 580f99a2f..2769cfe3a 100644 --- a/src/PE/ImageDebugDirectory.cs +++ b/src/PE/ImageDebugDirectory.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/PE/ImageDebugType.cs b/src/PE/ImageDebugType.cs index 33eaa2dbf..bbb1306ae 100644 --- a/src/PE/ImageDebugType.cs +++ b/src/PE/ImageDebugType.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib.PE { /// diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index 8fad2555f..c9b525cd8 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Diagnostics; diff --git a/src/Settings.cs b/src/Settings.cs index 277b25470..5b3af88be 100644 --- a/src/Settings.cs +++ b/src/Settings.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info namespace dnlib { /// diff --git a/src/Threading/ICancellationToken.cs b/src/Threading/ICancellationToken.cs index e7f74c0be..8558f122a 100644 --- a/src/Threading/ICancellationToken.cs +++ b/src/Threading/ICancellationToken.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; diff --git a/src/Threading/Lock.cs b/src/Threading/Lock.cs index c6f58b2b6..0a8475592 100644 --- a/src/Threading/Lock.cs +++ b/src/Threading/Lock.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Runtime.Serialization; diff --git a/src/Utils/ArrayEmpty.cs b/src/Utils/ArrayEmpty.cs index b214b53b6..f056fc379 100644 --- a/src/Utils/ArrayEmpty.cs +++ b/src/Utils/ArrayEmpty.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info // System namespace so it can easily be replaced with Array.Empty later namespace System { diff --git a/src/Utils/CollectionDebugView.cs b/src/Utils/CollectionDebugView.cs index 60f417e1d..d56d09daf 100644 --- a/src/Utils/CollectionDebugView.cs +++ b/src/Utils/CollectionDebugView.cs @@ -1,4 +1,4 @@ -// dnlib: See LICENSE.txt for more info +// dnlib: See LICENSE.txt for more info using System; using System.Collections.Generic; From e47dbbbbe4f4dfdf99712416fa6cd64a23f96e79 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 1 Jan 2019 13:06:13 +0100 Subject: [PATCH 259/511] Update .editorconfig --- .editorconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index e50fdca43..63fd71df8 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,15 +1,15 @@ root = true [*] +charset = utf-8 #end_of_line = indent_size = 4 indent_style = tab -insert_final_newline = true tab_width = 4 [*.json] -[App.config] +[app.config] [*.yml] indent_size = 2 @@ -29,6 +29,8 @@ indent_style = space indent_style = space [*.{cs,vb}] +insert_final_newline = true + dotnet_separate_import_directive_groups = false dotnet_sort_system_directives_first = true dotnet_style_coalesce_expression = true:suggestion From 4c94246d99cd8593354b495c2a994d0f19e6e2e6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 2 Jan 2019 16:23:36 +0100 Subject: [PATCH 260/511] Update sourcelink version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a38f22b7f..5fdede399 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -49,7 +49,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + From b00ead9d0ce309b8e7fb7d86039cdf01cd8ff4ab Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 2 Jan 2019 16:23:44 +0100 Subject: [PATCH 261/511] Use PackageLicenseExpression --- src/dnlib.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 5fdede399..7452060be 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -22,7 +22,7 @@ $(Version) 0xd4d https://github.com/0xd4d/dnlib - https://github.com/0xd4d/dnlib/blob/master/LICENSE.txt + MIT $(InformationalVersion) dotnet;assembly;module;reader;writer;PDB;PortablePdb;WindowsPdb;IL;CIL;MSIL;metadata strict @@ -44,7 +44,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + From 8cedb9b020fa577deb0af6e72ccd778c2f91d795 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 18 Jan 2019 04:29:18 +0100 Subject: [PATCH 262/511] Update README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 06e49a0ee..399492311 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,6 @@ .NET module/assembly reader/writer library -NuGet ------ - -[![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) - Compiling --------- From 728f2f4d9c3a2fa6b954a15e7d698581c1b05812 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 19 Jan 2019 09:20:07 +0100 Subject: [PATCH 263/511] Update links --- src/DotNet/StrongNameKey.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/StrongNameKey.cs b/src/DotNet/StrongNameKey.cs index 8db339bef..025ca6336 100644 --- a/src/DotNet/StrongNameKey.cs +++ b/src/DotNet/StrongNameKey.cs @@ -337,8 +337,8 @@ public StrongNameKey(Stream stream) : this(new BinaryReader(stream)) { } public StrongNameKey(BinaryReader reader) { /* * Links: - * http://msdn.microsoft.com/en-us/library/cc250013%28v=prot.20%29.aspx - * http://msdn.microsoft.com/en-us/library/windows/desktop/aa387689%28v=vs.85%29.aspx + * https://msdn.microsoft.com/en-us/library/cc250013%28v=prot.20%29.aspx + * https://docs.microsoft.com/en-us/windows/desktop/SecCrypto/rsa-schannel-key-blobs * * struct PublicKeyBlob { * unsigned int SigAlgID; // sig algorithm used to create the sig (00002400 = CALG_RSA_SIGN) From 41ec86f8ae635effa01e723501e2ae0d531b6392 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 31 Jan 2019 23:14:30 +0100 Subject: [PATCH 264/511] Use snupkg instead of including pdb with nupkg --- src/dnlib.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 7452060be..b197aa555 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,4 +1,4 @@ - + @@ -28,7 +28,8 @@ strict true true - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true + snupkg Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. From e10f3349b978d9e727829c3d1aae8678042157d2 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 31 Jan 2019 23:27:08 +0100 Subject: [PATCH 265/511] Update appveyor.yml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index d5b3ae7f5..2deabe443 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ build: before_package: - cmd: msbuild /m /p:Configuration=Release /t:Pack dnlib.sln artifacts: -- path: src\bin\Release\*.nupkg +- path: src\bin\Release\*.*nupkg name: dnlib NuGet Packages notifications: - provider: Email From 8986f0e00e39146b30a348bbff768aaa84f4701f Mon Sep 17 00:00:00 2001 From: Martin Karing Date: Fri, 1 Feb 2019 00:32:15 +0100 Subject: [PATCH 266/511] GetCachedAssemblies function in AssemblyResolver The dnlib.DotNet.AssemblyResolver class has a new method called GetCachedAssemblies that allows access to the list of assemblies that are currently cached in the resolver. --- src/DotNet/AssemblyResolver.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 60d909155..d72e5a1b8 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -365,6 +365,12 @@ public void Clear() { } } + /// + /// Gets the cached assemblies in this resolver. + /// + /// The cached assemblies. + public IEnumerable GetCachedAssemblies() => cachedAssemblies.Values; + static string GetAssemblyNameKey(IAssembly asmName) { // Make sure the name contains PublicKeyToken= and not PublicKey= return asmName.FullNameToken; From b27db7c0abbd0d522cc3b88405240051aad3cfd1 Mon Sep 17 00:00:00 2001 From: Martin Karing Date: Fri, 1 Feb 2019 01:03:37 +0100 Subject: [PATCH 267/511] MethodBodyChunks - Remove method Added method that allows removing the method body from it's chunk. --- src/DotNet/Writer/MethodBodyChunks.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index 2abc7a91a..759f86421 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -101,6 +101,25 @@ internal MethodBody Add(MethodBody methodBody, RVA origRva, uint origSize) { return methodBody; } + /// Removes the specified method body from this chunk + /// The method body + /// if the method body is removed + /// is + /// + /// as already been called. + ///
- or -
+ /// Reusing of native method bodies is enabled. + ///
+ public bool Remove(MethodBody methodBody) { + if (methodBody == null) throw new ArgumentNullException(nameof(methodBody)); + if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); + if (CanReuseOldBodyLocation) + throw new InvalidOperationException("Reusing old body locations is enabled. Can't remove bodies."); + + var list = methodBody.IsFat ? fatMethods : tinyMethods; + return list.Remove(methodBody); + } + internal void InitializeReusedMethodBodies(IPEImage peImage, uint fileOffsetDelta) { foreach (var info in reusedMethods) { var offset = peImage.ToFileOffset(info.RVA) + fileOffsetDelta; From 1c265af6b37232d486ed0c2afc6952cb515da722 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 1 Feb 2019 07:41:27 +0100 Subject: [PATCH 268/511] Use a lock, remove exception info from XML docs --- src/DotNet/AssemblyResolver.cs | 13 ++++++++++++- src/DotNet/Writer/MethodBodyChunks.cs | 12 ++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index d72e5a1b8..8f146ac64 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Xml; using dnlib.Threading; @@ -369,7 +370,17 @@ public void Clear() { /// Gets the cached assemblies in this resolver. ///
/// The cached assemblies. - public IEnumerable GetCachedAssemblies() => cachedAssemblies.Values; + public IEnumerable GetCachedAssemblies() { + AssemblyDef[] assemblies; +#if THREAD_SAFE + theLock.EnterReadLock(); try { +#endif + assemblies = cachedAssemblies.Values.ToArray(); +#if THREAD_SAFE + } finally { theLock.ExitReadLock(); } +#endif + return assemblies; + } static string GetAssemblyNameKey(IAssembly asmName) { // Make sure the name contains PublicKeyToken= and not PublicKey= diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index 759f86421..1bbcbb8e6 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -104,15 +104,11 @@ internal MethodBody Add(MethodBody methodBody, RVA origRva, uint origSize) { /// Removes the specified method body from this chunk /// The method body /// if the method body is removed - /// is - /// - /// as already been called. - ///
- or -
- /// Reusing of native method bodies is enabled. - ///
public bool Remove(MethodBody methodBody) { - if (methodBody == null) throw new ArgumentNullException(nameof(methodBody)); - if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); + if (methodBody == null) + throw new ArgumentNullException(nameof(methodBody)); + if (setOffsetCalled) + throw new InvalidOperationException("SetOffset() has already been called"); if (CanReuseOldBodyLocation) throw new InvalidOperationException("Reusing old body locations is enabled. Can't remove bodies."); From 1488f8c60d1cbe3cfe1223fee9f616145c0e3f1d Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 20:03:32 +0100 Subject: [PATCH 269/511] Update default image base constants --- src/DotNet/Writer/PEHeaders.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 0c476fa28..745f3e092 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -22,7 +22,7 @@ public sealed class PEHeadersOptions { public const Subsystem DEFAULT_SUBSYSTEM = dnlib.PE.Subsystem.WindowsGui; /// - /// Default major linker version + /// Default major linker version. Roslyn C# defaults to 0x30, and Roslyn VB defaults to 0x50. /// public const byte DEFAULT_MAJOR_LINKER_VERSION = 11; @@ -303,9 +303,9 @@ public void SetOffset(FileOffset offset, RVA rva) { length += (uint)sections.Count * 0x28; if (Use32BitOptionalHeader()) - imageBase = options.ImageBase ?? 0x00400000; + imageBase = options.ImageBase ?? (IsExeFile ? 0x00400000UL : 0x10000000); else - imageBase = options.ImageBase ?? 0x0000000140000000; + imageBase = options.ImageBase ?? (IsExeFile ? 0x0000000140000000UL : 0x0000000180000000); } int SectionsCount { From babe3acd3d2603559df024a88740b2464e06947c Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 20:03:41 +0100 Subject: [PATCH 270/511] Use RVA instead of file offset --- src/DotNet/Pdb/PdbReaderContext.cs | 8 ++++---- src/DotNet/Pdb/Portable/SymbolReaderFactory.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs index 1ac5a0d73..dbf505628 100644 --- a/src/DotNet/Pdb/PdbReaderContext.cs +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -54,13 +54,13 @@ public bool TryGetCodeViewData(out Guid guid, out uint age, out string pdbFilena DataReader GetCodeViewDataReader() { if (codeViewDebugDir == null) return default; - return CreateReader(codeViewDebugDir.PointerToRawData, codeViewDebugDir.SizeOfData); + return CreateReader(codeViewDebugDir.AddressOfRawData, codeViewDebugDir.SizeOfData); } - public DataReader CreateReader(FileOffset offset, uint size) { - if (offset == 0 || size == 0) + public DataReader CreateReader(RVA rva, uint size) { + if (rva == 0 || size == 0) return default; - var reader = peImage.CreateReader(offset, size); + var reader = peImage.CreateReader(rva, size); if (reader.Length != size) return default; return reader; diff --git a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs index dc615d643..35cd3f98d 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs @@ -59,7 +59,7 @@ public static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext p var embeddedDir = pdbContext.TryGetDebugDirectoryEntry(ImageDebugType.EmbeddedPortablePdb); if (embeddedDir == null) return null; - var reader = pdbContext.CreateReader(embeddedDir.PointerToRawData, embeddedDir.SizeOfData); + var reader = pdbContext.CreateReader(embeddedDir.AddressOfRawData, embeddedDir.SizeOfData); if (reader.Length < 8) return null; // "MPDB" = 0x4244504D From 6f5b8d2e9437295cb30c2a7bb8dac335d23cdf62 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 20:03:50 +0100 Subject: [PATCH 271/511] Don't verify debug dir major/minor version when reading portable PDBs --- src/DotNet/Pdb/Portable/SymbolReaderFactory.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs index 35cd3f98d..f5e170d07 100644 --- a/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Portable/SymbolReaderFactory.cs @@ -7,7 +7,6 @@ using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; using dnlib.PE; -using DDW = dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Portable { static class SymbolReaderFactory { @@ -26,12 +25,9 @@ public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFact var debugDir = pdbContext.CodeViewDebugDirectory; if (debugDir == null) return null; - if (debugDir.MinorVersion != DDW.PortablePdbConstants.PortableCodeViewVersionMagic) - return null; - bool validFormatVersion = debugDir.MajorVersion == DDW.PortablePdbConstants.FormatVersion; - Debug.Assert(validFormatVersion, $"New Portable PDB version: 0x{debugDir.MajorVersion:X4}"); - if (!validFormatVersion) - return null; + // Don't check that debugDir.MinorVersion == PortablePdbConstants.PortableCodeViewVersionMagic + // and debugDir.MajorVersion == PortablePdbConstants.FormatVersion since it could be a converted + // WindowsPDB file: https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#codeview-debug-directory-entry-type-2 if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; From cbf1ceabd27b5c04b9eeff9a7e2b59b4f613193b Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 20:03:58 +0100 Subject: [PATCH 272/511] Check for empty DBI stream --- src/DotNet/Pdb/Managed/PdbReader.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index db8ff0142..d2d921d07 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -221,6 +221,9 @@ static uint ReadSizeField(ref DataReader reader) { ushort? ReadModules() { ref var stream = ref streams[STREAM_DBI].Content; + modules = new List(); + if (stream.Length == 0) + return null; stream.Position = 20; ushort symrecStream = stream.ReadUInt16(); stream.Position += 2; @@ -235,7 +238,6 @@ static uint ReadSizeField(ref DataReader reader) { otherSize += ReadSizeField(ref stream); // ecinfoSize stream.Position += 8; - modules = new List(); var moduleStream = stream.Slice(stream.Position, gpmodiSize); while (moduleStream.Position < moduleStream.Length) { var module = new DbiModule(); From 19dfbd66b908eca576e509305c5e975be29c04fc Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 22:43:56 +0100 Subject: [PATCH 273/511] Add an option to override PDB filename stored in the debug dir --- src/DotNet/Writer/ModuleWriterBase.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 9150e1a94..f4e42f1e6 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -320,6 +320,11 @@ public bool Is64Bit { ///
public string PdbFileName { get; set; } + /// + /// PDB file name stored in the debug directory, or null to use + /// + public string PdbFileNameInDebugDirectory { get; set; } + /// /// PDB stream. If this is initialized, then you should also set /// to the name of the PDB file since the file name must be written to the PE debug directory. @@ -911,7 +916,7 @@ void WriteWindowsPdb(PdbState pdbState) { var pdbAge = PdbAge; bool hasContentId = pdbWriter.GetDebugInfo(TheOptions.PdbChecksumAlgorithm, ref pdbAge, out var pdbGuid, out uint stamp, out var idd, out var codeViewData); if (hasContentId) { - debugDirectory.Add(GetCodeViewData(pdbGuid, pdbAge, pdbFilename), + debugDirectory.Add(GetCodeViewData(pdbGuid, pdbAge, TheOptions.PdbFileNameInDebugDirectory ?? pdbFilename), type: ImageDebugType.CodeView, majorVersion: 0, minorVersion: 0, @@ -1044,7 +1049,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { // - Reproducible // - EmbeddedPortablePdb - debugDirectory.Add(GetCodeViewData(pdbGuid, PdbAge, pdbFilename), + debugDirectory.Add(GetCodeViewData(pdbGuid, PdbAge, TheOptions.PdbFileNameInDebugDirectory ?? pdbFilename), type: ImageDebugType.CodeView, majorVersion: PortablePdbConstants.FormatVersion, minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, From ed752475e342fea9646e708da982d492c69eff31 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 22:44:05 +0100 Subject: [PATCH 274/511] Disable net35 target if 'dotnet build' is used --- Examples/Examples.csproj | 2 +- src/dnlib.csproj | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 3ee5bf726..faeb219cd 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,7 +1,7 @@  - net35;net461;netcoreapp2.0 + net461;netcoreapp2.0 Exe diff --git a/src/dnlib.csproj b/src/dnlib.csproj index b197aa555..e1f733325 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -8,6 +8,7 @@ netstandard2.0;net461;netcoreapp2.1 + true $(TargetFrameworks);net35 Reads and writes .NET assemblies and modules From 678ebfc2e06a384c45239fa40d5e6dff4fe329ec Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 5 Feb 2019 23:48:13 +0100 Subject: [PATCH 275/511] Hide obsolete members --- src/DotNet/MD/ComImageFlags.cs | 3 +++ src/DotNet/VTableFixups.cs | 3 +++ src/DotNet/Writer/ModuleWriterBase.cs | 2 ++ src/PE/Characteristics.cs | 2 ++ 4 files changed, 10 insertions(+) diff --git a/src/DotNet/MD/ComImageFlags.cs b/src/DotNet/MD/ComImageFlags.cs index 2f1e2a91c..9752f68b3 100644 --- a/src/DotNet/MD/ComImageFlags.cs +++ b/src/DotNet/MD/ComImageFlags.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.ComponentModel; namespace dnlib.DotNet.MD { /// @@ -17,6 +18,7 @@ public enum ComImageFlags : uint { /// See COMIMAGE_FLAGS_32BITREQUIRED in the Windows SDK /// [Obsolete("Use " + nameof(Bit32Required), error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] _32BitRequired = Bit32Required, /// @@ -48,6 +50,7 @@ public enum ComImageFlags : uint { /// See COMIMAGE_FLAGS_32BITPREFERRED in the Windows SDK /// [Obsolete("Use " + nameof(Bit32Preferred), error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] _32BitPreferred = Bit32Preferred, /// diff --git a/src/DotNet/VTableFixups.cs b/src/DotNet/VTableFixups.cs index 65f1515b9..d8c849fd7 100644 --- a/src/DotNet/VTableFixups.cs +++ b/src/DotNet/VTableFixups.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using dnlib.PE; @@ -86,6 +87,7 @@ public enum VTableFlags : ushort { /// 32-bit vtable slots /// [Obsolete("Use " + nameof(Bit32), error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] _32Bit = Bit32, /// @@ -97,6 +99,7 @@ public enum VTableFlags : ushort { /// 64-bit vtable slots /// [Obsolete("Use " + nameof(Bit64), error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] _64Bit = Bit64, /// diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index f4e42f1e6..e6fdd6ef1 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -12,6 +12,7 @@ using dnlib.DotNet.Pdb.WindowsPdb; using System.Text; using System.IO.Compression; +using System.ComponentModel; namespace dnlib.DotNet.Writer { /// @@ -159,6 +160,7 @@ public class ModuleWriterOptionsBase { /// Gets/sets the listener /// [Obsolete("Use event " + nameof(WriterEvent) + " instead of " + nameof(IModuleWriterListener), error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] public IModuleWriterListener Listener { get => listener; set => listener = value; diff --git a/src/PE/Characteristics.cs b/src/PE/Characteristics.cs index 1656f5f53..1608038f9 100644 --- a/src/PE/Characteristics.cs +++ b/src/PE/Characteristics.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.ComponentModel; namespace dnlib.PE { /// @@ -26,6 +27,7 @@ public enum Characteristics : ushort { BytesReversedLo = 0x0080, /// 32 bit word machine. [Obsolete("Use " + nameof(Bit32Machine), error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] _32BitMachine = Bit32Machine, /// 32 bit word machine. Bit32Machine = 0x0100, From 7d848c1115fd0b4f089818aa215d1258c3d43bd9 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 6 Feb 2019 19:11:59 +0100 Subject: [PATCH 276/511] Remove obsolete members, they were obsoleted 11 months ago --- src/DotNet/MD/ComImageFlags.cs | 17 +------------ src/DotNet/VTableFixups.cs | 15 ----------- src/DotNet/Writer/IModuleWriterListener.cs | 29 ---------------------- src/DotNet/Writer/ModuleWriterBase.cs | 21 ---------------- src/PE/Characteristics.cs | 7 +----- 5 files changed, 2 insertions(+), 87 deletions(-) delete mode 100644 src/DotNet/Writer/IModuleWriterListener.cs diff --git a/src/DotNet/MD/ComImageFlags.cs b/src/DotNet/MD/ComImageFlags.cs index 9752f68b3..0ddef31ed 100644 --- a/src/DotNet/MD/ComImageFlags.cs +++ b/src/DotNet/MD/ComImageFlags.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; -using System.ComponentModel; +using System; namespace dnlib.DotNet.MD { /// @@ -14,13 +13,6 @@ public enum ComImageFlags : uint { /// ILOnly = 1, - /// - /// See COMIMAGE_FLAGS_32BITREQUIRED in the Windows SDK - /// - [Obsolete("Use " + nameof(Bit32Required), error: false)] - [EditorBrowsable(EditorBrowsableState.Never)] - _32BitRequired = Bit32Required, - /// /// See COMIMAGE_FLAGS_32BITREQUIRED in the Windows SDK /// @@ -46,13 +38,6 @@ public enum ComImageFlags : uint { /// TrackDebugData = 0x10000, - /// - /// See COMIMAGE_FLAGS_32BITPREFERRED in the Windows SDK - /// - [Obsolete("Use " + nameof(Bit32Preferred), error: false)] - [EditorBrowsable(EditorBrowsableState.Never)] - _32BitPreferred = Bit32Preferred, - /// /// See COMIMAGE_FLAGS_32BITPREFERRED in the Windows SDK /// diff --git a/src/DotNet/VTableFixups.cs b/src/DotNet/VTableFixups.cs index d8c849fd7..2dfb1c851 100644 --- a/src/DotNet/VTableFixups.cs +++ b/src/DotNet/VTableFixups.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using dnlib.PE; @@ -83,25 +82,11 @@ void Initialize(ModuleDefMD module) { /// [Flags] public enum VTableFlags : ushort { - /// - /// 32-bit vtable slots - /// - [Obsolete("Use " + nameof(Bit32), error: false)] - [EditorBrowsable(EditorBrowsableState.Never)] - _32Bit = Bit32, - /// /// 32-bit vtable slots /// Bit32 = 0x01, - /// - /// 64-bit vtable slots - /// - [Obsolete("Use " + nameof(Bit64), error: false)] - [EditorBrowsable(EditorBrowsableState.Never)] - _64Bit = Bit64, - /// /// 64-bit vtable slots /// diff --git a/src/DotNet/Writer/IModuleWriterListener.cs b/src/DotNet/Writer/IModuleWriterListener.cs deleted file mode 100644 index 7fffefcb7..000000000 --- a/src/DotNet/Writer/IModuleWriterListener.cs +++ /dev/null @@ -1,29 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - /// - /// Gets notified of various events when writing a module - /// - public interface IModuleWriterListener { - /// - /// Called by and its sub classes. - /// - /// The module writer - /// Type of writer event - void OnWriterEvent(ModuleWriterBase writer, ModuleWriterEvent evt); - } - - /// - /// A which does nothing - /// - public sealed class DummyModuleWriterListener : IModuleWriterListener { - /// - /// An instance of this dummy listener - /// - public static readonly DummyModuleWriterListener Instance = new DummyModuleWriterListener(); - - /// - public void OnWriterEvent(ModuleWriterBase writer, ModuleWriterEvent evt) { - } - } -} diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index e6fdd6ef1..91b68cc3c 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -12,7 +12,6 @@ using dnlib.DotNet.Pdb.WindowsPdb; using System.Text; using System.IO.Compression; -using System.ComponentModel; namespace dnlib.DotNet.Writer { /// @@ -145,7 +144,6 @@ public enum PdbWriterOptions { /// Common module writer options base class /// public class ModuleWriterOptionsBase { - IModuleWriterListener listener; PEHeadersOptions peHeadersOptions; Cor20HeaderOptions cor20HeaderOptions; MetadataOptions metadataOptions; @@ -156,16 +154,6 @@ public class ModuleWriterOptionsBase { StrongNamePublicKey strongNamePublicKey; bool delaySign; - /// - /// Gets/sets the listener - /// - [Obsolete("Use event " + nameof(WriterEvent) + " instead of " + nameof(IModuleWriterListener), error: false)] - [EditorBrowsable(EditorBrowsableState.Never)] - public IModuleWriterListener Listener { - get => listener; - set => listener = value; - } - /// /// Raised at various times when writing the file. The listener has a chance to modify /// the file, eg. add extra metadata, encrypt methods, etc. @@ -697,7 +685,6 @@ public void Write(Stream dest) { else if (TheOptions.StrongNameKey != null || TheOptions.StrongNamePublicKey != null) TheOptions.Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; - AddLegacyListener(); destStream = dest; destStreamBaseOffset = destStream.Position; OnWriterEvent(ModuleWriterEvent.Begin); @@ -706,14 +693,6 @@ public void Write(Stream dest) { OnWriterEvent(ModuleWriterEvent.End); } - void AddLegacyListener() { -#pragma warning disable 0618 // Type or member is obsolete - var listener = TheOptions.Listener; -#pragma warning restore 0618 // Type or member is obsolete - if (listener != null) - TheOptions.WriterEvent += (s, e) => listener.OnWriterEvent(e.Writer, e.Event); - } - /// /// Returns the module that is written /// diff --git a/src/PE/Characteristics.cs b/src/PE/Characteristics.cs index 1608038f9..9ec6fe0da 100644 --- a/src/PE/Characteristics.cs +++ b/src/PE/Characteristics.cs @@ -1,7 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; -using System.ComponentModel; +using System; namespace dnlib.PE { /// @@ -26,10 +25,6 @@ public enum Characteristics : ushort { /// Bytes of machine word are reversed. BytesReversedLo = 0x0080, /// 32 bit word machine. - [Obsolete("Use " + nameof(Bit32Machine), error: false)] - [EditorBrowsable(EditorBrowsableState.Never)] - _32BitMachine = Bit32Machine, - /// 32 bit word machine. Bit32Machine = 0x0100, /// Debugging info stripped from file in .DBG file DebugStripped = 0x0200, From 1f703ade894977bb7ea32a7c132c35e17a156d1e Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 6 Feb 2019 19:12:08 +0100 Subject: [PATCH 277/511] Remove BOM chars from files --- src/DotNet/AssemblyHash.cs | 2 +- src/DotNet/AssemblyHashAlgorithm.cs | 2 +- src/DotNet/AssemblyNameComparer.cs | 2 +- src/DotNet/AssemblyResolver.cs | 2 +- src/DotNet/ElementType.cs | 2 +- src/DotNet/Emit/Code.cs | 2 +- src/DotNet/Emit/ExceptionHandler.cs | 2 +- src/DotNet/Emit/ExceptionHandlerType.cs | 2 +- src/DotNet/Emit/Extensions.cs | 2 +- src/DotNet/Emit/FlowControl.cs | 2 +- src/DotNet/Emit/InvalidMethodException.cs | 2 +- src/DotNet/Emit/OpCodeType.cs | 2 +- src/DotNet/Emit/OpCodes.cs | 2 +- src/DotNet/Emit/OperandType.cs | 2 +- src/DotNet/Emit/StackBehaviour.cs | 2 +- src/DotNet/EventAttributes.cs | 2 +- src/DotNet/Extensions.cs | 2 +- src/DotNet/FileAttributes.cs | 2 +- src/DotNet/GenericArguments.cs | 2 +- src/DotNet/ICorLibTypes.cs | 2 +- src/DotNet/IDecrypters.cs | 2 +- src/DotNet/ILogger.cs | 2 +- src/DotNet/IResolver.cs | 2 +- src/DotNet/IType.cs | 2 +- src/DotNet/ITypeDefFinder.cs | 2 +- src/DotNet/IVariable.cs | 2 +- src/DotNet/MD/CodedToken.cs | 2 +- src/DotNet/MD/ColumnSize.cs | 2 +- src/DotNet/MD/DotNetTableSizes.cs | 2 +- src/DotNet/MD/GuidStream.cs | 2 +- src/DotNet/MD/IRowReaders.cs | 2 +- src/DotNet/MD/MDHeaderRuntimeVersion.cs | 2 +- src/DotNet/MD/MDStreamFlags.cs | 2 +- src/DotNet/MD/RawRowEqualityComparer.cs | 2 +- src/DotNet/MD/RawTableRows.cs | 2 +- src/DotNet/MD/StorageFlags.cs | 2 +- src/DotNet/MD/StringsStream.cs | 2 +- src/DotNet/MD/Table.cs | 2 +- src/DotNet/MD/USStream.cs | 2 +- src/DotNet/MDToken.cs | 2 +- src/DotNet/MethodOverride.cs | 2 +- src/DotNet/MethodSemanticsAttributes.cs | 2 +- src/DotNet/ModuleContext.cs | 2 +- src/DotNet/ModuleKind.cs | 2 +- src/DotNet/NullResolver.cs | 2 +- src/DotNet/ParamAttributes.cs | 2 +- src/DotNet/ParameterList.cs | 2 +- src/DotNet/Pdb/Managed/DbiDocument.cs | 2 +- src/DotNet/Pdb/Managed/DbiModule.cs | 2 +- src/DotNet/Pdb/Managed/MsfStream.cs | 2 +- src/DotNet/Pdb/Managed/PdbException.cs | 2 +- src/DotNet/PropertyAttributes.cs | 2 +- src/DotNet/PublicKeyToken.cs | 2 +- src/DotNet/ReflectionExtensions.cs | 2 +- src/DotNet/ResolveException.cs | 2 +- src/DotNet/SecurityAction.cs | 2 +- src/DotNet/SerializationType.cs | 2 +- src/DotNet/StrongNameSigner.cs | 2 +- src/DotNet/TypeNameParser.cs | 2 +- src/DotNet/Writer/BlobHeap.cs | 2 +- src/DotNet/Writer/ChunkList.cs | 2 +- src/DotNet/Writer/CustomAttributeWriter.cs | 2 +- src/DotNet/Writer/IChunk.cs | 2 +- src/DotNet/Writer/IHeap.cs | 2 +- src/DotNet/Writer/ModuleWriterException.cs | 2 +- src/DotNet/Writer/USHeap.cs | 2 +- src/IO/FileOffset.cs | 2 +- src/IO/IOExtensions.cs | 2 +- src/PE/DllCharacteristics.cs | 2 +- src/PE/IImageOptionalHeader.cs | 2 +- src/PE/IPEType.cs | 2 +- src/PE/Machine.cs | 2 +- src/PE/RVA.cs | 2 +- src/PE/Subsystem.cs | 2 +- src/Utils/LazyList.cs | 2 +- src/W32Resources/ResourceDirectoryEntry.cs | 2 +- src/W32Resources/ResourceName.cs | 2 +- src/W32Resources/Win32Resources.cs | 2 +- 78 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/DotNet/AssemblyHash.cs b/src/DotNet/AssemblyHash.cs index ee683adac..85735ff03 100644 --- a/src/DotNet/AssemblyHash.cs +++ b/src/DotNet/AssemblyHash.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.IO; using System.Security.Cryptography; diff --git a/src/DotNet/AssemblyHashAlgorithm.cs b/src/DotNet/AssemblyHashAlgorithm.cs index b1b02853c..d30217d83 100644 --- a/src/DotNet/AssemblyHashAlgorithm.cs +++ b/src/DotNet/AssemblyHashAlgorithm.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Any ALG_CLASS_HASH type in WinCrypt.h can be used by Microsoft's CLI implementation /// diff --git a/src/DotNet/AssemblyNameComparer.cs b/src/DotNet/AssemblyNameComparer.cs index 60088cb89..40660a798 100644 --- a/src/DotNet/AssemblyNameComparer.cs +++ b/src/DotNet/AssemblyNameComparer.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; namespace dnlib.DotNet { diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 8f146ac64..556d8d011 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/src/DotNet/ElementType.cs b/src/DotNet/ElementType.cs index 915974aec..df727e8c0 100644 --- a/src/DotNet/ElementType.cs +++ b/src/DotNet/ElementType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// See CorHdr.h/CorElementType /// diff --git a/src/DotNet/Emit/Code.cs b/src/DotNet/Emit/Code.cs index 59a6fedc8..5d444a10f 100644 --- a/src/DotNet/Emit/Code.cs +++ b/src/DotNet/Emit/Code.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// A CIL opcode. If the high byte is 0 or if it's , it's a 1-byte opcode, /// else it's a two-byte opcode and the highest byte is the first byte of the opcode. diff --git a/src/DotNet/Emit/ExceptionHandler.cs b/src/DotNet/Emit/ExceptionHandler.cs index d0d4ceff8..48b10936c 100644 --- a/src/DotNet/Emit/ExceptionHandler.cs +++ b/src/DotNet/Emit/ExceptionHandler.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// A CIL method exception handler /// diff --git a/src/DotNet/Emit/ExceptionHandlerType.cs b/src/DotNet/Emit/ExceptionHandlerType.cs index 57622149f..d5b80ef1a 100644 --- a/src/DotNet/Emit/ExceptionHandlerType.cs +++ b/src/DotNet/Emit/ExceptionHandlerType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet.Emit { /// diff --git a/src/DotNet/Emit/Extensions.cs b/src/DotNet/Emit/Extensions.cs index 31f88b3d2..fcbb4f39c 100644 --- a/src/DotNet/Emit/Extensions.cs +++ b/src/DotNet/Emit/Extensions.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// Extension methods /// diff --git a/src/DotNet/Emit/FlowControl.cs b/src/DotNet/Emit/FlowControl.cs index a01204541..d29b86fde 100644 --- a/src/DotNet/Emit/FlowControl.cs +++ b/src/DotNet/Emit/FlowControl.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// CIL opcode flow control /// diff --git a/src/DotNet/Emit/InvalidMethodException.cs b/src/DotNet/Emit/InvalidMethodException.cs index 35ffaf40f..8538ac113 100644 --- a/src/DotNet/Emit/InvalidMethodException.cs +++ b/src/DotNet/Emit/InvalidMethodException.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Runtime.Serialization; namespace dnlib.DotNet.Emit { diff --git a/src/DotNet/Emit/OpCodeType.cs b/src/DotNet/Emit/OpCodeType.cs index 473ad433d..a0d6df86f 100644 --- a/src/DotNet/Emit/OpCodeType.cs +++ b/src/DotNet/Emit/OpCodeType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// CIL opcode type /// diff --git a/src/DotNet/Emit/OpCodes.cs b/src/DotNet/Emit/OpCodes.cs index bfcda86ca..2c21d7555 100644 --- a/src/DotNet/Emit/OpCodes.cs +++ b/src/DotNet/Emit/OpCodes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// Contains all valid CIL opcodes /// diff --git a/src/DotNet/Emit/OperandType.cs b/src/DotNet/Emit/OperandType.cs index 1fcd6ee9d..f4fe42fa0 100644 --- a/src/DotNet/Emit/OperandType.cs +++ b/src/DotNet/Emit/OperandType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using dnlib.DotNet.MD; +using dnlib.DotNet.MD; namespace dnlib.DotNet.Emit { /// diff --git a/src/DotNet/Emit/StackBehaviour.cs b/src/DotNet/Emit/StackBehaviour.cs index ccb9e926a..37e323135 100644 --- a/src/DotNet/Emit/StackBehaviour.cs +++ b/src/DotNet/Emit/StackBehaviour.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Emit { +namespace dnlib.DotNet.Emit { /// /// CIL opcode stack behavior /// diff --git a/src/DotNet/EventAttributes.cs b/src/DotNet/EventAttributes.cs index dc01c73c1..abe9ac861 100644 --- a/src/DotNet/EventAttributes.cs +++ b/src/DotNet/EventAttributes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet { /// diff --git a/src/DotNet/Extensions.cs b/src/DotNet/Extensions.cs index 4ed09f1bc..2d5da47b6 100644 --- a/src/DotNet/Extensions.cs +++ b/src/DotNet/Extensions.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Extension methods /// diff --git a/src/DotNet/FileAttributes.cs b/src/DotNet/FileAttributes.cs index f7613b615..3fab691ad 100644 --- a/src/DotNet/FileAttributes.cs +++ b/src/DotNet/FileAttributes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet { /// diff --git a/src/DotNet/GenericArguments.cs b/src/DotNet/GenericArguments.cs index ccd908fb4..3df52028d 100644 --- a/src/DotNet/GenericArguments.cs +++ b/src/DotNet/GenericArguments.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; +using System.Collections.Generic; namespace dnlib.DotNet { readonly struct GenericArgumentsStack { diff --git a/src/DotNet/ICorLibTypes.cs b/src/DotNet/ICorLibTypes.cs index 65dbb5f46..2eb82350a 100644 --- a/src/DotNet/ICorLibTypes.cs +++ b/src/DotNet/ICorLibTypes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Access to .NET core library's simple types /// diff --git a/src/DotNet/IDecrypters.cs b/src/DotNet/IDecrypters.cs index 96e66a5de..dc90367f7 100644 --- a/src/DotNet/IDecrypters.cs +++ b/src/DotNet/IDecrypters.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; +using System.Collections.Generic; using dnlib.PE; using dnlib.DotNet.Emit; diff --git a/src/DotNet/ILogger.cs b/src/DotNet/ILogger.cs index 96d4263a6..494c2ac29 100644 --- a/src/DotNet/ILogger.cs +++ b/src/DotNet/ILogger.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Reflection; using dnlib.DotNet.Writer; diff --git a/src/DotNet/IResolver.cs b/src/DotNet/IResolver.cs index 067d221d4..70c92bb9e 100644 --- a/src/DotNet/IResolver.cs +++ b/src/DotNet/IResolver.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Resolves types, methods, fields /// diff --git a/src/DotNet/IType.cs b/src/DotNet/IType.cs index 03cd92424..520d79251 100644 --- a/src/DotNet/IType.cs +++ b/src/DotNet/IType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Interface to get the full name of a type /// diff --git a/src/DotNet/ITypeDefFinder.cs b/src/DotNet/ITypeDefFinder.cs index 52d654b90..2f4ba4836 100644 --- a/src/DotNet/ITypeDefFinder.cs +++ b/src/DotNet/ITypeDefFinder.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Finds s /// diff --git a/src/DotNet/IVariable.cs b/src/DotNet/IVariable.cs index a80d9d11e..0cb4fb1e3 100644 --- a/src/DotNet/IVariable.cs +++ b/src/DotNet/IVariable.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Interface to access a local or a parameter /// diff --git a/src/DotNet/MD/CodedToken.cs b/src/DotNet/MD/CodedToken.cs index ad1aff2eb..3e3f7495e 100644 --- a/src/DotNet/MD/CodedToken.cs +++ b/src/DotNet/MD/CodedToken.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet.MD { /// diff --git a/src/DotNet/MD/ColumnSize.cs b/src/DotNet/MD/ColumnSize.cs index 942197a11..7784c6630 100644 --- a/src/DotNet/MD/ColumnSize.cs +++ b/src/DotNet/MD/ColumnSize.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.MD { +namespace dnlib.DotNet.MD { /// /// MD table column size /// diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index 82fe5778e..cea936786 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; namespace dnlib.DotNet.MD { diff --git a/src/DotNet/MD/GuidStream.cs b/src/DotNet/MD/GuidStream.cs index 109c819af..0127a46b2 100644 --- a/src/DotNet/MD/GuidStream.cs +++ b/src/DotNet/MD/GuidStream.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using dnlib.IO; namespace dnlib.DotNet.MD { diff --git a/src/DotNet/MD/IRowReaders.cs b/src/DotNet/MD/IRowReaders.cs index 47a1b174e..acb89bc04 100644 --- a/src/DotNet/MD/IRowReaders.cs +++ b/src/DotNet/MD/IRowReaders.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.MD { +namespace dnlib.DotNet.MD { /// /// Reads metadata table columns /// diff --git a/src/DotNet/MD/MDHeaderRuntimeVersion.cs b/src/DotNet/MD/MDHeaderRuntimeVersion.cs index 0eec0e7cc..054e0d6b2 100644 --- a/src/DotNet/MD/MDHeaderRuntimeVersion.cs +++ b/src/DotNet/MD/MDHeaderRuntimeVersion.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.MD { +namespace dnlib.DotNet.MD { /// /// Version strings found in the meta data header /// diff --git a/src/DotNet/MD/MDStreamFlags.cs b/src/DotNet/MD/MDStreamFlags.cs index 6393efac8..92c938f4c 100644 --- a/src/DotNet/MD/MDStreamFlags.cs +++ b/src/DotNet/MD/MDStreamFlags.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet.MD { /// diff --git a/src/DotNet/MD/RawRowEqualityComparer.cs b/src/DotNet/MD/RawRowEqualityComparer.cs index 092463e8c..cf824534c 100644 --- a/src/DotNet/MD/RawRowEqualityComparer.cs +++ b/src/DotNet/MD/RawRowEqualityComparer.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.Collections.Generic; +using System.Collections.Generic; #pragma warning disable 1591 // XML doc comments diff --git a/src/DotNet/MD/RawTableRows.cs b/src/DotNet/MD/RawTableRows.cs index d40cb3e5b..fb3f32466 100644 --- a/src/DotNet/MD/RawTableRows.cs +++ b/src/DotNet/MD/RawTableRows.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.MD { +namespace dnlib.DotNet.MD { #pragma warning disable 1591 // Missing XML comment for publicly visible type or member /// /// Raw contents of an uncompressed Module table row diff --git a/src/DotNet/MD/StorageFlags.cs b/src/DotNet/MD/StorageFlags.cs index 7f9ced41a..c5d03873e 100644 --- a/src/DotNet/MD/StorageFlags.cs +++ b/src/DotNet/MD/StorageFlags.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet.MD { /// diff --git a/src/DotNet/MD/StringsStream.cs b/src/DotNet/MD/StringsStream.cs index 6ab1e7f7a..47df5ea4c 100644 --- a/src/DotNet/MD/StringsStream.cs +++ b/src/DotNet/MD/StringsStream.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using dnlib.IO; +using dnlib.IO; namespace dnlib.DotNet.MD { /// diff --git a/src/DotNet/MD/Table.cs b/src/DotNet/MD/Table.cs index e65c23bc2..6cf111544 100644 --- a/src/DotNet/MD/Table.cs +++ b/src/DotNet/MD/Table.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.MD { +namespace dnlib.DotNet.MD { /// /// The metadata tables /// diff --git a/src/DotNet/MD/USStream.cs b/src/DotNet/MD/USStream.cs index 9a3189843..a6be17e1f 100644 --- a/src/DotNet/MD/USStream.cs +++ b/src/DotNet/MD/USStream.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using dnlib.IO; namespace dnlib.DotNet.MD { diff --git a/src/DotNet/MDToken.cs b/src/DotNet/MDToken.cs index 8802ab622..3663039d9 100644 --- a/src/DotNet/MDToken.cs +++ b/src/DotNet/MDToken.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Diagnostics; using dnlib.DotNet.MD; diff --git a/src/DotNet/MethodOverride.cs b/src/DotNet/MethodOverride.cs index b1714fa97..901ed6081 100644 --- a/src/DotNet/MethodOverride.cs +++ b/src/DotNet/MethodOverride.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Describes which method some method implements /// diff --git a/src/DotNet/MethodSemanticsAttributes.cs b/src/DotNet/MethodSemanticsAttributes.cs index 9780bbabd..488e92e9a 100644 --- a/src/DotNet/MethodSemanticsAttributes.cs +++ b/src/DotNet/MethodSemanticsAttributes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet { /// diff --git a/src/DotNet/ModuleContext.cs b/src/DotNet/ModuleContext.cs index f7959d6be..1696c12f2 100644 --- a/src/DotNet/ModuleContext.cs +++ b/src/DotNet/ModuleContext.cs @@ -2,7 +2,7 @@ using System.Threading; -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// context /// diff --git a/src/DotNet/ModuleKind.cs b/src/DotNet/ModuleKind.cs index 332868238..9cd42c93f 100644 --- a/src/DotNet/ModuleKind.cs +++ b/src/DotNet/ModuleKind.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Module kind /// diff --git a/src/DotNet/NullResolver.cs b/src/DotNet/NullResolver.cs index 454246022..805097d54 100644 --- a/src/DotNet/NullResolver.cs +++ b/src/DotNet/NullResolver.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// A resolver that always fails /// diff --git a/src/DotNet/ParamAttributes.cs b/src/DotNet/ParamAttributes.cs index 5e0ac484a..39146fc4f 100644 --- a/src/DotNet/ParamAttributes.cs +++ b/src/DotNet/ParamAttributes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet { /// diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index 12221d9ce..d0dd96ab4 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using dnlib.Threading; diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index 71611f343..b8b1c2e6b 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Diagnostics; using System.Diagnostics.SymbolStore; using dnlib.DotNet.Pdb.Symbols; diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index 181f3d150..a577e9425 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using dnlib.DotNet.Pdb.Symbols; using dnlib.IO; diff --git a/src/DotNet/Pdb/Managed/MsfStream.cs b/src/DotNet/Pdb/Managed/MsfStream.cs index b43fa8cb3..95cbdf18d 100644 --- a/src/DotNet/Pdb/Managed/MsfStream.cs +++ b/src/DotNet/Pdb/Managed/MsfStream.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using dnlib.IO; namespace dnlib.DotNet.Pdb.Managed { diff --git a/src/DotNet/Pdb/Managed/PdbException.cs b/src/DotNet/Pdb/Managed/PdbException.cs index c382b340c..132025d87 100644 --- a/src/DotNet/Pdb/Managed/PdbException.cs +++ b/src/DotNet/Pdb/Managed/PdbException.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Runtime.Serialization; namespace dnlib.DotNet.Pdb.Managed { diff --git a/src/DotNet/PropertyAttributes.cs b/src/DotNet/PropertyAttributes.cs index c2546b3e6..9e08763af 100644 --- a/src/DotNet/PropertyAttributes.cs +++ b/src/DotNet/PropertyAttributes.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.DotNet { /// diff --git a/src/DotNet/PublicKeyToken.cs b/src/DotNet/PublicKeyToken.cs index fef218f53..7bf0204ea 100644 --- a/src/DotNet/PublicKeyToken.cs +++ b/src/DotNet/PublicKeyToken.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Represents a public key token /// diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index 8ab6332ec..713b11ed9 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Reflection; namespace dnlib.DotNet { diff --git a/src/DotNet/ResolveException.cs b/src/DotNet/ResolveException.cs index 812151a12..dc6f29433 100644 --- a/src/DotNet/ResolveException.cs +++ b/src/DotNet/ResolveException.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Runtime.Serialization; namespace dnlib.DotNet { diff --git a/src/DotNet/SecurityAction.cs b/src/DotNet/SecurityAction.cs index 85fa0a9aa..e93ba3965 100644 --- a/src/DotNet/SecurityAction.cs +++ b/src/DotNet/SecurityAction.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// Security action. See CorHdr.h/CorDeclSecurity /// diff --git a/src/DotNet/SerializationType.cs b/src/DotNet/SerializationType.cs index 16046d3ce..59a46802a 100644 --- a/src/DotNet/SerializationType.cs +++ b/src/DotNet/SerializationType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet { +namespace dnlib.DotNet { /// /// See CorSerializationType/CorHdr.h /// diff --git a/src/DotNet/StrongNameSigner.cs b/src/DotNet/StrongNameSigner.cs index caf619e4c..c30f017f9 100644 --- a/src/DotNet/StrongNameSigner.cs +++ b/src/DotNet/StrongNameSigner.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.IO; using System.Security.Cryptography; diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index 06f99f99b..12728ee92 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index 7559d59e8..129f777ef 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using dnlib.IO; diff --git a/src/DotNet/Writer/ChunkList.cs b/src/DotNet/Writer/ChunkList.cs index 47971ad4b..ab55dba81 100644 --- a/src/DotNet/Writer/ChunkList.cs +++ b/src/DotNet/Writer/ChunkList.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; namespace dnlib.DotNet.Writer { diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index 9e297d029..2d61c8428 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index 24ca5f24b..754be65c2 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System.IO; +using System.IO; using dnlib.IO; using dnlib.PE; diff --git a/src/DotNet/Writer/IHeap.cs b/src/DotNet/Writer/IHeap.cs index 80a871b88..b75e0754e 100644 --- a/src/DotNet/Writer/IHeap.cs +++ b/src/DotNet/Writer/IHeap.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.DotNet.Writer { +namespace dnlib.DotNet.Writer { /// /// .NET Heap interface /// diff --git a/src/DotNet/Writer/ModuleWriterException.cs b/src/DotNet/Writer/ModuleWriterException.cs index 2a6375900..201471396 100644 --- a/src/DotNet/Writer/ModuleWriterException.cs +++ b/src/DotNet/Writer/ModuleWriterException.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Runtime.Serialization; namespace dnlib.DotNet.Writer { diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index f94a648b4..09a858f1e 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections.Generic; using System.IO; using dnlib.IO; diff --git a/src/IO/FileOffset.cs b/src/IO/FileOffset.cs index cdde4fe07..882fe3c4c 100644 --- a/src/IO/FileOffset.cs +++ b/src/IO/FileOffset.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.IO { +namespace dnlib.IO { /// /// Represents a file offset /// diff --git a/src/IO/IOExtensions.cs b/src/IO/IOExtensions.cs index f4d9bbd84..719cdd24b 100644 --- a/src/IO/IOExtensions.cs +++ b/src/IO/IOExtensions.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.IO { +namespace dnlib.IO { /// /// Extension methods /// diff --git a/src/PE/DllCharacteristics.cs b/src/PE/DllCharacteristics.cs index a8bcfc6ac..adc4745f4 100644 --- a/src/PE/DllCharacteristics.cs +++ b/src/PE/DllCharacteristics.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.PE { /// diff --git a/src/PE/IImageOptionalHeader.cs b/src/PE/IImageOptionalHeader.cs index 7d2d23e7c..1fc97d281 100644 --- a/src/PE/IImageOptionalHeader.cs +++ b/src/PE/IImageOptionalHeader.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using dnlib.IO; +using dnlib.IO; namespace dnlib.PE { /// diff --git a/src/PE/IPEType.cs b/src/PE/IPEType.cs index c40f520a4..d4b3ca58b 100644 --- a/src/PE/IPEType.cs +++ b/src/PE/IPEType.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using dnlib.IO; +using dnlib.IO; namespace dnlib.PE { /// diff --git a/src/PE/Machine.cs b/src/PE/Machine.cs index 6a08cb885..79700e4e9 100644 --- a/src/PE/Machine.cs +++ b/src/PE/Machine.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.PE { +namespace dnlib.PE { /// /// IMAGE_FILE_HEADER.Machine enum /// diff --git a/src/PE/RVA.cs b/src/PE/RVA.cs index 3408e6943..14cc70fa9 100644 --- a/src/PE/RVA.cs +++ b/src/PE/RVA.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.PE { +namespace dnlib.PE { /// /// Represents an RVA (relative virtual address) /// diff --git a/src/PE/Subsystem.cs b/src/PE/Subsystem.cs index c89818283..7f24dbcf4 100644 --- a/src/PE/Subsystem.cs +++ b/src/PE/Subsystem.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.PE { +namespace dnlib.PE { /// /// IMAGE_OPTIONAL_HEADER.Subsystem /// diff --git a/src/Utils/LazyList.cs b/src/Utils/LazyList.cs index e79114ab9..7ac86d413 100644 --- a/src/Utils/LazyList.cs +++ b/src/Utils/LazyList.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/W32Resources/ResourceDirectoryEntry.cs b/src/W32Resources/ResourceDirectoryEntry.cs index b407b01f2..b4ddaac37 100644 --- a/src/W32Resources/ResourceDirectoryEntry.cs +++ b/src/W32Resources/ResourceDirectoryEntry.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -namespace dnlib.W32Resources { +namespace dnlib.W32Resources { /// /// Base class of and /// diff --git a/src/W32Resources/ResourceName.cs b/src/W32Resources/ResourceName.cs index e996d3b72..cecb08a4d 100644 --- a/src/W32Resources/ResourceName.cs +++ b/src/W32Resources/ResourceName.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; namespace dnlib.W32Resources { /// diff --git a/src/W32Resources/Win32Resources.cs b/src/W32Resources/Win32Resources.cs index 58aeb525b..9cb1fc503 100644 --- a/src/W32Resources/Win32Resources.cs +++ b/src/W32Resources/Win32Resources.cs @@ -1,6 +1,6 @@ // dnlib: See LICENSE.txt for more info -using System; +using System; using System.Threading; using dnlib.Utils; using dnlib.IO; From daa2eb0c6ac60649f3a80b9e8dab4dc8246f5794 Mon Sep 17 00:00:00 2001 From: dyarkovoy Date: Wed, 13 Feb 2019 15:57:00 +0200 Subject: [PATCH 278/511] Customize importing of System.Type's (#245) * moved mapper?.Map(type) inside TryResolve() --- src/DotNet/Importer.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 4cd9b9daa..ba7945007 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -74,6 +74,14 @@ public abstract class ImportMapper { /// referenced by the entity that is being imported. /// matching or null if there's no match. public virtual MemberRef Map(MemberRef source) => null; + + /// + /// Overrides default behavior of + /// May be used to use reference assemblies for resolution, for example. + /// + /// to create for. + /// or null to use default 's type resolution + public virtual TypeRef Map(Type source) => null; } /// @@ -330,7 +338,7 @@ static bool Equals(IAssembly a, IAssembly b) { UTF8String.CaseInsensitiveEquals(a.Culture, b.Culture); } - ITypeDefOrRef CreateTypeRef(Type type) => TryResolve(CreateTypeRef2(type)); + ITypeDefOrRef CreateTypeRef(Type type) => TryResolve(mapper?.Map(type) ?? CreateTypeRef2(type)); TypeRef CreateTypeRef2(Type type) { if (!type.IsNested) From b11a184f53ccde49297f1db3369fe6bfbb128c14 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsI@users.noreply.github.com> Date: Wed, 13 Feb 2019 18:40:31 +0100 Subject: [PATCH 279/511] Build dnlib on UNIX-based OS (#247) Build dnlib on UNIX-based OS --- Examples/Examples.csproj | 3 ++- src/dnlib.csproj | 12 ++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index faeb219cd..6079ae119 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,7 +1,8 @@  - net461;netcoreapp2.0 + netcoreapp2.1 + $(TargetFrameworks);net461 Exe diff --git a/src/dnlib.csproj b/src/dnlib.csproj index e1f733325..a06b57e38 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -5,7 +5,8 @@ $(DefineConstants);$(MoreDefineConstants) $(DefineConstants);THREAD_SAFE - netstandard2.0;net461;netcoreapp2.1 + netstandard2.0;netcoreapp2.1 + $(TargetFrameworks);net461 true @@ -66,13 +67,4 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof $(DefineConstants);TRACE - - true - - /usr/lib/mono/2.0-api - /usr/local/lib/mono/2.0-api - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.0-api - /usr/local/Cellar/mono/4.6.2.16/lib/mono/2.0-api - - From c39b8ba1282f77cbf8c1d3fa72c3e0198936c98c Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 13 Feb 2019 18:44:35 +0100 Subject: [PATCH 280/511] Update csproj --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a06b57e38..3659b892e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -36,7 +36,7 @@ Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. For better *Windows PDB* writer support, you should add a reference to `Microsoft.DiaSymReader.Native` nuget package too, see the dnlib README for more info: https://github.com/0xd4d/dnlib#windows-pdbs . You don't need to do anything special for *Portable PDB* support. - + ..\dnlib.snk From 830b646172bfa1ed73382a4c903a69303b2dbc3f Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 13 Feb 2019 18:47:08 +0100 Subject: [PATCH 281/511] Disable pack --- Examples/Examples.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 6079ae119..5509ffff9 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -4,6 +4,7 @@ netcoreapp2.1 $(TargetFrameworks);net461 Exe + false From aee8a875ef87d73396f6e5b998882b3e6fa53c10 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 13 Feb 2019 18:51:02 +0100 Subject: [PATCH 282/511] Update sln --- dnlib.sln | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/dnlib.sln b/dnlib.sln index 87236a6c1..50fd6003d 100644 --- a/dnlib.sln +++ b/dnlib.sln @@ -10,35 +10,17 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {FDFC1237-143F-4919-8318-4926901F4639}.Debug|x86.ActiveCfg = Debug|Any CPU {FDFC1237-143F-4919-8318-4926901F4639}.Release|Any CPU.ActiveCfg = Release|Any CPU {FDFC1237-143F-4919-8318-4926901F4639}.Release|Any CPU.Build.0 = Release|Any CPU - {FDFC1237-143F-4919-8318-4926901F4639}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {FDFC1237-143F-4919-8318-4926901F4639}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {FDFC1237-143F-4919-8318-4926901F4639}.Release|x86.ActiveCfg = Release|Any CPU {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.ActiveCfg = Debug|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.Build.0 = Debug|Any CPU {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Any CPU.ActiveCfg = Release|Any CPU {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Any CPU.Build.0 = Release|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.ActiveCfg = Release|Any CPU - {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 280f7ad2433a13468fa92cb5326fb61f1af5c8d5 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 15 Feb 2019 19:52:22 +0100 Subject: [PATCH 283/511] Add net452 tf --- Examples/Examples.csproj | 2 +- src/dnlib.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 5509ffff9..24e37dd21 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -2,7 +2,7 @@ netcoreapp2.1 - $(TargetFrameworks);net461 + $(TargetFrameworks);net452 Exe false diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 3659b892e..68740da46 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -6,7 +6,7 @@ $(DefineConstants);$(MoreDefineConstants) $(DefineConstants);THREAD_SAFE netstandard2.0;netcoreapp2.1 - $(TargetFrameworks);net461 + $(TargetFrameworks);net452 true From abe851a1b47fe009e00d4fdee235602c8d7fd72c Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 17 Feb 2019 18:22:21 +0100 Subject: [PATCH 284/511] Remove netcoreapp2.1 tf --- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/PE/ProcessorArchUtils.cs | 2 +- src/dnlib.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index e43a07d27..61977113f 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -27,7 +27,7 @@ static class MethodTableToTypeConverter { static MethodTableToTypeConverter() { if (ptrFieldInfo == null) { -#if NETSTANDARD2_0 || NETCOREAPP +#if NETSTANDARD2_0 var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); #else var asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index c9b525cd8..8af9f611b 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -16,7 +16,7 @@ public static Machine GetProcessCpuArchitecture() { } static class RuntimeInformationUtils { -#if NETSTANDARD2_0 || NETCOREAPP +#if NETSTANDARD2_0 public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => TryGetArchitecture((int)RuntimeInformation.ProcessArchitecture, out machine); #else diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 68740da46..07037c7c1 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -5,7 +5,7 @@ $(DefineConstants);$(MoreDefineConstants) $(DefineConstants);THREAD_SAFE - netstandard2.0;netcoreapp2.1 + netstandard2.0 $(TargetFrameworks);net452 From 7279bd1be7a1c8d431f8e04b354aa6c9f36d86c3 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 17 Feb 2019 18:22:30 +0100 Subject: [PATCH 285/511] Update netstandard checks --- src/DotNet/Emit/MethodTableToTypeConverter.cs | 6 +++--- src/DotNet/ModuleDefMD.cs | 2 +- src/PE/ProcessorArchUtils.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index 61977113f..b1d3d7f9a 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -27,7 +27,7 @@ static class MethodTableToTypeConverter { static MethodTableToTypeConverter() { if (ptrFieldInfo == null) { -#if NETSTANDARD2_0 +#if NETSTANDARD var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); #else var asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); @@ -77,7 +77,7 @@ static Type GetTypeNET45(TypeBuilder tb, MethodBuilder mb, IntPtr address) { int maxStack = 8; var locals = GetLocalSignature(address); setMethodBodyMethodInfo.Invoke(mb, new object[5] { code, maxStack, locals, null, null }); -#if NETSTANDARD2_0 +#if NETSTANDARD var type = tb.CreateTypeInfo(); #else var type = tb.CreateType(); @@ -100,7 +100,7 @@ static Type GetTypeNET40(TypeBuilder tb, MethodBuilder mb, IntPtr address) { sigDoneFieldInfo.SetValue(sigHelper, true); currSigFieldInfo.SetValue(sigHelper, locals.Length); signatureFieldInfo.SetValue(sigHelper, locals); -#if NETSTANDARD2_0 +#if NETSTANDARD var type = tb.CreateTypeInfo(); #else var type = tb.CreateType(); diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 7e8cdd82a..9b3cb9376 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -207,7 +207,7 @@ static ImageLayout GetImageLayout(System.Reflection.Module mod) { public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext context, ImageLayout imageLayout) => Load(mod, new ModuleCreationOptions(context), imageLayout); static IntPtr GetModuleHandle(System.Reflection.Module mod) { -#if NETSTANDARD2_0 +#if NETSTANDARD var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new[] { typeof(System.Reflection.Module) }); if (GetHINSTANCE == null) throw new NotSupportedException("System.Reflection.Module loading is not supported on current platform"); diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index 8af9f611b..bc22a78b6 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -16,7 +16,7 @@ public static Machine GetProcessCpuArchitecture() { } static class RuntimeInformationUtils { -#if NETSTANDARD2_0 +#if NETSTANDARD public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => TryGetArchitecture((int)RuntimeInformation.ProcessArchitecture, out machine); #else From 0524b664d3a1808747a6ef3f82026576b14fa4f8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 17 Feb 2019 18:22:38 +0100 Subject: [PATCH 286/511] Don't throw if GetHINSTANCE() doesn't exist --- src/DotNet/ModuleDefMD.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 9b3cb9376..629792a88 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -210,7 +210,7 @@ static IntPtr GetModuleHandle(System.Reflection.Module mod) { #if NETSTANDARD var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new[] { typeof(System.Reflection.Module) }); if (GetHINSTANCE == null) - throw new NotSupportedException("System.Reflection.Module loading is not supported on current platform"); + return IntPtr.Zero; return (IntPtr)GetHINSTANCE.Invoke(null, new[] { mod }); #else From c44e072c3f24cea204cefcc584d972830a916b2e Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 17 Feb 2019 18:22:46 +0100 Subject: [PATCH 287/511] Update if cond --- src/IO/DataReaderStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/DataReaderStream.cs b/src/IO/DataReaderStream.cs index 86073c623..c640190c5 100644 --- a/src/IO/DataReaderStream.cs +++ b/src/IO/DataReaderStream.cs @@ -26,7 +26,7 @@ public DataReaderStream(ref DataReader reader) { public override void Flush() { } bool CheckAndSetPosition() { - if (position < 0 || position > reader.Length) + if ((ulong)position > reader.Length) return false; reader.Position = (uint)position; return true; From a1d0554abe9321ee17e67dbf23a3f1629b678496 Mon Sep 17 00:00:00 2001 From: Martin Karing Date: Sun, 17 Feb 2019 20:29:37 +0100 Subject: [PATCH 288/511] refs #249 Added constructor Added new constructor to the DynamicMethodBodyReader. The new constructor allows setting the importer that is used by the class when reading a dynamic method. --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 67f5550b8..cfe4f3c34 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -105,9 +105,22 @@ public DynamicMethodBodyReader(ModuleDef module, object obj) /// created by DynamicMethod.CreateDelegate(), a DynamicMethod instance, a RTDynamicMethod /// instance or a DynamicResolver instance. /// Generic parameter context - public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext gpContext) { + public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext gpContext) + : this(module, obj, new Importer(module, ImporterOptions.TryToUseDefs, gpContext), gpContext) { + } + + /// + /// Constructor + /// + /// Module that will own the method body + /// This can be one of several supported types: the delegate instance + /// created by DynamicMethod.CreateDelegate(), a DynamicMethod instance, a RTDynamicMethod + /// instance or a DynamicResolver instance. + /// Importer + /// Generic parameter context + public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, GenericParamContext gpContext) { this.module = module; - importer = new Importer(module, ImporterOptions.TryToUseDefs, gpContext); + this.importer = importer; this.gpContext = gpContext; methodName = null; From c860c9940d5bb47885290a0a79bf7e8d4cd3ecdb Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 9 Mar 2019 20:54:38 +0100 Subject: [PATCH 289/511] Ignore arrays with too many dimensions, closes #255 --- src/DotNet/SignatureReader.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index f8acbbc5c..1acd9575d 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -33,6 +33,9 @@ public interface ISignatureReaderHelper { /// Reads signatures from the #Blob stream /// public struct SignatureReader { + // .NET Core and .NET Framework limit arrays to 32 dimensions + const uint MaxArrayRank = 0x20; + readonly ISignatureReaderHelper helper; readonly ICorLibTypes corLibTypes; DataReader reader; @@ -614,12 +617,16 @@ TypeSig ReadType() { uint rank; if (!reader.TryReadCompressedUInt32(out rank)) break; + if (rank > MaxArrayRank) + break; if (rank == 0) { result = new ArraySig(nextType, rank); break; } if (!reader.TryReadCompressedUInt32(out num)) break; + if (num > MaxArrayRank) + break; var sizes = new List((int)num); for (uint i = 0; i < num; i++) { if (!reader.TryReadCompressedUInt32(out uint size)) @@ -628,6 +635,8 @@ TypeSig ReadType() { } if (!reader.TryReadCompressedUInt32(out num)) break; + if (num > MaxArrayRank) + break; var lowerBounds = new List((int)num); for (uint i = 0; i < num; i++) { if (!reader.TryReadCompressedInt32(out int size)) From 6ef111b6ce50c29282044368ea8d15141ad364cf Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 10 Mar 2019 02:03:48 +0100 Subject: [PATCH 290/511] Don't print too many method generic params --- src/DotNet/FullNameFactory.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index 73049c8e4..22f6ed9ae 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -24,6 +24,7 @@ public interface IFullNameFactoryHelper { /// Creates type names, method names, etc. /// public struct FullNameFactory { + const uint MaxMethodGenParamCount = 512; const string RECURSION_ERROR_RESULT_STRING = "<<>>"; const string NULLVALUE = "<<>>"; readonly StringBuilder sb; @@ -2117,6 +2118,8 @@ void CreateMethodFullName(string declaringType, string name, MethodBaseSig metho if (methodSig.Generic) { sb.Append('<'); uint genParamCount = methodSig.GenParamCount; + if (genParamCount > MaxMethodGenParamCount) + genParamCount = MaxMethodGenParamCount; for (uint i = 0; i < genParamCount; i++) { if (i != 0) sb.Append(','); From 69d4291c5e39cfc52850aefa805584bfb72d1b4e Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 10 Mar 2019 02:04:09 +0100 Subject: [PATCH 291/511] Reuse local --- src/DotNet/SignatureReader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 1acd9575d..44b938a5d 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -543,7 +543,7 @@ TypeSig ReadType() { if (!recursionCounter.Increment()) return null; - uint num; + uint num, i; TypeSig nextType, result = null; switch ((ElementType)reader.ReadByte()) { case ElementType.Void: result = corLibTypes.Void; break; @@ -607,7 +607,7 @@ TypeSig ReadType() { break; var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); var args = genericInstSig.GenericArguments; - for (uint i = 0; i < num; i++) + for (i = 0; i < num; i++) args.Add(ReadType()); result = genericInstSig; break; @@ -628,7 +628,7 @@ TypeSig ReadType() { if (num > MaxArrayRank) break; var sizes = new List((int)num); - for (uint i = 0; i < num; i++) { + for (i = 0; i < num; i++) { if (!reader.TryReadCompressedUInt32(out uint size)) goto exit; sizes.Add(size); @@ -638,7 +638,7 @@ TypeSig ReadType() { if (num > MaxArrayRank) break; var lowerBounds = new List((int)num); - for (uint i = 0; i < num; i++) { + for (i = 0; i < num; i++) { if (!reader.TryReadCompressedInt32(out int size)) goto exit; lowerBounds.Add(size); From 358e053374dcdf2f9f03d99cf5c3ef25a63cc989 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 12 Mar 2019 19:54:25 +0100 Subject: [PATCH 292/511] Increase array rank limit --- src/DotNet/SignatureReader.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 44b938a5d..4bdeba9a3 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -33,8 +33,9 @@ public interface ISignatureReaderHelper { /// Reads signatures from the #Blob stream /// public struct SignatureReader { - // .NET Core and .NET Framework limit arrays to 32 dimensions - const uint MaxArrayRank = 0x20; + // .NET Core and .NET Framework limit arrays to 32 dimensions. Use a bigger limit + // so it's possible to read some bad MD, but not big enough to allocate a ton of mem. + const uint MaxArrayRank = 64; readonly ISignatureReaderHelper helper; readonly ICorLibTypes corLibTypes; From ad16f8fd05d227b3764eb2e09974ed695406befa Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 12 Mar 2019 20:09:22 +0100 Subject: [PATCH 293/511] Don't print too many array ranks, update method sig limit too --- src/DotNet/FullNameFactory.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index 22f6ed9ae..8c8f4102c 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -24,7 +24,8 @@ public interface IFullNameFactoryHelper { /// Creates type names, method names, etc. /// public struct FullNameFactory { - const uint MaxMethodGenParamCount = 512; + const uint MaxArrayRank = 100; + const uint MaxMethodGenParamCount = 200; const string RECURSION_ERROR_RESULT_STRING = "<<>>"; const string NULLVALUE = "<<>>"; readonly StringBuilder sb; @@ -1304,6 +1305,8 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { var arraySig = (ArraySig)typeSig; sb.Append('['); uint rank = arraySig.Rank; + if (rank > MaxArrayRank) + rank = MaxArrayRank; if (rank == 0) sb.Append(""); // Not allowed else if (rank == 1) From ab141d52226753fbd950188be8a4d67c5a0adb9f Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 20 Mar 2019 07:22:45 +0100 Subject: [PATCH 294/511] Update tfm --- Examples/Examples.csproj | 2 +- src/dnlib.csproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 24e37dd21..f46f204e1 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -2,7 +2,7 @@ netcoreapp2.1 - $(TargetFrameworks);net452 + $(TargetFrameworks);net45 Exe false diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 07037c7c1..8a53cb939 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,4 +1,4 @@ - + @@ -6,7 +6,7 @@ $(DefineConstants);$(MoreDefineConstants) $(DefineConstants);THREAD_SAFE netstandard2.0 - $(TargetFrameworks);net452 + $(TargetFrameworks);net45 true From 3a823451d4e06475a7eccc1955a32e7c27458695 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 22 Mar 2019 02:14:48 +0100 Subject: [PATCH 295/511] Use arg, closes #261 --- src/DotNet/Importer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index ba7945007..69904d52d 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -142,7 +142,7 @@ public Importer(ModuleDef module, ImporterOptions options) /// Importer options /// Generic parameter context public Importer(ModuleDef module, ImporterOptions options, GenericParamContext gpContext) - : this(module, options, new GenericParamContext(), null) { + : this(module, options, gpContext, null) { } /// From f5ebc631ecbf25a653837864a7bbf1fc819fd683 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 22 Mar 2019 02:29:43 +0100 Subject: [PATCH 296/511] Update new ctor --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 7 +++---- src/DotNet/Importer.cs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index cfe4f3c34..f9389f092 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -106,7 +106,7 @@ public DynamicMethodBodyReader(ModuleDef module, object obj) /// instance or a DynamicResolver instance. /// Generic parameter context public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext gpContext) - : this(module, obj, new Importer(module, ImporterOptions.TryToUseDefs, gpContext), gpContext) { + : this(module, obj, new Importer(module, ImporterOptions.TryToUseDefs, gpContext)) { } /// @@ -117,11 +117,10 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext /// created by DynamicMethod.CreateDelegate(), a DynamicMethod instance, a RTDynamicMethod /// instance or a DynamicResolver instance. /// Importer - /// Generic parameter context - public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, GenericParamContext gpContext) { + public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer) { this.module = module; this.importer = importer; - this.gpContext = gpContext; + gpContext = importer.gpContext; methodName = null; if (obj == null) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 69904d52d..4f6b1a65a 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -90,7 +90,7 @@ public abstract class ImportMapper { /// public struct Importer { readonly ModuleDef module; - readonly GenericParamContext gpContext; + internal readonly GenericParamContext gpContext; readonly ImportMapper mapper; RecursionCounter recursionCounter; ImporterOptions options; From 698134d3acbb3bb17da957420f27686324e91fce Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 23 Mar 2019 12:38:59 +0100 Subject: [PATCH 297/511] Bump version --- src/dnlib.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 8a53cb939..6499c782c 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -1,4 +1,4 @@ - + @@ -20,7 +20,7 @@ dnlib dnlib en-US - 3.1.0 + 3.2.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 71218f355899ee09fe6711bdc4153a71cbe1238a Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 19 Apr 2019 23:56:51 +0200 Subject: [PATCH 298/511] Support SecurityMitigations flag --- src/DotNet/MethodDef.cs | 8 ++++++++ src/DotNet/MethodImplAttributes.cs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 77ad3b28a..861ee24ef 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -851,6 +851,14 @@ public bool IsAggressiveOptimization { set => ModifyImplAttributes(value, MethodImplAttributes.AggressiveOptimization); } + /// + /// Gets/sets the bit + /// + public bool IsSecurityMitigations { + get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.SecurityMitigations) != 0; + set => ModifyImplAttributes(value, MethodImplAttributes.SecurityMitigations); + } + /// /// Gets/sets the bit /// diff --git a/src/DotNet/MethodImplAttributes.cs b/src/DotNet/MethodImplAttributes.cs index e7f9ed93f..b1d3b3a48 100644 --- a/src/DotNet/MethodImplAttributes.cs +++ b/src/DotNet/MethodImplAttributes.cs @@ -44,5 +44,7 @@ public enum MethodImplAttributes : ushort { NoOptimization = 0x0040, /// Method may contain hot code and should be aggressively optimized. AggressiveOptimization = 0x0200, + /// The JIT compiler should look for security mitigation attributes, such as the user-defined System.Runtime.CompilerServices.SecurityMitigationsAttribute. If found, the JIT compiler applies any related security mitigations. Available starting with .NET Framework 4.8. + SecurityMitigations = 0x0400, } } From 703352db3ce54f728f88c4953f303c6413954ca6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 20 Apr 2019 13:37:06 +0200 Subject: [PATCH 299/511] Rename --- src/DotNet/MethodDef.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 861ee24ef..0e0ae44bf 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -854,7 +854,7 @@ public bool IsAggressiveOptimization { /// /// Gets/sets the bit /// - public bool IsSecurityMitigations { + public bool HasSecurityMitigations { get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.SecurityMitigations) != 0; set => ModifyImplAttributes(value, MethodImplAttributes.SecurityMitigations); } From 1d3ae5533a3d379b70893bd3f32dd321987d40e6 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 20 Apr 2019 13:38:07 +0200 Subject: [PATCH 300/511] Verify that method version is 1 --- src/DotNet/Pdb/Managed/PdbReader.cs | 2 ++ src/DotNet/Pdb/Portable/PortablePdbReader.cs | 2 ++ src/DotNet/Pdb/Symbols/SymbolReader.cs | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index d2d921d07..6b5ec3de6 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -317,6 +317,8 @@ void ApplyRidMap(ref DataReader reader) { internal static string ReadCString(ref DataReader reader) => reader.TryReadZeroTerminatedUtf8String() ?? string.Empty; public override SymbolMethod GetMethod(MethodDef method, int version) { + if (version != 1) + return null; if (functions.TryGetValue(method.MDToken.ToInt32(), out var symMethod)) return symMethod; return null; diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index ab3eef414..e5a428a18 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -93,6 +93,8 @@ bool TryGetSymbolDocument(uint rid, out SymbolDocument document) { } public override SymbolMethod GetMethod(MethodDef method, int version) { + if (version != 1) + return null; var mdTable = pdbMetadata.TablesStream.MethodDebugInformationTable; uint methodRid = method.Rid; if (!mdTable.IsValidRID(methodRid)) diff --git a/src/DotNet/Pdb/Symbols/SymbolReader.cs b/src/DotNet/Pdb/Symbols/SymbolReader.cs index 40a1e39d5..2cc995ac2 100644 --- a/src/DotNet/Pdb/Symbols/SymbolReader.cs +++ b/src/DotNet/Pdb/Symbols/SymbolReader.cs @@ -33,7 +33,7 @@ public abstract class SymbolReader : IDisposable { /// Gets a method or returns null if the method doesn't exist in the PDB file /// /// Method - /// Edit and continue version + /// Edit and continue version. The first version is 1 /// public abstract SymbolMethod GetMethod(MethodDef method, int version); From aa1c3accbfe6accba41186652d16245fdf75f7f3 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 23 Apr 2019 13:49:36 +0200 Subject: [PATCH 301/511] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 399492311..22c7d34d7 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,8 @@ Requirements: - `ModuleWriterOptions.Cor20HeaderOptions.Flags`: The `IL Only` bit must be cleared. - It must be a DLL file (see `ModuleWriterOptions.PEHeadersOptions.Characteristics`). The file will fail to load at runtime if it's an EXE file. +NOTE: there appears to be a bug in VS' debugger. If you try to debug managed code that calls an exported method, a fatal execution engine exception is thrown. It repros with VS + debug builds. Workaround: debug a release build or attach to a debug build. See the following issues: [#271](https://github.com/0xd4d/dnlib/issues/271), [#172](https://github.com/0xd4d/dnlib/issues/172) + Type classes ------------ From d59983add143e156c09797d563bc6d27b8520224 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 23 Apr 2019 23:31:04 +0200 Subject: [PATCH 302/511] Update README --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 22c7d34d7..6f46780fa 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,21 @@ Requirements: - `ModuleWriterOptions.Cor20HeaderOptions.Flags`: The `IL Only` bit must be cleared. - It must be a DLL file (see `ModuleWriterOptions.PEHeadersOptions.Characteristics`). The file will fail to load at runtime if it's an EXE file. -NOTE: there appears to be a bug in VS' debugger. If you try to debug managed code that calls an exported method, a fatal execution engine exception is thrown. It repros with VS + debug builds. Workaround: debug a release build or attach to a debug build. See the following issues: [#271](https://github.com/0xd4d/dnlib/issues/271), [#172](https://github.com/0xd4d/dnlib/issues/172) +NOTE: VS' debugger crashes if there's a `DebuggableAttribute` attribute and if the first ctor arg is 0x107. The workaround is to clear the `EnableEditAndContinue` bit: + +```C# +var ca = module.Assembly.CustomAttributes.Find("System.Diagnostics.DebuggableAttribute"); +if (ca != null && ca.ConstructorArguments.Count == 1) { + var arg = ca.ConstructorArguments[0]; + // VS' debugger crashes if value == 0x107, so clear EnC bit + if (arg.Type.FullName == "System.Diagnostics.DebuggableAttribute/DebuggingModes" && arg.Value is int value && value == 0x107) { + arg.Value = value & ~(int)DebuggableAttribute.DebuggingModes.EnableEditAndContinue; + ca.ConstructorArguments[0] = arg; + } +} +``` + +See the following issues: [#271](https://github.com/0xd4d/dnlib/issues/271), [#172](https://github.com/0xd4d/dnlib/issues/172) Type classes ------------ From 26c6a900d5959c74bf71663a7a9e0411e023cac0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 22 May 2019 00:52:16 +0200 Subject: [PATCH 303/511] Truncate streams with invalid size, similar to what older dnlib versions did --- src/DotNet/MD/TablesStream.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index b39f9bd90..054185228 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -243,6 +243,10 @@ void InitializeMdTableReaders() { var currentPos = reader.Position; foreach (var mdTable in mdTables) { var dataLen = (uint)mdTable.TableInfo.RowSize * mdTable.Rows; + if (currentPos > reader.Length) + currentPos = reader.Length; + if ((ulong)currentPos + dataLen > reader.Length) + dataLen = reader.Length - currentPos; mdTable.DataReader = reader.Slice(currentPos, dataLen); var newPos = currentPos + dataLen; if (newPos < currentPos) From 887fb6af2783f47d74716a8b0ba455ba33c84ffd Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 22 May 2019 20:30:37 +0200 Subject: [PATCH 304/511] Add C# 8 readonly members --- src/DotNet/CustomAttribute.cs | 10 ++++---- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 2 +- src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs | 2 +- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 2 +- src/DotNet/Writer/TablesHeap.cs | 3 --- src/IO/DataReader.cs | 24 +++++++++---------- src/IO/DataReaderStream.cs | 2 +- src/dnlib.csproj | 2 +- 8 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/DotNet/CustomAttribute.cs b/src/DotNet/CustomAttribute.cs index 8a363f45a..327afa1f6 100644 --- a/src/DotNet/CustomAttribute.cs +++ b/src/DotNet/CustomAttribute.cs @@ -259,7 +259,7 @@ public struct CAArgument : ICloneable { /// Gets/sets the argument type /// public TypeSig Type { - get => type; + readonly get => type; set => type = value; } @@ -267,7 +267,7 @@ public TypeSig Type { /// Gets/sets the argument value /// public object Value { - get => value; + readonly get => value; set => this.value = value; } @@ -290,14 +290,14 @@ public CAArgument(TypeSig type, object value) { this.value = value; } - object ICloneable.Clone() => Clone(); + readonly object ICloneable.Clone() => Clone(); /// /// Clones this instance and any s and s /// referenced from this instance. /// /// - public CAArgument Clone() { + public readonly CAArgument Clone() { var value = this.value; if (value is CAArgument) value = ((CAArgument)value).Clone(); @@ -314,7 +314,7 @@ public CAArgument Clone() { } /// - public override string ToString() => $"{value ?? "null"} ({type})"; + public override readonly string ToString() => $"{value ?? "null"} ({type})"; } /// diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 73cf8e404..b2f476e75 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -279,7 +279,7 @@ public struct StateMachineHoistedLocalScope { /// /// true if it's a syntesized local ( and are both null) /// - public bool IsSynthesizedLocal => Start == null && End == null; + public readonly bool IsSynthesizedLocal => Start == null && End == null; /// /// The instruction of the first operation in the scope. Can be null if it's a synthesized local diff --git a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs index a358735d3..45535e638 100644 --- a/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs +++ b/src/DotNet/Pdb/Symbols/SymbolSequencePoint.cs @@ -39,7 +39,7 @@ public struct SymbolSequencePoint { /// public int EndColumn; - string GetDebuggerString() { + readonly string GetDebuggerString() { var sb = new StringBuilder(); if (Line == 0xFEEFEE && EndLine == 0xFEEFEE) sb.Append(""); diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 52c4f89dd..6b7fa3e77 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -197,7 +197,7 @@ public CurrentMethod(WindowsPdbWriter pdbWriter, MethodDef method, Dictionary { public bool Equals(RawDummyRow x, RawDummyRow y) => throw new NotSupportedException(); public int GetHashCode(RawDummyRow obj) => throw new NotSupportedException(); } - - public uint Read(int index) => throw new NotSupportedException(); - public void Write(int index, uint value) => throw new NotSupportedException(); } /// diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index f97968575..6d6ab660c 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -25,23 +25,23 @@ public struct DataReader { /// /// Gets the start offset of the data /// - public uint StartOffset => startOffset; + public readonly uint StartOffset => startOffset; /// /// Gets the end offset of the data, not inclusive /// - public uint EndOffset => endOffset; + public readonly uint EndOffset => endOffset; /// /// Gets the total length of the data /// - public uint Length => endOffset - startOffset; + public readonly uint Length => endOffset - startOffset; /// /// Gets the current offset. This is between and (inclusive) /// public uint CurrentOffset { - get => currentOffset; + readonly get => currentOffset; set { VerifyState(); if (value < startOffset || value > endOffset) { @@ -57,7 +57,7 @@ public uint CurrentOffset { /// Gets/sets the position relative to /// public uint Position { - get => currentOffset - startOffset; + readonly get => currentOffset - startOffset; set { VerifyState(); if (value > Length) { @@ -72,7 +72,7 @@ public uint Position { /// /// Gets the number of bytes that can be read without throwing an exception /// - public uint BytesLeft => endOffset - currentOffset; + public readonly uint BytesLeft => endOffset - currentOffset; readonly DataStream stream; readonly uint startOffset; @@ -96,7 +96,7 @@ public DataReader(DataStream stream, uint offset, uint length) { } [Conditional("DEBUG")] - void VerifyState() { + readonly void VerifyState() { Debug.Assert(startOffset <= currentOffset); Debug.Assert(currentOffset <= endOffset); } @@ -167,14 +167,14 @@ public DataReader Slice(int start) { /// /// Length of data /// - public bool CanRead(int length) => length >= 0 && (uint)length <= BytesLeft; + public readonly bool CanRead(int length) => length >= 0 && (uint)length <= BytesLeft; /// /// Checks if it's possible to read bytes /// /// Length of data /// - public bool CanRead(uint length) => length <= BytesLeft; + public readonly bool CanRead(uint length) => length <= BytesLeft; /// /// Reads a @@ -640,7 +640,7 @@ public string ReadSerializedString(Encoding encoding) { /// Returns all data without updating the current position /// /// - public byte[] ToArray() { + public readonly byte[] ToArray() { int length = (int)Length; if (length < 0) ThrowInvalidOperationException(); @@ -750,9 +750,9 @@ public string ReadString(int byteCount, Encoding encoding) { /// Creates a that can access this content. The caller doesn't have to dispose of the returned stream. /// /// - public Stream AsStream() => new DataReaderStream(ref this); + public readonly Stream AsStream() => new DataReaderStream(this); - byte[] AllocTempBuffer() => new byte[(int)Math.Min(0x2000, BytesLeft)]; + readonly byte[] AllocTempBuffer() => new byte[(int)Math.Min(0x2000, BytesLeft)]; /// /// Copies the data, starting from , to diff --git a/src/IO/DataReaderStream.cs b/src/IO/DataReaderStream.cs index c640190c5..738f30557 100644 --- a/src/IO/DataReaderStream.cs +++ b/src/IO/DataReaderStream.cs @@ -18,7 +18,7 @@ public override long Position { DataReader reader; long position; - public DataReaderStream(ref DataReader reader) { + public DataReaderStream(in DataReader reader) { this.reader = reader; position = reader.Position; } diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 6499c782c..94b43c8f8 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -42,7 +42,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof ..\dnlib.snk true - latest + 8.0 true From e5444a934def60aee005bc862a585147a6292903 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 30 May 2019 17:26:02 +0200 Subject: [PATCH 305/511] Update appveyor build worker image to VS2019 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 2deabe443..bd268a4e9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ version: x.x.{build} -image: Visual Studio 2017 +image: Visual Studio 2019 configuration: Release before_build: - cmd: appveyor-retry nuget restore From a75105a4600b5641e42e6ac36847661ae9383701 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 11 Jun 2019 16:11:23 +0200 Subject: [PATCH 306/511] Ignore invalid pdb filenames, closes #275 --- src/DotNet/Pdb/SymbolReaderFactory.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index 97349d009..786d7ba29 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System; using System.IO; using System.Text; using dnlib.DotNet.MD; @@ -22,12 +23,18 @@ public static SymbolReader CreateFromAssemblyFile(PdbReaderOptions options, Meta else pdbFilename = pdbWindowsFilename; - var fileToCheck = assemblyFileName == string.Empty ? pdbFilename : Path.Combine(Path.GetDirectoryName(assemblyFileName), pdbFilename); - if (!File.Exists(fileToCheck)) { - var ext = Path.GetExtension(pdbFilename); - if (string.IsNullOrEmpty(ext)) - ext = "pdb"; - fileToCheck = Path.ChangeExtension(assemblyFileName, ext); + string fileToCheck; + try { + fileToCheck = assemblyFileName == string.Empty ? pdbFilename : Path.Combine(Path.GetDirectoryName(assemblyFileName), pdbFilename); + if (!File.Exists(fileToCheck)) { + var ext = Path.GetExtension(pdbFilename); + if (string.IsNullOrEmpty(ext)) + ext = "pdb"; + fileToCheck = Path.ChangeExtension(assemblyFileName, ext); + } + } + catch (ArgumentException) { + return null;// Invalid filename } return Create(options, metadata, fileToCheck); } From 1e5fb01ba3fc6cf93876b04ac6b93c74be8eb583 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 15 Jun 2019 19:35:43 +0200 Subject: [PATCH 307/511] Update nuget package refs --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 6499c782c..7e77efd80 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -52,7 +52,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + From 4e30b3c9171286c4648246b2ed6fdb04679bd8b7 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 15 Jun 2019 21:43:49 +0200 Subject: [PATCH 308/511] Enable nullablePublicOnly C# feature --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 94b43c8f8..03d46c293 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -27,7 +27,7 @@ MIT $(InformationalVersion) dotnet;assembly;module;reader;writer;PDB;PortablePdb;WindowsPdb;IL;CIL;MSIL;metadata - strict + strict;nullablePublicOnly true true true From 376b4ab277e01079a5cb53fb5ffe7c5d273882d8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 19 Jun 2019 00:19:30 +0200 Subject: [PATCH 309/511] Use ??= --- src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs | 4 ++-- src/DotNet/Writer/Metadata.cs | 10 +++++----- src/DotNet/Writer/ModuleWriter.cs | 2 +- src/DotNet/Writer/ModuleWriterBase.cs | 6 +++--- src/DotNet/Writer/NativeModuleWriter.cs | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 1d06b94b2..6ef10398b 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -133,7 +133,7 @@ static ISymUnmanagedReader CreateSymUnmanagedReader(PdbReaderOptions options) { } if (useOldDiaSymReader) - return (ISymUnmanagedReader)Activator.CreateInstance(CorSymReader_Type ?? (CorSymReader_Type = Type.GetTypeFromCLSID(CLSID_CorSymReader_SxS))); + return (ISymUnmanagedReader)Activator.CreateInstance(CorSymReader_Type ??= Type.GetTypeFromCLSID(CLSID_CorSymReader_SxS)); return null; } @@ -177,7 +177,7 @@ static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) } if (useOldDiaSymReader) - return (ISymUnmanagedWriter2)Activator.CreateInstance(CorSymWriterType ?? (CorSymWriterType = Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS))); + return (ISymUnmanagedWriter2)Activator.CreateInstance(CorSymWriterType ??= Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS)); return null; } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 964c0ef35..4812e232d 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -202,7 +202,7 @@ public sealed class MetadataOptions { /// Gets/sets the options. This is never null. /// public MetadataHeaderOptions MetadataHeaderOptions { - get => metadataHeaderOptions ?? (metadataHeaderOptions = new MetadataHeaderOptions()); + get => metadataHeaderOptions ??= new MetadataHeaderOptions(); set => metadataHeaderOptions = value; } @@ -210,7 +210,7 @@ public MetadataHeaderOptions MetadataHeaderOptions { /// Gets/sets the debug (portable PDB) options. This is never null. /// public MetadataHeaderOptions DebugMetadataHeaderOptions { - get => debugMetadataHeaderOptions ?? (debugMetadataHeaderOptions = MetadataHeaderOptions.CreatePortablePdbV1_0()); + get => debugMetadataHeaderOptions ??= MetadataHeaderOptions.CreatePortablePdbV1_0(); set => debugMetadataHeaderOptions = value; } @@ -218,7 +218,7 @@ public MetadataHeaderOptions DebugMetadataHeaderOptions { /// Gets/sets the options. This is never null. /// public TablesHeapOptions TablesHeapOptions { - get => tablesHeapOptions ?? (tablesHeapOptions = new TablesHeapOptions()); + get => tablesHeapOptions ??= new TablesHeapOptions(); set => tablesHeapOptions = value; } @@ -226,7 +226,7 @@ public TablesHeapOptions TablesHeapOptions { /// Gets/sets the debug (portable PDB) options. This is never null. /// public TablesHeapOptions DebugTablesHeapOptions { - get => tablesHeapOptions ?? (tablesHeapOptions = TablesHeapOptions.CreatePortablePdbV1_0()); + get => tablesHeapOptions ??= TablesHeapOptions.CreatePortablePdbV1_0(); set => tablesHeapOptions = value; } @@ -238,7 +238,7 @@ public TablesHeapOptions DebugTablesHeapOptions { /// /// Extra heaps to add to the metadata. Also see and /// - public List CustomHeaps => customHeaps ?? (customHeaps = new List()); + public List CustomHeaps => customHeaps ??= new List(); /// /// Raised after all heaps have been added. The caller can sort the list if needed diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 138987d45..aa7fa9749 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -54,7 +54,7 @@ public sealed class ModuleWriter : ModuleWriterBase { /// Gets/sets the writer options. This is never null /// public ModuleWriterOptions Options { - get => options ?? (options = new ModuleWriterOptions(module)); + get => options ??= new ModuleWriterOptions(module); set => options = value; } diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 91b68cc3c..ea45d235b 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -190,7 +190,7 @@ public ILogger MetadataLogger { /// Gets/sets the options. This is never null. /// public PEHeadersOptions PEHeadersOptions { - get => peHeadersOptions ?? (peHeadersOptions = new PEHeadersOptions()); + get => peHeadersOptions ??= new PEHeadersOptions(); set => peHeadersOptions = value; } @@ -198,7 +198,7 @@ public PEHeadersOptions PEHeadersOptions { /// Gets/sets the options. This is never null. /// public Cor20HeaderOptions Cor20HeaderOptions { - get => cor20HeaderOptions ?? (cor20HeaderOptions = new Cor20HeaderOptions()); + get => cor20HeaderOptions ??= new Cor20HeaderOptions(); set => cor20HeaderOptions = value; } @@ -206,7 +206,7 @@ public Cor20HeaderOptions Cor20HeaderOptions { /// Gets/sets the options. This is never null. /// public MetadataOptions MetadataOptions { - get => metadataOptions ?? (metadataOptions = new MetadataOptions()); + get => metadataOptions ??= new MetadataOptions(); set => metadataOptions = value; } diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 95694de23..7caa463c2 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -152,7 +152,7 @@ public override string ToString() { /// Gets/sets the writer options. This is never null /// public NativeModuleWriterOptions Options { - get => options ?? (options = new NativeModuleWriterOptions(module, optimizeImageSize: true)); + get => options ??= new NativeModuleWriterOptions(module, optimizeImageSize: true); set => options = value; } From 95635cbe54d8aee4f2be00d05d6ccb1f332b4d75 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 23 Jun 2019 21:08:45 +0200 Subject: [PATCH 310/511] Add TypeDef.IsEquivalent --- src/DotNet/TIAHelper.cs | 6 ++++-- src/DotNet/TypeDef.cs | 5 +++++ src/DotNet/UTF8String.cs | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/DotNet/TIAHelper.cs b/src/DotNet/TIAHelper.cs index 857701cfd..223d208e6 100644 --- a/src/DotNet/TIAHelper.cs +++ b/src/DotNet/TIAHelper.cs @@ -22,8 +22,8 @@ public Info(UTF8String scope, UTF8String identifier) { public bool Equals(Info other) => stricmp(Scope, other.Scope) && UTF8String.Equals(Identifier, other.Identifier); static bool stricmp(UTF8String a, UTF8String b) { - var da = (object)a == null ? null : a.Data; - var db = (object)b == null ? null : b.Data; + var da = a?.Data; + var db = b?.Data; if (da == db) return true; if (da == null || db == null) @@ -110,6 +110,8 @@ static byte[] Concat(byte[] a, byte b, byte[] c) { return data; } + internal static bool IsTypeDefEquivalent(TypeDef td) => GetInfo(td) != null && CheckEquivalent(td); + static bool CheckEquivalent(TypeDef td) { Debug.Assert(td != null); diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index d1064ab8f..db4093d90 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -672,6 +672,11 @@ public bool IsDelegate { /// public bool IsPrimitive => this.IsPrimitive(); + /// + /// Checks whether this type has opted into equivalence + /// + public bool IsEquivalent => TIAHelper.IsTypeDefEquivalent(this); + /// /// Modify property: = /// ( & ) | . diff --git a/src/DotNet/UTF8String.cs b/src/DotNet/UTF8String.cs index 9fab4d90e..a222c7ece 100644 --- a/src/DotNet/UTF8String.cs +++ b/src/DotNet/UTF8String.cs @@ -129,7 +129,7 @@ public static int GetHashCode(UTF8String utf8) { /// Instance #1 or null /// Instance #2 or null /// < 0 if a < b, 0 if a == b, > 0 if a > b - public static int CompareTo(UTF8String a, UTF8String b) => Utils.CompareTo((object)a == null ? null : a.data, (object)b == null ? null : b.data); + public static int CompareTo(UTF8String a, UTF8String b) => Utils.CompareTo(a?.data, b?.data); /// /// Compares two instances (case insensitive) From 9891e5f317fbce4a497d769284076ec25f25973f Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 9 Jul 2019 18:38:00 +0200 Subject: [PATCH 311/511] Update csproj file --- src/dnlib.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 7e77efd80..a339424e9 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -33,7 +33,8 @@ true snupkg - Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. + +Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. For better *Windows PDB* writer support, you should add a reference to `Microsoft.DiaSymReader.Native` nuget package too, see the dnlib README for more info: https://github.com/0xd4d/dnlib#windows-pdbs . You don't need to do anything special for *Portable PDB* support. @@ -52,7 +53,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + From 7a4ba2b71dcc945cead4129bc7c544cdd60f92bb Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 9 Jul 2019 18:38:08 +0200 Subject: [PATCH 312/511] Ignore exceptions due to invalid chars, closes #283 --- src/DotNet/AssemblyResolver.cs | 57 ++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 556d8d011..8a546c690 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -508,7 +508,14 @@ IEnumerable FindAssemblies2(IAssembly assembly, IEnumerable path var exts = assembly.IsContentTypeWindowsRuntime ? winMDAssemblyExtensions : assemblyExtensions; foreach (var ext in exts) { foreach (var path in paths) { - var fullPath = Path.Combine(path, asmSimpleName + ext); + string fullPath; + try { + fullPath = Path.Combine(path, asmSimpleName + ext); + } + catch (ArgumentException) { + // Invalid path chars + yield break; + } if (File.Exists(fullPath)) yield return fullPath; } @@ -549,7 +556,14 @@ protected virtual IEnumerable PostFindAssemblies(IAssembly assembly, Mod /// null or an enumerable of full paths to try protected virtual IEnumerable FindAssemblies(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { if (assembly.IsContentTypeWindowsRuntime) { - var path = Path.Combine(Path.Combine(Environment.SystemDirectory, "WinMetadata"), assembly.Name + ".winmd"); + string path; + try { + path = Path.Combine(Path.Combine(Environment.SystemDirectory, "WinMetadata"), assembly.Name + ".winmd"); + } + catch (ArgumentException) { + // Invalid path chars + path = null; + } if (File.Exists(path)) yield return path; } @@ -596,7 +610,14 @@ IEnumerable FindAssembliesGacExactly(IAssembly assembly, ModuleDef sourc static IEnumerable GetExtraMonoPaths(IAssembly assembly, ModuleDef sourceModule) { if (extraMonoPaths != null) { foreach (var dir in extraMonoPaths) { - var file = Path.Combine(dir, assembly.Name + ".dll"); + string file; + try { + file = Path.Combine(dir, assembly.Name + ".dll"); + } + catch (ArgumentException) { + // Invalid path chars + break; + } if (File.Exists(file)) yield return file; } @@ -614,7 +635,13 @@ IEnumerable FindAssembliesGacExactly(GacInfo gacInfo, IAssembly assembly var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); foreach (var subDir in gacInfo.SubDirs) { var baseDir = Path.Combine(gacInfo.Path, subDir); - baseDir = Path.Combine(baseDir, asmSimpleName); + try { + baseDir = Path.Combine(baseDir, asmSimpleName); + } + catch (ArgumentException) { + // Invalid path chars + break; + } baseDir = Path.Combine(baseDir, $"{gacInfo.Prefix}{verString}_{cultureString}_{pktString}"); var pathName = Path.Combine(baseDir, asmSimpleName + ".dll"); if (File.Exists(pathName)) @@ -639,7 +666,13 @@ IEnumerable FindAssembliesGacAny(GacInfo gacInfo, IAssembly assembly, Mo var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); foreach (var subDir in gacInfo.SubDirs) { var baseDir = Path.Combine(gacInfo.Path, subDir); - baseDir = Path.Combine(baseDir, asmSimpleName); + try { + baseDir = Path.Combine(baseDir, asmSimpleName); + } + catch (ArgumentException) { + // Invalid path chars + break; + } foreach (var dir in GetDirs(baseDir)) { var pathName = Path.Combine(dir, asmSimpleName + ".dll"); if (File.Exists(pathName)) @@ -670,10 +703,16 @@ IEnumerable FindAssembliesModuleSearchPaths(IAssembly assembly, ModuleDe foreach (var path in searchPaths) { for (int i = 0; i < 2; i++) { string path2; - if (i == 0) - path2 = Path.Combine(path, asmSimpleName + ext); - else - path2 = Path.Combine(Path.Combine(path, asmSimpleName), asmSimpleName + ext); + try { + if (i == 0) + path2 = Path.Combine(path, asmSimpleName + ext); + else + path2 = Path.Combine(Path.Combine(path, asmSimpleName), asmSimpleName + ext); + } + catch (ArgumentException) { + // Invalid path chars + yield break; + } if (File.Exists(path2)) yield return path2; } From 913930431eeacfd4cc0a47fe1c4d25ffe8329be0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 14 Jul 2019 17:59:09 +0200 Subject: [PATCH 313/511] Use Module.ScopeName and not Module.Name, closes #284 --- src/DotNet/Importer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 4f6b1a65a..8dadb62b3 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -606,7 +606,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { var asm = module.Context.AssemblyResolver.Resolve(origDeclType.Module.Assembly.GetName(), module); if (asm == null || asm.FullName != origDeclType.Assembly.FullName) throw new Exception("Couldn't resolve the correct assembly"); - var mod = asm.FindModule(origDeclType.Module.Name) as ModuleDefMD; + var mod = asm.FindModule(origDeclType.Module.ScopeName) as ModuleDefMD; if (mod == null) throw new Exception("Couldn't resolve the correct module"); var fieldDef = mod.ResolveField((uint)(origField.MetadataToken & 0x00FFFFFF)); From b4843c7ce1f43429148fb5e008e5bfe5c80e7564 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 14 Jul 2019 18:43:12 +0200 Subject: [PATCH 314/511] Use 'is null' --- Examples/Example1.cs | 2 +- README.md | 2 +- src/DotNet/AllTypesHelper.cs | 2 +- src/DotNet/AssemblyDef.cs | 82 +-- src/DotNet/AssemblyHash.cs | 6 +- src/DotNet/AssemblyNameComparer.cs | 10 +- src/DotNet/AssemblyNameInfo.cs | 8 +- src/DotNet/AssemblyRef.cs | 12 +- src/DotNet/AssemblyResolver.cs | 76 +-- src/DotNet/CallingConventionSig.cs | 4 +- src/DotNet/ClassLayout.cs | 2 +- src/DotNet/Constant.cs | 4 +- src/DotNet/CorLibTypes.cs | 2 +- src/DotNet/CustomAttribute.cs | 8 +- src/DotNet/CustomAttributeCollection.cs | 6 +- src/DotNet/CustomAttributeReader.cs | 46 +- src/DotNet/DeclSecurity.cs | 16 +- src/DotNet/DeclSecurityReader.cs | 2 +- src/DotNet/Emit/DynamicMethodBodyReader.cs | 44 +- src/DotNet/Emit/Instruction.cs | 10 +- src/DotNet/Emit/InstructionPrinter.cs | 12 +- src/DotNet/Emit/MethodBody.cs | 2 +- src/DotNet/Emit/MethodBodyReader.cs | 16 +- src/DotNet/Emit/MethodBodyReaderBase.cs | 16 +- src/DotNet/Emit/MethodTableToTypeConverter.cs | 8 +- src/DotNet/Emit/MethodUtils.cs | 16 +- src/DotNet/Emit/OpCodes.cs | 4 +- src/DotNet/EventDef.cs | 34 +- src/DotNet/ExportedType.cs | 32 +- src/DotNet/FieldDef.cs | 36 +- src/DotNet/FileDef.cs | 6 +- src/DotNet/FrameworkRedirect.cs | 2 +- src/DotNet/FullNameFactory.cs | 138 ++-- src/DotNet/GenericArguments.cs | 8 +- src/DotNet/GenericParam.cs | 10 +- src/DotNet/GenericParamConstraint.cs | 6 +- src/DotNet/GenericParamContext.cs | 4 +- src/DotNet/IAssemblyResolver.cs | 16 +- src/DotNet/ICodedToken.cs | 78 +-- src/DotNet/ICorLibTypes.cs | 8 +- src/DotNet/ILogger.cs | 8 +- src/DotNet/IResolver.cs | 4 +- src/DotNet/IType.cs | 6 +- src/DotNet/ITypeDefFinder.cs | 16 +- src/DotNet/ImplMap.cs | 4 +- src/DotNet/Importer.cs | 144 ++--- src/DotNet/InterfaceImpl.cs | 6 +- src/DotNet/MD/CompressedMetadata.cs | 16 +- src/DotNet/MD/DotNetStream.cs | 6 +- src/DotNet/MD/ENCMetadata.cs | 18 +- src/DotNet/MD/MetadataBase.cs | 64 +- src/DotNet/MD/MetadataFactory.cs | 16 +- src/DotNet/MD/RidList.cs | 6 +- src/DotNet/MD/StringsStream.cs | 2 +- src/DotNet/MD/TablesStream.cs | 8 +- src/DotNet/MD/TablesStream_Read.cs | 8 +- src/DotNet/ManifestResource.cs | 6 +- src/DotNet/MarshalBlobReader.cs | 2 +- src/DotNet/MarshalType.cs | 4 +- src/DotNet/MemberFinder.cs | 124 ++-- src/DotNet/MemberMDInitializer.cs | 2 +- src/DotNet/MemberRef.cs | 46 +- src/DotNet/MethodDef.cs | 40 +- src/DotNet/MethodSpec.cs | 14 +- src/DotNet/ModuleContext.cs | 6 +- src/DotNet/ModuleDef.cs | 74 +-- src/DotNet/ModuleDefMD.cs | 72 +-- src/DotNet/ModuleLoader.cs | 134 ++-- src/DotNet/ModuleRef.cs | 8 +- src/DotNet/ParamDef.cs | 12 +- src/DotNet/ParameterList.cs | 26 +- src/DotNet/Pdb/Dss/MDEmitter.cs | 28 +- src/DotNet/Pdb/Dss/MetaDataImport.cs | 10 +- src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs | 16 +- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 4 +- src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs | 2 +- src/DotNet/Pdb/Dss/SymbolMethodImpl.cs | 14 +- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 12 +- .../Pdb/Dss/SymbolReaderWriterFactory.cs | 6 +- src/DotNet/Pdb/Dss/SymbolScopeImpl.cs | 8 +- src/DotNet/Pdb/Dss/SymbolWriterImpl.cs | 16 +- src/DotNet/Pdb/Managed/DbiDocument.cs | 4 +- src/DotNet/Pdb/Managed/DbiFunction.cs | 10 +- src/DotNet/Pdb/Managed/DbiModule.cs | 8 +- src/DotNet/Pdb/Managed/DbiScope.cs | 18 +- src/DotNet/Pdb/Managed/PdbReader.cs | 10 +- src/DotNet/Pdb/Managed/SymbolReaderFactory.cs | 4 +- src/DotNet/Pdb/PdbConstant.cs | 2 +- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 14 +- src/DotNet/Pdb/PdbDocument.cs | 4 +- src/DotNet/Pdb/PdbReaderContext.cs | 6 +- src/DotNet/Pdb/PdbState.cs | 26 +- .../Pdb/Portable/ImportScopeBlobReader.cs | 6 +- .../Pdb/Portable/ImportScopeBlobWriter.cs | 4 +- .../Portable/LocalConstantSigBlobReader.cs | 4 +- .../Portable/LocalConstantSigBlobWriter.cs | 10 +- .../PortablePdbCustomDebugInfoReader.cs | 30 +- .../PortablePdbCustomDebugInfoWriter.cs | 26 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 38 +- .../Pdb/Portable/SymbolReaderFactory.cs | 8 +- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 8 +- src/DotNet/Pdb/SymbolReaderFactory.cs | 8 +- .../WindowsPdb/PdbCustomDebugInfoReader.cs | 34 +- .../WindowsPdb/PdbCustomDebugInfoWriter.cs | 46 +- .../PseudoCustomDebugInfoFactory.cs | 18 +- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 52 +- src/DotNet/PropertyDef.cs | 38 +- src/DotNet/PublicKey.cs | 4 +- src/DotNet/PublicKeyBase.cs | 18 +- src/DotNet/PublicKeyToken.cs | 2 +- src/DotNet/ReflectionExtensions.cs | 14 +- src/DotNet/Resolver.cs | 30 +- src/DotNet/Resource.cs | 2 +- src/DotNet/ResourceCollection.cs | 16 +- src/DotNet/Resources/BuiltInResourceData.cs | 2 +- src/DotNet/Resources/ResourceDataFactory.cs | 8 +- src/DotNet/Resources/ResourceReader.cs | 4 +- src/DotNet/Resources/ResourceWriter.cs | 2 +- src/DotNet/SecurityAttribute.cs | 2 +- src/DotNet/SigComparer.cs | 594 +++++++++--------- src/DotNet/SignatureReader.cs | 4 +- src/DotNet/StandAloneSig.cs | 6 +- src/DotNet/StrongNameKey.cs | 2 +- src/DotNet/TIAHelper.cs | 34 +- src/DotNet/TypeDef.cs | 166 ++--- src/DotNet/TypeDefFinder.cs | 26 +- src/DotNet/TypeHelper.cs | 26 +- src/DotNet/TypeNameParser.cs | 22 +- src/DotNet/TypeRef.cs | 18 +- src/DotNet/TypeSig.cs | 38 +- src/DotNet/TypeSpec.cs | 18 +- src/DotNet/UTF8String.cs | 22 +- src/DotNet/Utils.cs | 24 +- src/DotNet/WinMDHelpers.cs | 52 +- src/DotNet/Writer/BlobHeap.cs | 16 +- src/DotNet/Writer/ByteArrayChunk.cs | 2 +- src/DotNet/Writer/ChunkList.cs | 4 +- src/DotNet/Writer/CustomAttributeWriter.cs | 68 +- src/DotNet/Writer/DataWriter.cs | 2 +- src/DotNet/Writer/DeclSecurityWriter.cs | 10 +- src/DotNet/Writer/GuidHeap.cs | 8 +- src/DotNet/Writer/IChunk.cs | 4 +- src/DotNet/Writer/ManagedExportsWriter.cs | 18 +- src/DotNet/Writer/MarshalBlobWriter.cs | 6 +- src/DotNet/Writer/MaxStackCalculator.cs | 12 +- src/DotNet/Writer/Metadata.cs | 286 ++++----- src/DotNet/Writer/MethodBody.cs | 6 +- src/DotNet/Writer/MethodBodyChunks.cs | 2 +- src/DotNet/Writer/MethodBodyWriter.cs | 6 +- src/DotNet/Writer/MethodBodyWriterBase.cs | 12 +- src/DotNet/Writer/ModuleWriter.cs | 8 +- src/DotNet/Writer/ModuleWriterBase.cs | 66 +- src/DotNet/Writer/NativeModuleWriter.cs | 44 +- src/DotNet/Writer/NormalMetadata.cs | 36 +- src/DotNet/Writer/PEHeaders.cs | 2 +- src/DotNet/Writer/PreserveTokensMetadata.cs | 62 +- src/DotNet/Writer/RelocDirectory.cs | 6 +- src/DotNet/Writer/SerializerMethodContext.cs | 10 +- src/DotNet/Writer/SignatureWriter.cs | 28 +- src/DotNet/Writer/StartupStub.cs | 10 +- src/DotNet/Writer/StringsHeap.cs | 18 +- src/DotNet/Writer/USHeap.cs | 16 +- src/DotNet/Writer/UniqueChunkList.cs | 2 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 12 +- src/IO/ByteArrayDataReaderFactory.cs | 2 +- src/IO/DataReader.cs | 26 +- src/IO/DataReaderFactoryFactory.cs | 2 +- src/IO/DataReaderStream.cs | 2 +- src/IO/DataStreamFactory.cs | 4 +- src/IO/MemoryMappedDataReaderFactory.cs | 6 +- src/IO/NativeMemoryDataReaderFactory.cs | 2 +- src/PE/PEImage.cs | 8 +- src/PE/PEInfo.cs | 4 +- src/PE/ProcessorArchUtils.cs | 2 +- src/Utils/LazyList.cs | 26 +- src/Utils/SimpleLazyList.cs | 4 +- src/W32Resources/ResourceName.cs | 4 +- src/W32Resources/Win32Resources.cs | 10 +- 178 files changed, 2145 insertions(+), 2145 deletions(-) diff --git a/Examples/Example1.cs b/Examples/Example1.cs index 62c8fd9b5..63ef143a3 100644 --- a/Examples/Example1.cs +++ b/Examples/Example1.cs @@ -18,7 +18,7 @@ public static void Run() { totalNumTypes++; Console.WriteLine(); Console.WriteLine("Type: {0}", type.FullName); - if (type.BaseType != null) + if (!(type.BaseType is null)) Console.WriteLine(" Base type: {0}", type.BaseType.FullName); Console.WriteLine(" Methods: {0}", type.Methods.Count); diff --git a/README.md b/README.md index 6f46780fa..0d4c99f21 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,7 @@ NOTE: VS' debugger crashes if there's a `DebuggableAttribute` attribute and if t ```C# var ca = module.Assembly.CustomAttributes.Find("System.Diagnostics.DebuggableAttribute"); -if (ca != null && ca.ConstructorArguments.Count == 1) { +if (!(ca is null) && ca.ConstructorArguments.Count == 1) { var arg = ca.ConstructorArguments[0]; // VS' debugger crashes if value == 0x107, so clear EnC bit if (arg.Type.FullName == "System.Diagnostics.DebuggableAttribute/DebuggingModes" && arg.Value is int value && value == 0x107) { diff --git a/src/DotNet/AllTypesHelper.cs b/src/DotNet/AllTypesHelper.cs index 6219009b2..a6e5c7465 100644 --- a/src/DotNet/AllTypesHelper.cs +++ b/src/DotNet/AllTypesHelper.cs @@ -14,7 +14,7 @@ readonly struct AllTypesHelper { public static IEnumerable Types(IEnumerable types) { var visited = new Dictionary(); var stack = new Stack>(); - if (types != null) + if (!(types is null)) stack.Push(types.GetEnumerator()); while (stack.Count > 0) { var enumerator = stack.Pop(); diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 0a55a4cb4..75bdd0e14 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -108,7 +108,7 @@ public UTF8String Culture { /// public IList DeclSecurities { get { - if (declSecurities == null) + if (declSecurities is null) InitializeDeclSecurities(); return declSecurities; } @@ -133,7 +133,7 @@ protected virtual void InitializeDeclSecurities() => /// public IList Modules { get { - if (modules == null) + if (modules is null) InitializeModules(); return modules; } @@ -149,7 +149,7 @@ protected virtual void InitializeModules() => /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -175,7 +175,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -340,7 +340,7 @@ public ModuleDef FindModule(UTF8String name) { int count = modules.Count; for (int i = 0; i < count; i++) { var module = modules[i]; - if (module == null) + if (module is null) continue; if (UTF8String.CaseInsensitiveEquals(module.Name, name)) return module; @@ -368,18 +368,18 @@ public static AssemblyDef Load(string fileName, ModuleContext context) => /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(string fileName, ModuleCreationOptions options = null) { - if (fileName == null) + if (fileName is null) throw new ArgumentNullException(nameof(fileName)); ModuleDef module = null; try { module = ModuleDefMD.Load(fileName, options); var asm = module.Assembly; - if (asm == null) + if (asm is null) throw new BadImageFormatException($"{fileName} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { - if (module != null) + if (!(module is null)) module.Dispose(); throw; } @@ -405,18 +405,18 @@ public static AssemblyDef Load(byte[] data, ModuleContext context) => /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(byte[] data, ModuleCreationOptions options = null) { - if (data == null) + if (data is null) throw new ArgumentNullException(nameof(data)); ModuleDef module = null; try { module = ModuleDefMD.Load(data, options); var asm = module.Assembly; - if (asm == null) + if (asm is null) throw new BadImageFormatException($"{module.ToString()} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { - if (module != null) + if (!(module is null)) module.Dispose(); throw; } @@ -448,12 +448,12 @@ public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options = null try { module = ModuleDefMD.Load(addr, options); var asm = module.Assembly; - if (asm == null) + if (asm is null) throw new BadImageFormatException($"{module.ToString()} (addr: {addr.ToInt64():X8}) is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { - if (module != null) + if (!(module is null)) module.Dispose(); throw; } @@ -483,18 +483,18 @@ public static AssemblyDef Load(Stream stream, ModuleContext context) => /// If is null /// If it's not a .NET assembly (eg. not a .NET file or only a .NET module) public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = null) { - if (stream == null) + if (stream is null) throw new ArgumentNullException(nameof(stream)); ModuleDef module = null; try { module = ModuleDefMD.Load(stream, options); var asm = module.Assembly; - if (asm == null) + if (asm is null) throw new BadImageFormatException($"{module.ToString()} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); return asm; } catch { - if (module != null) + if (!(module is null)) module.Dispose(); throw; } @@ -526,10 +526,10 @@ public TypeDef Find(string fullName, bool isReflectionName) { int count = modules.Count; for (int i = 0; i < count; i++) { var module = modules[i]; - if (module == null) + if (module is null) continue; var type = module.Find(fullName, isReflectionName); - if (type != null) + if (!(type is null)) return type; } return null; @@ -547,10 +547,10 @@ public TypeDef Find(TypeRef typeRef) { int count = modules.Count; for (int i = 0; i < count; i++) { var module = modules[i]; - if (module == null) + if (module is null) continue; var type = module.Find(typeRef); - if (type != null) + if (!(type is null)) return type; } return null; @@ -577,7 +577,7 @@ public void Write(Stream dest, ModuleWriterOptions options = null) => /// /// Target assembly public bool IsFriendAssemblyOf(AssemblyDef targetAsm) { - if (targetAsm == null) + if (targetAsm is null) return false; if (this == targetAsm) return true; @@ -623,7 +623,7 @@ public bool IsFriendAssemblyOf(AssemblyDef targetAsm) { /// Signature public key public void UpdateOrCreateAssemblySignatureKeyAttribute(StrongNamePublicKey identityPubKey, StrongNameKey identityKey, StrongNamePublicKey signaturePubKey) { var manifestModule = ManifestModule; - if (manifestModule == null) + if (manifestModule is null) return; // Remove all existing attributes @@ -634,7 +634,7 @@ public void UpdateOrCreateAssemblySignatureKeyAttribute(StrongNamePublicKey iden continue; CustomAttributes.RemoveAt(i); i--; - if (ca == null) + if (ca is null) ca = caTmp; } @@ -652,13 +652,13 @@ public void UpdateOrCreateAssemblySignatureKeyAttribute(StrongNamePublicKey iden bool IsValidAssemblySignatureKeyAttribute(CustomAttribute ca) { if (dnlib.Settings.IsThreadSafe) return false; - if (ca == null) + if (ca is null) return false; var ctor = ca.Constructor; - if (ctor == null) + if (ctor is null) return false; var sig = ctor.MethodSig; - if (sig == null || sig.Params.Count != 2) + if (sig is null || sig.Params.Count != 2) return false; if (sig.Params[0].GetElementType() != ElementType.String) return false; @@ -698,26 +698,26 @@ public virtual bool TryGetOriginalTargetFrameworkAttribute(out string framework, /// void IListListener.OnLazyAdd(int index, ref ModuleDef module) { - if (module == null) + if (module is null) return; #if DEBUG - if (module.Assembly == null) - throw new InvalidOperationException("Module.Assembly == null"); + if (module.Assembly is null) + throw new InvalidOperationException("Module.Assembly is null"); #endif } /// void IListListener.OnAdd(int index, ModuleDef module) { - if (module == null) + if (module is null) return; - if (module.Assembly != null) + if (!(module.Assembly is null)) throw new InvalidOperationException("Module already has an assembly. Remove it from that assembly before adding it to this assembly."); module.Assembly = this; } /// void IListListener.OnRemove(int index, ModuleDef module) { - if (module != null) + if (!(module is null)) module.Assembly = null; } @@ -728,7 +728,7 @@ void IListListener.OnResize(int index) { /// void IListListener.OnClear() { foreach (var module in modules.GetEnumerable_NoLock()) { - if (module != null) + if (!(module is null)) module.Assembly = null; } } @@ -787,9 +787,9 @@ public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey) /// Locale /// If any of the args is invalid public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey, UTF8String locale) { - if ((object)name == null) + if (name is null) throw new ArgumentNullException(nameof(name)); - if ((object)locale == null) + if (locale is null) throw new ArgumentNullException(nameof(locale)); modules = new LazyList(this); this.name = name; @@ -816,7 +816,7 @@ public AssemblyDefUser(AssemblyName asmName) /// Assembly name info /// If is null public AssemblyDefUser(IAssembly asmName) { - if (asmName == null) + if (asmName is null) throw new ArgumentNullException(nameof(asmName)); modules = new LazyList(this); name = asmName.Name; @@ -856,7 +856,7 @@ protected override void InitializeModules() { module = readerModule; else module = readerModule.ReadModule(list2[index - 1], this); - if (module == null) + if (module is null) module = new ModuleDefUser("INVALID", Guid.NewGuid()); module.Assembly = this; return module; @@ -909,10 +909,10 @@ void InitializeTargetFrameworkAttribute() { if (ns != nameSystemRuntimeVersioning || name != nameTargetFrameworkAttribute) continue; var ca = CustomAttributeReader.Read(readerModule, caType, caRow.Value, gpContext); - if (ca == null || ca.ConstructorArguments.Count != 1) + if (ca is null || ca.ConstructorArguments.Count != 1) continue; var s = ca.ConstructorArguments[0].Value as UTF8String; - if ((object)s == null) + if (s is null) continue; if (TryCreateTargetFrameworkInfo(s, out var tmpFramework, out var tmpVersion, out var tmpProfile)) { tfaFramework = tmpFramework; @@ -984,7 +984,7 @@ static bool TryCreateTargetFrameworkInfo(string attrString, out string framework profileRes = value; } } - if (versionRes == null) + if (versionRes is null) return false; framework = frameworkRes; @@ -1029,7 +1029,7 @@ static bool TryParse(string s, out Version version) { /// If is invalid public AssemblyDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.AssemblyTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Assembly rid {rid} does not exist"); diff --git a/src/DotNet/AssemblyHash.cs b/src/DotNet/AssemblyHash.cs index 85735ff03..6a926fd5c 100644 --- a/src/DotNet/AssemblyHash.cs +++ b/src/DotNet/AssemblyHash.cs @@ -52,7 +52,7 @@ public AssemblyHash(AssemblyHashAlgorithm hashAlgo) { /// public void Dispose() { - if (hasher != null) + if (!(hasher is null)) ((IDisposable)hasher).Dispose(); } @@ -65,7 +65,7 @@ public void Dispose() { /// The algorithm to use /// Hashed data or null if was null public static byte[] Hash(byte[] data, AssemblyHashAlgorithm hashAlgo) { - if (data == null) + if (data is null) return null; using (var asmHash = new AssemblyHash(hashAlgo)) { @@ -123,7 +123,7 @@ public byte[] ComputeHash() { /// The data /// A new instance public static PublicKeyToken CreatePublicKeyToken(byte[] publicKeyData) { - if (publicKeyData == null) + if (publicKeyData is null) return new PublicKeyToken(); var hash = Hash(publicKeyData, AssemblyHashAlgorithm.SHA1); var pkt = new byte[8]; diff --git a/src/DotNet/AssemblyNameComparer.cs b/src/DotNet/AssemblyNameComparer.cs index 40660a798..4c4a07826 100644 --- a/src/DotNet/AssemblyNameComparer.cs +++ b/src/DotNet/AssemblyNameComparer.cs @@ -101,9 +101,9 @@ public enum AssemblyNameComparerFlags { public int CompareTo(IAssembly a, IAssembly b) { if (a == b) return 0; - if (a == null) + if (a is null) return -1; - if (b == null) + if (b is null) return 1; int v; @@ -141,9 +141,9 @@ public int CompareTo(IAssembly a, IAssembly b) { public int CompareClosest(IAssembly requested, IAssembly a, IAssembly b) { if (a == b) return 0; - if (a == null) + if (a is null) return !CompareName ? 1 : UTF8String.CaseInsensitiveEquals(requested.Name, b.Name) ? 1 : 0; - if (b == null) + if (b is null) return !CompareName ? 0 : UTF8String.CaseInsensitiveEquals(requested.Name, a.Name) ? 0 : 1; // Compare the most important parts first: @@ -237,7 +237,7 @@ public int CompareClosest(IAssembly requested, IAssembly a, IAssembly b) { /// Assembly name /// The hash code public int GetHashCode(IAssembly a) { - if (a == null) + if (a is null) return 0; int hash = 0; diff --git a/src/DotNet/AssemblyNameInfo.cs b/src/DotNet/AssemblyNameInfo.cs index bc947e9c0..fe199589d 100644 --- a/src/DotNet/AssemblyNameInfo.cs +++ b/src/DotNet/AssemblyNameInfo.cs @@ -229,10 +229,10 @@ public AssemblyNameInfo(string asmFullName) /// /// The assembly public AssemblyNameInfo(IAssembly asm) { - if (asm == null) + if (asm is null) return; var asmDef = asm as AssemblyDef; - hashAlgId = asmDef == null ? 0 : asmDef.HashAlgorithm; + hashAlgId = asmDef is null ? 0 : asmDef.HashAlgorithm; version = asm.Version ?? new Version(0, 0, 0, 0); flags = asm.Attributes; publicKeyOrToken = asm.PublicKeyOrToken; @@ -245,7 +245,7 @@ public AssemblyNameInfo(IAssembly asm) { /// /// Assembly name info public AssemblyNameInfo(AssemblyName asmName) { - if (asmName == null) + if (asmName is null) return; hashAlgId = (AssemblyHashAlgorithm)asmName.HashAlgorithm; version = asmName.Version ?? new Version(0, 0, 0, 0); @@ -253,7 +253,7 @@ public AssemblyNameInfo(AssemblyName asmName) { publicKeyOrToken = (PublicKeyBase)PublicKeyBase.CreatePublicKey(asmName.GetPublicKey()) ?? PublicKeyBase.CreatePublicKeyToken(asmName.GetPublicKeyToken()); name = asmName.Name ?? string.Empty; - culture = asmName.CultureInfo != null && asmName.CultureInfo.Name != null ? asmName.CultureInfo.Name : string.Empty; + culture = !(asmName.CultureInfo is null) && !(asmName.CultureInfo.Name is null) ? asmName.CultureInfo.Name : string.Empty; } /// diff --git a/src/DotNet/AssemblyRef.cs b/src/DotNet/AssemblyRef.cs index d2d0b5f2a..f275854d3 100644 --- a/src/DotNet/AssemblyRef.cs +++ b/src/DotNet/AssemblyRef.cs @@ -117,7 +117,7 @@ public byte[] Hash { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -142,7 +142,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -371,9 +371,9 @@ public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey /// Locale /// If any of the args is invalid public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey, UTF8String locale) { - if ((object)name == null) + if (name is null) throw new ArgumentNullException(nameof(name)); - if ((object)locale == null) + if (locale is null) throw new ArgumentNullException(nameof(locale)); this.name = name; this.version = version ?? throw new ArgumentNullException(nameof(version)); @@ -395,7 +395,7 @@ public AssemblyRefUser(AssemblyName asmName) ///
/// Assembly public AssemblyRefUser(IAssembly assembly) { - if (assembly == null) + if (assembly is null) throw new ArgumentNullException("asmName"); version = assembly.Version ?? new Version(0, 0, 0, 0); @@ -441,7 +441,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public AssemblyRefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.AssemblyRefTable.IsInvalidRID(rid)) throw new BadImageFormatException($"AssemblyRef rid {rid} does not exist"); diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 8a546c690..bc1eab8a5 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -57,7 +57,7 @@ public GacInfo(int version, string prefix, string path, string[] subDirs) { static AssemblyResolver() { gacInfos = new List(); - if (Type.GetType("Mono.Runtime") != null) { + if (!(Type.GetType("Mono.Runtime") is null)) { var dirs = new Dictionary(StringComparer.OrdinalIgnoreCase); var extraMonoPathsList = new List(); foreach (var prefix in FindMonoPrefixes()) { @@ -83,7 +83,7 @@ static AssemblyResolver() { } var paths = Environment.GetEnvironmentVariable("MONO_PATH"); - if (paths != null) { + if (!(paths is null)) { foreach (var tmp in paths.Split(Path.PathSeparator)) { var path = tmp.Trim(); if (path != string.Empty && Directory.Exists(path)) @@ -211,7 +211,7 @@ public AssemblyResolver(ModuleContext defaultModuleContext) { /// public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { - if (assembly == null) + if (assembly is null) return null; if (EnableFrameworkRedirect && !FindExactMatch) @@ -221,7 +221,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { theLock.EnterWriteLock(); try { #endif var resolvedAssembly = Resolve2(assembly, sourceModule); - if (resolvedAssembly == null) { + if (resolvedAssembly is null) { string asmName = UTF8String.ToSystemStringOrEmpty(assembly.Name); string asmNameTrimmed = asmName.Trim(); if (asmName != asmNameTrimmed) { @@ -235,7 +235,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { } } - if (resolvedAssembly == null) { + if (resolvedAssembly is null) { // Make sure we don't search for this assembly again. This speeds up callers who // keep asking for this assembly when trying to resolve many different TypeRefs cachedAssemblies[GetAssemblyNameKey(assembly)] = null; @@ -254,7 +254,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { int count = modules.Count; for (int i = 0; i < count; i++) { var module = modules[i]; - if (module != null) + if (!(module is null)) module.EnableTypeDefFindCache = true; } } @@ -274,7 +274,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { // Dupe assembly. Don't insert it. var dupeModule = resolvedAssembly.ManifestModule; - if (dupeModule != null) + if (!(dupeModule is null)) dupeModule.Dispose(); return asm1 ?? asm2; #if THREAD_SAFE @@ -289,7 +289,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { /// true if 's assembly is cached, false /// if it's not cached because some other assembly with the exact same full name has /// already been cached or if or its assembly is null. - public bool AddToCache(ModuleDef module) => module != null && AddToCache(module.Assembly); + public bool AddToCache(ModuleDef module) => !(module is null) && AddToCache(module.Assembly); /// /// Add an assembly to the assembly cache @@ -299,13 +299,13 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { /// cached because some other assembly with the exact same full name has already been /// cached or if is null. public bool AddToCache(AssemblyDef asm) { - if (asm == null) + if (asm is null) return false; var asmKey = GetAssemblyNameKey(asm); #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (cachedAssemblies.TryGetValue(asmKey, out var cachedAsm) && cachedAsm != null) + if (cachedAssemblies.TryGetValue(asmKey, out var cachedAsm) && !(cachedAsm is null)) return asm == cachedAsm; cachedAssemblies[asmKey] = asm; return true; @@ -321,7 +321,7 @@ public bool AddToCache(AssemblyDef asm) { /// true if its assembly was removed, false if it wasn't removed /// since it wasn't in the cache, it has no assembly, or was /// null - public bool Remove(ModuleDef module) => module != null && Remove(module.Assembly); + public bool Remove(ModuleDef module) => !(module is null) && Remove(module.Assembly); /// /// Removes the assembly from the cache @@ -330,7 +330,7 @@ public bool AddToCache(AssemblyDef asm) { /// true if it was removed, false if it wasn't removed since it /// wasn't in the cache or if was null public bool Remove(AssemblyDef asm) { - if (asm == null) + if (asm is null) return false; var asmKey = GetAssemblyNameKey(asm); #if THREAD_SAFE @@ -359,7 +359,7 @@ public void Clear() { } finally { theLock.ExitWriteLock(); } #endif foreach (var asm in asms) { - if (asm == null) + if (asm is null) continue; foreach (var mod in asm.Modules) mod.Dispose(); @@ -392,13 +392,13 @@ AssemblyDef Resolve2(IAssembly assembly, ModuleDef sourceModule) { return resolvedAssembly; var moduleContext = defaultModuleContext; - if (moduleContext == null && sourceModule != null) + if (moduleContext is null && !(sourceModule is null)) moduleContext = sourceModule.Context; resolvedAssembly = FindExactAssembly(assembly, PreFindAssemblies(assembly, sourceModule, true), moduleContext) ?? FindExactAssembly(assembly, FindAssemblies(assembly, sourceModule, true), moduleContext) ?? FindExactAssembly(assembly, PostFindAssemblies(assembly, sourceModule, true), moduleContext); - if (resolvedAssembly != null) + if (!(resolvedAssembly is null)) return resolvedAssembly; if (!findExactMatch) { @@ -420,7 +420,7 @@ AssemblyDef Resolve2(IAssembly assembly, ModuleDef sourceModule) { /// An instance or null if an exact match /// couldn't be found. AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, ModuleContext moduleContext) { - if (paths == null) + if (paths is null) return null; var asmComparer = AssemblyNameComparer.CompareAll; foreach (var path in paths) { @@ -428,7 +428,7 @@ AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, Mod try { mod = ModuleDefMD.Load(path, moduleContext); var asm = mod.Assembly; - if (asm != null && asmComparer.Equals(assembly, asm)) { + if (!(asm is null) && asmComparer.Equals(assembly, asm)) { mod = null; return asm; } @@ -436,7 +436,7 @@ AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, Mod catch { } finally { - if (mod != null) + if (!(mod is null)) mod.Dispose(); } } @@ -453,7 +453,7 @@ AssemblyDef FindClosestAssembly(IAssembly assembly) { var asmComparer = AssemblyNameComparer.CompareAll; foreach (var kv in cachedAssemblies) { var asm = kv.Value; - if (asm == null) + if (asm is null) continue; if (asmComparer.CompareClosest(assembly, closest, asm) == 1) closest = asm; @@ -462,7 +462,7 @@ AssemblyDef FindClosestAssembly(IAssembly assembly) { } AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumerable paths, ModuleContext moduleContext) { - if (paths == null) + if (paths is null) return closest; var asmComparer = AssemblyNameComparer.CompareAll; foreach (var path in paths) { @@ -470,10 +470,10 @@ AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumer try { mod = ModuleDefMD.Load(path, moduleContext); var asm = mod.Assembly; - if (asm != null && asmComparer.CompareClosest(assembly, closest, asm) == 1) { - if (!IsCached(closest) && closest != null) { + if (!(asm is null) && asmComparer.CompareClosest(assembly, closest, asm) == 1) { + if (!IsCached(closest) && !(closest is null)) { var closeMod = closest.ManifestModule; - if (closeMod != null) + if (!(closeMod is null)) closeMod.Dispose(); } closest = asm; @@ -483,7 +483,7 @@ AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumer catch { } finally { - if (mod != null) + if (!(mod is null)) mod.Dispose(); } } @@ -496,14 +496,14 @@ AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumer /// /// Assembly to check bool IsCached(AssemblyDef asm) { - if (asm == null) + if (asm is null) return false; return cachedAssemblies.TryGetValue(GetAssemblyNameKey(asm), out var cachedAsm) && cachedAsm == asm; } IEnumerable FindAssemblies2(IAssembly assembly, IEnumerable paths) { - if (paths != null) { + if (!(paths is null)) { var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); var exts = assembly.IsContentTypeWindowsRuntime ? winMDAssemblyExtensions : assemblyExtensions; foreach (var ext in exts) { @@ -584,7 +584,7 @@ IEnumerable FindAssembliesGac(IAssembly assembly, ModuleDef sourceModule } IEnumerable GetGacInfos(ModuleDef sourceModule) { - int version = sourceModule == null ? int.MinValue : sourceModule.IsClr40 ? 4 : 2; + int version = sourceModule is null ? int.MinValue : sourceModule.IsClr40 ? 4 : 2; // Try the correct GAC first (eg. GAC4 if it's a .NET 4 assembly) foreach (var gacInfo in gacInfos) { if (gacInfo.Version == version) @@ -601,14 +601,14 @@ IEnumerable FindAssembliesGacExactly(IAssembly assembly, ModuleDef sourc foreach (var path in FindAssembliesGacExactly(gacInfo, assembly, sourceModule)) yield return path; } - if (extraMonoPaths != null) { + if (!(extraMonoPaths is null)) { foreach (var path in GetExtraMonoPaths(assembly, sourceModule)) yield return path; } } static IEnumerable GetExtraMonoPaths(IAssembly assembly, ModuleDef sourceModule) { - if (extraMonoPaths != null) { + if (!(extraMonoPaths is null)) { foreach (var dir in extraMonoPaths) { string file; try { @@ -626,7 +626,7 @@ static IEnumerable GetExtraMonoPaths(IAssembly assembly, ModuleDef sourc IEnumerable FindAssembliesGacExactly(GacInfo gacInfo, IAssembly assembly, ModuleDef sourceModule) { var pkt = PublicKeyBase.ToPublicKeyToken(assembly.PublicKeyOrToken); - if (gacInfo != null && pkt != null) { + if (!(gacInfo is null) && !(pkt is null)) { string pktString = pkt.ToString(); string verString = Utils.CreateVersionWithNoUndefinedValues(assembly.Version).ToString(); var cultureString = UTF8String.ToSystemStringOrEmpty(assembly.Culture); @@ -655,14 +655,14 @@ IEnumerable FindAssembliesGacAny(IAssembly assembly, ModuleDef sourceMod foreach (var path in FindAssembliesGacAny(gacInfo, assembly, sourceModule)) yield return path; } - if (extraMonoPaths != null) { + if (!(extraMonoPaths is null)) { foreach (var path in GetExtraMonoPaths(assembly, sourceModule)) yield return path; } } IEnumerable FindAssembliesGacAny(GacInfo gacInfo, IAssembly assembly, ModuleDef sourceModule) { - if (gacInfo != null) { + if (!(gacInfo is null)) { var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); foreach (var subDir in gacInfo.SubDirs) { var baseDir = Path.Combine(gacInfo.Path, subDir); @@ -727,7 +727,7 @@ IEnumerable FindAssembliesModuleSearchPaths(IAssembly assembly, ModuleDe /// A list of all search paths to use for this module IEnumerable GetSearchPaths(ModuleDef module) { var keyModule = module; - if (keyModule == null) + if (keyModule is null) keyModule = nullModule; if (moduleSearchPaths.TryGetValue(keyModule, out var searchPaths)) return searchPaths; @@ -750,13 +750,13 @@ IEnumerable GetSearchPaths(ModuleDef module) { /// The module or null if unknown /// A list of search paths protected IEnumerable GetModulePrivateSearchPaths(ModuleDef module) { - if (module == null) + if (module is null) return Array2.Empty(); var asm = module.Assembly; - if (asm == null) + if (asm is null) return Array2.Empty(); module = asm.ManifestModule; - if (module == null) + if (module is null) return Array2.Empty(); // Should never happen string baseDir = null; @@ -771,7 +771,7 @@ protected IEnumerable GetModulePrivateSearchPaths(ModuleDef module) { } catch { } - if (baseDir != null) + if (!(baseDir is null)) return new List { baseDir }; return Array2.Empty(); } @@ -788,7 +788,7 @@ IEnumerable GetPrivatePaths(string baseDir, string configFileName) { doc.Load(XmlReader.Create(xmlStream)); foreach (var tmp in doc.GetElementsByTagName("probing")) { var probingElem = tmp as XmlElement; - if (probingElem == null) + if (probingElem is null) continue; var privatePath = probingElem.GetAttribute("privatePath"); if (string.IsNullOrEmpty(privatePath)) diff --git a/src/DotNet/CallingConventionSig.cs b/src/DotNet/CallingConventionSig.cs index a8d242240..98c182d1e 100644 --- a/src/DotNet/CallingConventionSig.cs +++ b/src/DotNet/CallingConventionSig.cs @@ -571,7 +571,7 @@ public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSi this.genParamCount = genParamCount; this.retType = retType; parameters = new List(argTypes); - this.paramsAfterSentinel = paramsAfterSentinel == null ? null : new List(paramsAfterSentinel); + this.paramsAfterSentinel = paramsAfterSentinel is null ? null : new List(paramsAfterSentinel); } /// @@ -762,7 +762,7 @@ internal PropertySig(CallingConvention callingConvention, uint genParamCount, Ty this.genParamCount = genParamCount; this.retType = retType; parameters = new List(argTypes); - this.paramsAfterSentinel = paramsAfterSentinel == null ? null : new List(paramsAfterSentinel); + this.paramsAfterSentinel = paramsAfterSentinel is null ? null : new List(paramsAfterSentinel); } /// diff --git a/src/DotNet/ClassLayout.cs b/src/DotNet/ClassLayout.cs index b4ff4e177..e11c69832 100644 --- a/src/DotNet/ClassLayout.cs +++ b/src/DotNet/ClassLayout.cs @@ -83,7 +83,7 @@ sealed class ClassLayoutMD : ClassLayout, IMDTokenProviderMD { /// If is invalid public ClassLayoutMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ClassLayoutTable.IsInvalidRID(rid)) throw new BadImageFormatException($"ClassLayout rid {rid} does not exist"); diff --git a/src/DotNet/Constant.cs b/src/DotNet/Constant.cs index 9de02a805..833be0ce7 100644 --- a/src/DotNet/Constant.cs +++ b/src/DotNet/Constant.cs @@ -75,7 +75,7 @@ public ConstantUser(object value, ElementType type) { } static ElementType GetElementType(object value) { - if (value == null) + if (value is null) return ElementType.Class; switch (System.Type.GetTypeCode(value.GetType())) { case TypeCode.Boolean: return ElementType.Boolean; @@ -114,7 +114,7 @@ sealed class ConstantMD : Constant, IMDTokenProviderMD { /// If is invalid public ConstantMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ConstantTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Constant rid {rid} does not exist"); diff --git a/src/DotNet/CorLibTypes.cs b/src/DotNet/CorLibTypes.cs index 60a24ec28..c13bc4aa4 100644 --- a/src/DotNet/CorLibTypes.cs +++ b/src/DotNet/CorLibTypes.cs @@ -131,7 +131,7 @@ ITypeDefOrRef CreateCorLibTypeRef(bool isCorLib, string name) { var tr = new TypeRefUser(module, "System", name, corLibAssemblyRef); if (isCorLib) { var td = module.Find(tr); - if (td != null) + if (!(td is null)) return td; } return module.UpdateRowId(tr); diff --git a/src/DotNet/CustomAttribute.cs b/src/DotNet/CustomAttribute.cs index 8a363f45a..90be4039c 100644 --- a/src/DotNet/CustomAttribute.cs +++ b/src/DotNet/CustomAttribute.cs @@ -37,7 +37,7 @@ public string TypeFullName { if (ctor is MethodDef mdCtor) { var declType = mdCtor.DeclaringType; - if (declType != null) + if (!(declType is null)) return declType.FullName; } @@ -48,7 +48,7 @@ public string TypeFullName { /// /// true if the raw custom attribute blob hasn't been parsed /// - public bool IsRawBlob => rawData != null; + public bool IsRawBlob => !(rawData is null); /// /// Gets the raw custom attribute blob or null if the CA was successfully parsed. @@ -163,8 +163,8 @@ public CustomAttribute(ICustomAttributeType ctor, IEnumerable argume /// Original custom attribute #Blob offset or 0 public CustomAttribute(ICustomAttributeType ctor, IEnumerable arguments, IEnumerable namedArguments, uint caBlobOffset) { this.ctor = ctor; - this.arguments = arguments == null ? new List() : new List(arguments); - this.namedArguments = namedArguments == null ? new List() : new List(namedArguments); + this.arguments = arguments is null ? new List() : new List(arguments); + this.namedArguments = namedArguments is null ? new List() : new List(namedArguments); this.caBlobOffset = caBlobOffset; } diff --git a/src/DotNet/CustomAttributeCollection.cs b/src/DotNet/CustomAttributeCollection.cs index 7d82a299a..214f1443b 100644 --- a/src/DotNet/CustomAttributeCollection.cs +++ b/src/DotNet/CustomAttributeCollection.cs @@ -30,7 +30,7 @@ public CustomAttributeCollection(int length, object context, Func /// Full name of custom attribute type /// true if the custom attribute type is present, false otherwise - public bool IsDefined(string fullName) => Find(fullName) != null; + public bool IsDefined(string fullName) => !(Find(fullName) is null); /// /// Removes all custom attributes of a certain type @@ -50,7 +50,7 @@ public void RemoveAll(string fullName) { /// A or null if it wasn't found public CustomAttribute Find(string fullName) { foreach (var ca in this) { - if (ca != null && ca.TypeFullName == fullName) + if (!(ca is null) && ca.TypeFullName == fullName) return ca; } @@ -64,7 +64,7 @@ public CustomAttribute Find(string fullName) { /// All s of the requested type public IEnumerable FindAll(string fullName) { foreach (var ca in this) { - if (ca != null && ca.TypeFullName == fullName) + if (!(ca is null) && ca.TypeFullName == fullName) yield return ca; } } diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 5a1e8c238..b1bdc3896 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -23,22 +23,22 @@ sealed class CAAssemblyRefFinder : IAssemblyRefFinder { /// public AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { var modAsm = module.Assembly; - if (modAsm != null) { + if (!(modAsm is null)) { var type = modAsm.Find(nonNestedTypeRef); - if (type != null) + if (!(type is null)) return module.UpdateRowId(new AssemblyRefUser(modAsm)); } - else if (module.Find(nonNestedTypeRef) != null) + else if (!(module.Find(nonNestedTypeRef) is null)) return AssemblyRef.CurrentAssembly; var corLibAsm = module.Context.AssemblyResolver.Resolve(module.CorLibTypes.AssemblyRef, module); - if (corLibAsm != null) { + if (!(corLibAsm is null)) { var type = corLibAsm.Find(nonNestedTypeRef); - if (type != null) + if (!(type is null)) return module.CorLibTypes.AssemblyRef; } - if (modAsm != null) + if (!(modAsm is null)) return module.UpdateRowId(new AssemblyRefUser(modAsm)); return AssemblyRef.CurrentAssembly; } @@ -114,7 +114,7 @@ public struct CustomAttributeReader { public static CustomAttribute Read(ModuleDefMD readerModule, ICustomAttributeType ctor, uint offset, GenericParamContext gpContext) { var caReader = new CustomAttributeReader(readerModule, offset, gpContext); try { - if (ctor == null) + if (ctor is null) return caReader.CreateRaw(ctor); return caReader.Read(ctor); } @@ -182,7 +182,7 @@ static CustomAttribute Read(ModuleDef module, ref DataReader reader, ICustomAttr var caReader = new CustomAttributeReader(module, ref reader, gpContext); CustomAttribute ca; try { - if (ctor == null) + if (ctor is null) ca = caReader.CreateRaw(ctor); else ca = caReader.Read(ctor); @@ -244,7 +244,7 @@ internal static List ReadNamedArguments(ModuleDef module, ref D CustomAttribute Read(ICustomAttributeType ctor) { var methodSig = ctor?.MethodSig; - if (methodSig == null) + if (methodSig is null) throw new CABlobParserException("ctor is null or not a method"); if (ctor is MemberRef mrCtor && mrCtor.Class is TypeSpec owner && owner.TypeSig is GenericInstSig gis) { @@ -287,7 +287,7 @@ List ReadNamedArguments(int numNamedArgs) { TypeSig FixTypeSig(TypeSig type) => SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); TypeSig SubstituteGenericParameter(TypeSig type) { - if (genericArguments == null) + if (genericArguments is null) return type; return genericArguments.Resolve(type); } @@ -295,7 +295,7 @@ TypeSig SubstituteGenericParameter(TypeSig type) { CAArgument ReadFixedArg(TypeSig argType) { if (!recursionCounter.Increment()) throw new CABlobParserException("Too much recursion"); - if (argType == null) + if (argType is null) throw new CABlobParserException("null argType"); CAArgument result; @@ -309,10 +309,10 @@ CAArgument ReadFixedArg(TypeSig argType) { } CAArgument ReadElem(TypeSig argType) { - if (argType == null) + if (argType is null) throw new CABlobParserException("null argType"); var value = ReadValue((SerializationType)argType.ElementType, argType, out var realArgType); - if (realArgType == null) + if (realArgType is null) throw new CABlobParserException("Invalid arg type"); // One example when this is true is when prop/field type is object and @@ -396,7 +396,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy // It's ET.ValueType if it's eg. a ctor enum arg type case (SerializationType)ElementType.ValueType: - if (argType == null) + if (argType is null) throw new CABlobParserException("Invalid element type"); realArgType = argType; result = ReadEnumValue(GetEnumUnderlyingType(argType)); @@ -407,7 +407,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy case SerializationType.TaggedObject: realArgType = ReadFieldOrPropType(); var arraySig = realArgType as SZArraySig; - if (arraySig != null) + if (!(arraySig is null)) result = ReadArrayArgument(arraySig); else result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out var tmpType); @@ -416,7 +416,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy // It's ET.Class if it's eg. a ctor System.Type arg type case (SerializationType)ElementType.Class: var tdr = argType as TypeDefOrRefSig; - if (tdr != null && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System") { + if (!(tdr is null) && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System") { if (tdr.TypeName == "Type") { result = ReadValue(SerializationType.Type, tdr, out realArgType); break; @@ -455,7 +455,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy } object ReadEnumValue(TypeSig underlyingType) { - if (underlyingType != null) { + if (!(underlyingType is null)) { if (underlyingType.ElementType < ElementType.Boolean || underlyingType.ElementType > ElementType.U8) throw new CABlobParserException("Invalid enum underlying type"); return ReadValue((SerializationType)underlyingType.ElementType, underlyingType, out var realArgType); @@ -471,11 +471,11 @@ object ReadEnumValue(TypeSig underlyingType) { TypeSig ReadType(bool canReturnNull) { var name = ReadUTF8String(); - if (canReturnNull && (object)name == null) + if (canReturnNull && name is null) return null; var asmRefFinder = new CAAssemblyRefFinder(module); var type = TypeNameParser.ParseAsTypeSigReflection(module, UTF8String.ToSystemStringOrEmpty(name), asmRefFinder, gpContext); - if (type == null) + if (type is null) throw new CABlobParserException("Could not parse type"); return type; } @@ -487,10 +487,10 @@ TypeSig ReadType(bool canReturnNull) { /// The underlying type or null if we couldn't resolve the type ref /// If is not an enum or null static TypeSig GetEnumUnderlyingType(TypeSig type) { - if (type == null) + if (type is null) throw new CABlobParserException("null enum type"); var td = GetTypeDef(type); - if (td == null) + if (td is null) return null; if (!td.IsEnum) throw new CABlobParserException("Not an enum"); @@ -507,11 +507,11 @@ static TypeSig GetEnumUnderlyingType(TypeSig type) { static TypeDef GetTypeDef(TypeSig type) { if (type is TypeDefOrRefSig tdr) { var td = tdr.TypeDef; - if (td != null) + if (!(td is null)) return td; var tr = tdr.TypeRef; - if (tr != null) + if (!(tr is null)) return tr.Resolve(); } diff --git a/src/DotNet/DeclSecurity.cs b/src/DotNet/DeclSecurity.cs index 59d3dd80a..b7724ff6b 100644 --- a/src/DotNet/DeclSecurity.cs +++ b/src/DotNet/DeclSecurity.cs @@ -45,7 +45,7 @@ public SecurityAction Action { /// public IList SecurityAttributes { get { - if (securityAttributes == null) + if (securityAttributes is null) InitializeSecurityAttributes(); return securityAttributes; } @@ -61,7 +61,7 @@ protected virtual void InitializeSecurityAttributes() => /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -86,7 +86,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -115,15 +115,15 @@ protected virtual void InitializeCustomDebugInfos() => public string GetNet1xXmlString() => GetNet1xXmlStringInternal(SecurityAttributes); internal static string GetNet1xXmlStringInternal(IList secAttrs) { - if (secAttrs == null || secAttrs.Count != 1) + if (secAttrs is null || secAttrs.Count != 1) return null; var sa = secAttrs[0]; - if (sa == null || sa.TypeFullName != "System.Security.Permissions.PermissionSetAttribute") + if (sa is null || sa.TypeFullName != "System.Security.Permissions.PermissionSetAttribute") return null; if (sa.NamedArguments.Count != 1) return null; var na = sa.NamedArguments[0]; - if (na == null || !na.IsProperty || na.Name != "XML") + if (na is null || !na.IsProperty || na.Name != "XML") return null; if (na.ArgumentType.GetElementType() != ElementType.String) return null; @@ -131,7 +131,7 @@ internal static string GetNet1xXmlStringInternal(IList secAtt if (arg.Type.GetElementType() != ElementType.String) return null; var utf8 = arg.Value as UTF8String; - if ((object)utf8 != null) + if (!(utf8 is null)) return utf8; if (arg.Value is string s) return s; @@ -207,7 +207,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public DeclSecurityMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.DeclSecurityTable.IsInvalidRID(rid)) throw new BadImageFormatException($"DeclSecurity rid {rid} does not exist"); diff --git a/src/DotNet/DeclSecurityReader.cs b/src/DotNet/DeclSecurityReader.cs index 86f01ed7a..7db8c1713 100644 --- a/src/DotNet/DeclSecurityReader.cs +++ b/src/DotNet/DeclSecurityReader.cs @@ -103,7 +103,7 @@ IList ReadBinaryFormat() { /*int blobLength = (int)*/reader.ReadCompressedUInt32(); int numNamedArgs = (int)reader.ReadCompressedUInt32(); var namedArgs = CustomAttributeReader.ReadNamedArguments(module, ref reader, numNamedArgs, gpContext); - if (namedArgs == null) + if (namedArgs is null) throw new ApplicationException("Could not read named arguments"); list.Add(new SecurityAttribute(attrRef, namedArgs)); } diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index f9389f092..a0bfd7143 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -62,9 +62,9 @@ public ReflectionFieldInfo(string fieldName1, string fieldName2) { } public object Read(object instance) { - if (fieldInfo == null) + if (fieldInfo is null) InitializeField(instance.GetType()); - if (fieldInfo == null) + if (fieldInfo is null) throw new Exception($"Couldn't find field '{fieldName1}' or '{fieldName2}'"); return fieldInfo.GetValue(instance); @@ -72,16 +72,16 @@ public object Read(object instance) { public bool Exists(object instance) { InitializeField(instance.GetType()); - return fieldInfo != null; + return !(fieldInfo is null); } void InitializeField(Type type) { - if (fieldInfo != null) + if (!(fieldInfo is null)) return; var flags = SR.BindingFlags.Instance | SR.BindingFlags.Public | SR.BindingFlags.NonPublic; fieldInfo = type.GetField(fieldName1, flags); - if (fieldInfo == null && fieldName2 != null) + if (fieldInfo is null && !(fieldName2 is null)) fieldInfo = type.GetField(fieldName2, flags); } } @@ -123,25 +123,25 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer) gpContext = importer.gpContext; methodName = null; - if (obj == null) + if (obj is null) throw new ArgumentNullException(nameof(obj)); if (obj is Delegate del) { obj = del.Method; - if (obj == null) - throw new Exception("Delegate.Method == null"); + if (obj is null) + throw new Exception("Delegate.Method is null"); } if (obj.GetType().ToString() == "System.Reflection.Emit.DynamicMethod+RTDynamicMethod") { obj = rtdmOwnerFieldInfo.Read(obj) as DynamicMethod; - if (obj == null) + if (obj is null) throw new Exception("RTDynamicMethod.m_owner is null or invalid"); } if (obj is DynamicMethod) { methodName = ((DynamicMethod)obj).Name; obj = dmResolverFieldInfo.Read(obj); - if (obj == null) + if (obj is null) throw new Exception("No resolver found"); } @@ -149,19 +149,19 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer) throw new Exception("Couldn't find DynamicResolver"); var code = rslvCodeFieldInfo.Read(obj) as byte[]; - if (code == null) + if (code is null) throw new Exception("No code"); codeSize = code.Length; var delMethod = rslvMethodFieldInfo.Read(obj) as SR.MethodBase; - if (delMethod == null) + if (delMethod is null) throw new Exception("No method"); maxStack = (int)rslvMaxStackFieldInfo.Read(obj); var scope = rslvDynamicScopeFieldInfo.Read(obj); - if (scope == null) + if (scope is null) throw new Exception("No scope"); var tokensList = scopeTokensFieldInfo.Read(scope) as System.Collections.IList; - if (tokensList == null) + if (tokensList is null) throw new Exception("No tokens"); tokens = new List(tokensList.Count); for (int i = 0; i < tokensList.Count; i++) @@ -188,7 +188,7 @@ class ExceptionInfo { } static List CreateExceptionInfos(IList ehInfos) { - if (ehInfos == null) + if (ehInfos is null) return new List(); var infos = new List(ehInfos.Count); @@ -213,11 +213,11 @@ static List CreateExceptionInfos(IList ehInfos) { } void UpdateLocals(byte[] localsSig) { - if (localsSig == null || localsSig.Length == 0) + if (localsSig is null || localsSig.Length == 0) return; var sig = SignatureReader.ReadSig(this, module.CorLibTypes, localsSig, gpContext) as LocalSig; - if (sig == null) + if (sig is null) return; var sigLocals = sig.Locals; @@ -271,7 +271,7 @@ public bool Read() { } void CreateExceptionHandlers() { - if (ehHeader != null) { + if (!(ehHeader is null)) { if (ehHeader.Length < 4) return; var reader = new BinaryReader(new MemoryStream(ehHeader)); @@ -328,7 +328,7 @@ void CreateExceptionHandlers() { } } } - else if (ehInfos != null) { + else if (!(ehInfos is null)) { foreach (var ehInfo in CreateExceptionInfos(ehInfos)) { var tryStart = GetInstructionThrow((uint)ehInfo.StartAddr); var tryEnd = GetInstruction((uint)ehInfo.EndAddr); @@ -408,7 +408,7 @@ object ReadToken(uint token) { IMethod ImportMethod(uint rid) { var obj = Resolve(rid); - if (obj == null) + if (obj is null) return null; if (obj is RuntimeMethodHandle) @@ -449,7 +449,7 @@ SR.MethodInfo GetVarArgMethod(object obj) { IField ImportField(uint rid) { var obj = Resolve(rid); - if (obj == null) + if (obj is null) return null; if (obj is RuntimeFieldHandle) @@ -474,7 +474,7 @@ ITypeDefOrRef ImportType(uint rid) { CallingConventionSig ImportSignature(uint rid) { var sig = Resolve(rid) as byte[]; - if (sig == null) + if (sig is null) return null; return SignatureReader.ReadSig(this, module.CorLibTypes, sig, gpContext); diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index 89694f00a..af9a56b7f 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -326,7 +326,7 @@ public int GetSize() { case OperandType.InlineSwitch: var targets = Operand as IList; - return opCode.Size + 4 + (targets == null ? 0 : targets.Count * 4); + return opCode.Size + 4 + (targets is null ? 0 : targets.Count * 4); case OperandType.InlineVar: return opCode.Size + 2; @@ -397,7 +397,7 @@ void CalculateStackUsageCall(Code code, out int pushes, out int pops) { sig = method.MethodSig; else sig = op as MethodSig; // calli instruction - if (sig == null) + if (sig is null) return; bool implicitThis = sig.ImplicitThis; if (!IsSystemVoid(sig.RetType) || (code == Code.Newobj && sig.HasThis)) @@ -405,7 +405,7 @@ void CalculateStackUsageCall(Code code, out int pushes, out int pops) { pops += sig.Params.Count; var paramsAfterSentinel = sig.ParamsAfterSentinel; - if (paramsAfterSentinel != null) + if (!(paramsAfterSentinel is null)) pops += paramsAfterSentinel.Count; if (implicitThis && code != Code.Newobj) pops++; @@ -716,7 +716,7 @@ public int GetParameterIndex() { case Code.Ldarg: case Code.Ldarg_S: var parameter = Operand as Parameter; - if (parameter != null) + if (!(parameter is null)) return parameter.Index; break; } @@ -743,7 +743,7 @@ public Parameter GetParameter(IList parameters) { /// Declaring type (only needed if it's an instance method) /// The type or null if it doesn't exist public TypeSig GetArgumentType(MethodSig methodSig, ITypeDefOrRef declaringType) { - if (methodSig == null) + if (methodSig is null) return null; int index = GetParameterIndex(); if (index == 0 && methodSig.ImplicitThis) diff --git a/src/DotNet/Emit/InstructionPrinter.cs b/src/DotNet/Emit/InstructionPrinter.cs index 6e1a95bfe..290caa3c7 100644 --- a/src/DotNet/Emit/InstructionPrinter.cs +++ b/src/DotNet/Emit/InstructionPrinter.cs @@ -14,7 +14,7 @@ public static class InstructionPrinter { /// The instruction /// The result public static string ToString(Instruction instr) { - if (instr == null) + if (instr is null) return string.Empty; var sb = new StringBuilder(); @@ -67,7 +67,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string sb.Append(extra); if (op is IFullName) sb.Append((op as IFullName).FullName); - else if (op != null) + else if (!(op is null)) sb.Append(op.ToString()); else sb.Append("null"); @@ -93,7 +93,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string case OperandType.InlineSwitch: var targets = op as IList; - if (targets == null) + if (targets is null) sb.Append("null"); else { sb.Append('('); @@ -109,7 +109,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string case OperandType.InlineVar: case OperandType.ShortInlineVar: sb.Append(extra); - if (op == null) + if (op is null) sb.Append("null"); else sb.Append(op.ToString()); @@ -123,14 +123,14 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string } static void AddInstructionTarget(StringBuilder sb, Instruction targetInstr) { - if (targetInstr == null) + if (targetInstr is null) sb.Append("null"); else sb.Append($"IL_{targetInstr.Offset:X4}"); } static void EscapeString(StringBuilder sb, string s, bool addQuotes) { - if (s == null) { + if (s is null) { sb.Append("null"); return; } diff --git a/src/DotNet/Emit/MethodBody.cs b/src/DotNet/Emit/MethodBody.cs index 4ef4e6be7..9bed3b686 100644 --- a/src/DotNet/Emit/MethodBody.cs +++ b/src/DotNet/Emit/MethodBody.cs @@ -150,7 +150,7 @@ public PdbMethod PdbMethod { /// /// true if is not null /// - public bool HasPdbMethod => PdbMethod != null; + public bool HasPdbMethod => !(PdbMethod is null); /// /// Gets the total size of the body in the PE file, including header, IL bytes, and exception handlers. diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index 4198304ea..d11d8cac7 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -102,7 +102,7 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, Data /// /// Method parameters public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters) => - CreateCilBody(opResolver, ByteArrayDataReaderFactory.CreateReader(code), exceptions == null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions), parameters, new GenericParamContext()); + CreateCilBody(opResolver, ByteArrayDataReaderFactory.CreateReader(code), exceptions is null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions), parameters, new GenericParamContext()); /// /// Creates a CIL method body or returns an empty one if is not @@ -115,7 +115,7 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte /// Method parameters /// Generic parameter context public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, GenericParamContext gpContext) => - CreateCilBody(opResolver, ByteArrayDataReaderFactory.CreateReader(code), exceptions == null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions), parameters, gpContext); + CreateCilBody(opResolver, ByteArrayDataReaderFactory.CreateReader(code), exceptions is null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions), parameters, gpContext); /// /// Creates a CIL method body or returns an empty one if doesn't @@ -178,7 +178,7 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte /// Generic parameter context public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok, GenericParamContext gpContext) { var codeReader = ByteArrayDataReaderFactory.CreateReader(code); - var ehReader = exceptions == null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions); + var ehReader = exceptions is null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions); var mbReader = new MethodBodyReader(opResolver, codeReader, ehReader, parameters, gpContext); mbReader.SetHeader(flags, maxStack, codeSize, localVarSigTok); if (!mbReader.Read()) @@ -346,10 +346,10 @@ bool ReadHeader() { /// All locals or null if there are none IList ReadLocals() { var standAloneSig = opResolver.ResolveToken(localVarSigTok, gpContext) as StandAloneSig; - if (standAloneSig == null) + if (standAloneSig is null) return null; var localSig = standAloneSig.LocalSig; - if (localSig == null) + if (localSig is null) return null; return localSig.Locals; } @@ -368,10 +368,10 @@ IList ReadLocals() { /// protected override MethodSig ReadInlineSig(Instruction instr) { var standAloneSig = opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as StandAloneSig; - if (standAloneSig == null) + if (standAloneSig is null) return null; var sig = standAloneSig.MethodSig; - if (sig != null) + if (!(sig is null)) sig.OriginalToken = standAloneSig.MDToken.Raw; return sig; } @@ -395,7 +395,7 @@ void ReadExceptionHandlers(out uint totalBodySize) { } bool canSaveTotalBodySize; DataReader ehReader; - if (exceptionsReader != null) { + if (!(exceptionsReader is null)) { canSaveTotalBodySize = false; ehReader = exceptionsReader.Value; } diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index c535004db..406747130 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -76,7 +76,7 @@ protected MethodBodyReaderBase(DataReader reader, IList parameters) { protected void SetLocals(IList newLocals) { var locals = this.locals; locals.Clear(); - if (newLocals == null) + if (newLocals is null) return; int count = newLocals.Count; for (int i = 0; i < count; i++) @@ -90,7 +90,7 @@ protected void SetLocals(IList newLocals) { protected void SetLocals(IList newLocals) { var locals = this.locals; locals.Clear(); - if (newLocals == null) + if (newLocals is null) return; int count = newLocals.Count; for (int i = 0; i < count; i++) @@ -188,7 +188,7 @@ protected Instruction GetInstruction(uint offset) { /// protected Instruction GetInstructionThrow(uint offset) { var instr = GetInstruction(offset); - if (instr != null) + if (!(instr is null)) return instr; throw new InvalidOperationException($"There's no instruction @ {offset:X4}"); } @@ -489,7 +489,7 @@ protected bool Add(ExceptionHandler eh) { return false; if (eh.HandlerType == ExceptionHandlerType.Filter) { - if (eh.FilterStart == null) + if (eh.FilterStart is null) return false; if (eh.FilterStart.Offset >= handlerStart) return false; @@ -517,7 +517,7 @@ protected bool Add(ExceptionHandler eh) { /// at the end of the method. /// The instruction offset uint GetOffset(Instruction instr) { - if (instr != null) + if (!(instr is null)) return instr.Offset; var instructions = this.instructions; if (instructions.Count == 0) @@ -536,7 +536,7 @@ public virtual void RestoreMethod(MethodDef method) { body.Variables.Clear(); var locals = this.locals; - if (locals != null) { + if (!(locals is null)) { int count = locals.Count; for (int i = 0; i < count; i++) body.Variables.Add(locals[i]); @@ -544,7 +544,7 @@ public virtual void RestoreMethod(MethodDef method) { body.Instructions.Clear(); var instructions = this.instructions; - if (instructions != null) { + if (!(instructions is null)) { int count = instructions.Count; for (int i = 0; i < count; i++) body.Instructions.Add(instructions[i]); @@ -552,7 +552,7 @@ public virtual void RestoreMethod(MethodDef method) { body.ExceptionHandlers.Clear(); var exceptionHandlers = this.exceptionHandlers; - if (exceptionHandlers != null) { + if (!(exceptionHandlers is null)) { int count = exceptionHandlers.Count; for (int i = 0; i < count; i++) body.ExceptionHandlers.Add(exceptionHandlers[i]); diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index b1d3d7f9a..28d8ef5e6 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -26,7 +26,7 @@ static class MethodTableToTypeConverter { static object lockObj = new object(); static MethodTableToTypeConverter() { - if (ptrFieldInfo == null) { + if (ptrFieldInfo is null) { #if NETSTANDARD var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); #else @@ -53,14 +53,14 @@ public static Type Convert(IntPtr address) { } static Type GetTypeUsingTypeBuilder(IntPtr address) { - if (moduleBuilder == null) + if (moduleBuilder is null) return null; var tb = moduleBuilder.DefineType(GetNextTypeName()); var mb = tb.DefineMethod(METHOD_NAME, SR.MethodAttributes.Static, typeof(void), Array2.Empty()); try { - if (setMethodBodyMethodInfo != null) + if (!(setMethodBodyMethodInfo is null)) return GetTypeNET45(tb, mb, address); else return GetTypeNET40(tb, mb, address); @@ -111,7 +111,7 @@ static Type GetTypeNET40(TypeBuilder tb, MethodBuilder mb, IntPtr address) { // .NET 2.0 - 3.5 static Type GetTypeNET20(IntPtr address) { - if (ptrFieldInfo == null) + if (ptrFieldInfo is null) return null; object th = new RuntimeTypeHandle(); ptrFieldInfo.SetValue(th, address); diff --git a/src/DotNet/Emit/MethodUtils.cs b/src/DotNet/Emit/MethodUtils.cs index 5a018ed88..5a2024d30 100644 --- a/src/DotNet/Emit/MethodUtils.cs +++ b/src/DotNet/Emit/MethodUtils.cs @@ -219,7 +219,7 @@ public static void SimplifyMacros(this IList instructions, IList(IList list, int index) { - if (list == null) + if (list is null) return default; if ((uint)index < (uint)list.Count) return list[index]; @@ -241,7 +241,7 @@ public static void OptimizeMacros(this IList instructions) { case Code.Ldarg: case Code.Ldarg_S: arg = instr.Operand as Parameter; - if (arg == null) + if (arg is null) break; if (arg.Index == 0) { instr.OpCode = OpCodes.Ldarg_0; @@ -265,7 +265,7 @@ public static void OptimizeMacros(this IList instructions) { case Code.Ldarga: arg = instr.Operand as Parameter; - if (arg == null) + if (arg is null) break; if (byte.MinValue <= arg.Index && arg.Index <= byte.MaxValue) instr.OpCode = OpCodes.Ldarga_S; @@ -343,7 +343,7 @@ public static void OptimizeMacros(this IList instructions) { case Code.Ldloc: case Code.Ldloc_S: local = instr.Operand as Local; - if (local == null) + if (local is null) break; if (local.Index == 0) { instr.OpCode = OpCodes.Ldloc_0; @@ -367,7 +367,7 @@ public static void OptimizeMacros(this IList instructions) { case Code.Ldloca: local = instr.Operand as Local; - if (local == null) + if (local is null) break; if (byte.MinValue <= local.Index && local.Index <= byte.MaxValue) instr.OpCode = OpCodes.Ldloca_S; @@ -375,7 +375,7 @@ public static void OptimizeMacros(this IList instructions) { case Code.Starg: arg = instr.Operand as Parameter; - if (arg == null) + if (arg is null) break; if (byte.MinValue <= arg.Index && arg.Index <= byte.MaxValue) instr.OpCode = OpCodes.Starg_S; @@ -384,7 +384,7 @@ public static void OptimizeMacros(this IList instructions) { case Code.Stloc: case Code.Stloc_S: local = instr.Operand as Local; - if (local == null) + if (local is null) break; if (local.Index == 0) { instr.OpCode = OpCodes.Stloc_0; @@ -470,7 +470,7 @@ public static void OptimizeBranches(this IList instructions) { default: continue; } var targetInstr = instr.Operand as Instruction; - if (targetInstr == null) + if (targetInstr is null) continue; int afterShortInstr; diff --git a/src/DotNet/Emit/OpCodes.cs b/src/DotNet/Emit/OpCodes.cs index 2c21d7555..e9279617c 100644 --- a/src/DotNet/Emit/OpCodes.cs +++ b/src/DotNet/Emit/OpCodes.cs @@ -251,11 +251,11 @@ static OpCodes() { // The OpCode ctor copies itself to one of these arrays. Whatever are still null // are unsupported opcodes. Set them all to UNKNOWN1 or UNKNOWN2. for (int i = 0; i < OneByteOpCodes.Length; i++) { - if (OneByteOpCodes[i] == null) + if (OneByteOpCodes[i] is null) OneByteOpCodes[i] = UNKNOWN1; } for (int i = 0; i < TwoByteOpCodes.Length; i++) { - if (TwoByteOpCodes[i] == null) + if (TwoByteOpCodes[i] is null) TwoByteOpCodes[i] = UNKNOWN2; } } diff --git a/src/DotNet/EventDef.cs b/src/DotNet/EventDef.cs index f2c0867db..7c1c4c27f 100644 --- a/src/DotNet/EventDef.cs +++ b/src/DotNet/EventDef.cs @@ -72,7 +72,7 @@ public ITypeDefOrRef EventType { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -94,7 +94,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -110,12 +110,12 @@ protected virtual void InitializeCustomDebugInfos() => /// public MethodDef AddMethod { get { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); return addMethod; } set { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); addMethod = value; } @@ -126,12 +126,12 @@ public MethodDef AddMethod { /// public MethodDef InvokeMethod { get { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); return invokeMethod; } set { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); invokeMethod = value; } @@ -142,12 +142,12 @@ public MethodDef InvokeMethod { /// public MethodDef RemoveMethod { get { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); return removeMethod; } set { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); removeMethod = value; } @@ -158,7 +158,7 @@ public MethodDef RemoveMethod { /// public IList OtherMethods { get { - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods(); return otherMethods; } @@ -168,7 +168,7 @@ void InitializeEventMethods() { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (otherMethods == null) + if (otherMethods is null) InitializeEventMethods_NoLock(); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } @@ -199,9 +199,9 @@ protected virtual void InitializeEventMethods_NoLock() => /// public bool IsEmpty => // The first property access initializes the other fields we access here - AddMethod == null && - removeMethod == null && - invokeMethod == null && + AddMethod is null && + removeMethod is null && + invokeMethod is null && otherMethods.Count == 0; /// @@ -221,9 +221,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (currentDeclaringType != null) + if (!(currentDeclaringType is null)) currentDeclaringType.Events.Remove(this); // Will set DeclaringType2 = null - if (value != null) + if (!(value is null)) value.Events.Add(this); // Will set DeclaringType2 = value } } @@ -373,7 +373,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public EventDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.EventTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Event rid {rid} does not exist"); @@ -406,7 +406,7 @@ internal EventDefMD InitializeAll() { protected override void InitializeEventMethods_NoLock() { IList newOtherMethods; var dt = declaringType2 as TypeDefMD; - if (dt == null) + if (dt is null) newOtherMethods = new List(); else dt.InitializeEvent(this, out addMethod, out invokeMethod, out removeMethod, out newOtherMethods); diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 7cb7e3f1b..84d7cff6f 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -46,7 +46,7 @@ public uint Rid { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -71,7 +71,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -86,7 +86,7 @@ protected virtual void InitializeCustomDebugInfos() => public bool IsValueType { get { var td = Resolve(); - return td != null && td.IsValueType; + return !(td is null) && td.IsValueType; } } @@ -231,7 +231,7 @@ void InitializeImplementation() { /// /// true if it's nested within another /// - public bool IsNested => DeclaringType != null; + public bool IsNested => !(DeclaringType is null); /// /// Gets the declaring type, if any @@ -475,7 +475,7 @@ public bool MovedToAnotherAssembly { return et.IsForwarder; et = impl as ExportedType; - if (et == null) + if (et is null) break; } return false; @@ -494,7 +494,7 @@ public bool MovedToAnotherAssembly { /// Source module or null /// A instance or null if it couldn't be resolved public TypeDef Resolve(ModuleDef sourceModule) { - if (module == null) + if (module is null) return null; return Resolve(sourceModule, this); @@ -502,15 +502,15 @@ public TypeDef Resolve(ModuleDef sourceModule) { static TypeDef Resolve(ModuleDef sourceModule, ExportedType et) { for (int i = 0; i < MAX_LOOP_ITERS; i++) { - if (et == null || et.module == null) + if (et is null || et.module is null) break; var resolver = et.module.Context.AssemblyResolver; var etAsm = resolver.Resolve(et.DefinitionAssembly, sourceModule ?? et.module); - if (etAsm == null) + if (etAsm is null) break; var td = etAsm.Find(et.FullName, false); - if (td != null) + if (!(td is null)) return td; et = FindExportedType(etAsm, et); @@ -542,7 +542,7 @@ static ExportedType FindExportedType(AssemblyDef asm, ExportedType et) { /// If the type couldn't be resolved public TypeDef ResolveThrow() { var type = Resolve(); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); } @@ -555,12 +555,12 @@ public TypeRef ToTypeRef() { TypeRef result = null, prev = null; var mod = module; IImplementation impl = this; - for (int i = 0; i < MAX_LOOP_ITERS && impl != null; i++) { + for (int i = 0; i < MAX_LOOP_ITERS && !(impl is null); i++) { if (impl is ExportedType et) { var newTr = mod.UpdateRowId(new TypeRefUser(mod, et.TypeNamespace, et.TypeName)); - if (result == null) + if (result is null) result = newTr; - if (prev != null) + if (!(prev is null)) prev.ResolutionScope = newTr; prev = newTr; @@ -586,12 +586,12 @@ public TypeRef ToTypeRef() { } static ModuleDef FindModule(ModuleDef module, FileDef file) { - if (module == null || file == null) + if (module is null || file is null) return null; if (UTF8String.CaseInsensitiveEquals(module.Name, file.Name)) return module; var asm = module.Assembly; - if (asm == null) + if (asm is null) return null; return asm.FindModule(file.Name); } @@ -670,7 +670,7 @@ protected override IImplementation GetImplementation_NoLock() => /// If is invalid public ExportedTypeMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ExportedTypeTable.IsInvalidRID(rid)) throw new BadImageFormatException($"ExportedType rid {rid} does not exist"); diff --git a/src/DotNet/FieldDef.cs b/src/DotNet/FieldDef.cs index ac1279d98..2bbaf726f 100644 --- a/src/DotNet/FieldDef.cs +++ b/src/DotNet/FieldDef.cs @@ -49,7 +49,7 @@ public uint Rid { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -71,7 +71,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -370,7 +370,7 @@ void InitializeConstant() { public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public bool HasImplMap => ImplMap != null; + public bool HasImplMap => !(ImplMap is null); /// /// Gets/sets the declaring type (owner type) @@ -381,9 +381,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (currentDeclaringType != null) + if (!(currentDeclaringType is null)) currentDeclaringType.Fields.Remove(this); // Will set DeclaringType2 = null - if (value != null) + if (!(value is null)) value.Fields.Add(this); // Will set DeclaringType2 = value } } @@ -431,12 +431,12 @@ public FieldSig FieldSig { /// /// true if is not null /// - public bool HasLayoutInfo => FieldOffset != null; + public bool HasLayoutInfo => !(FieldOffset is null); /// /// true if is not null /// - public bool HasConstant => Constant != null; + public bool HasConstant => !(Constant is null); /// /// Gets the constant element type or if there's no constant @@ -444,14 +444,14 @@ public FieldSig FieldSig { public ElementType ElementType { get { var c = Constant; - return c == null ? ElementType.End : c.Type; + return c is null ? ElementType.End : c.Type; } } /// /// true if is not null /// - public bool HasMarshalType => MarshalType != null; + public bool HasMarshalType => !(MarshalType is null); /// /// Gets/sets the field type @@ -460,7 +460,7 @@ public TypeSig FieldType { get => FieldSig.GetFieldType(); set { var sig = FieldSig; - if (sig != null) + if (!(sig is null)) sig.Type = value; } } @@ -655,7 +655,7 @@ public uint GetFieldSize() { /// true if is valid, false otherwise protected bool GetFieldSize(TypeDef declaringType, FieldSig fieldSig, int ptrSize, out uint size) { size = 0; - if (fieldSig == null) + if (fieldSig is null) return false; return GetClassSize(declaringType, fieldSig.Type, ptrSize, out size); } @@ -663,7 +663,7 @@ protected bool GetFieldSize(TypeDef declaringType, FieldSig fieldSig, int ptrSiz bool GetClassSize(TypeDef declaringType, TypeSig ts, int ptrSize, out uint size) { size = 0; ts = ts.RemovePinnedAndModifiers(); - if (ts == null) + if (ts is null) return false; int size2 = ts.ElementType.GetPrimitiveSize(ptrSize); @@ -673,25 +673,25 @@ bool GetClassSize(TypeDef declaringType, TypeSig ts, int ptrSize, out uint size) } var tdrs = ts as TypeDefOrRefSig; - if (tdrs == null) + if (tdrs is null) return false; var td = tdrs.TypeDef; - if (td != null) + if (!(td is null)) return TypeDef.GetClassSize(td, out size); var tr = tdrs.TypeRef; - if (tr != null) + if (!(tr is null)) return TypeDef.GetClassSize(tr.Resolve(), out size); return false; } int GetPointerSize(TypeDef declaringType) { - if (declaringType == null) + if (declaringType is null) return 4; var module = declaringType.Module; - if (module == null) + if (module is null) return 4; return module.GetPointerSize(); } @@ -808,7 +808,7 @@ protected override Constant GetConstant_NoLock() => /// If is invalid public FieldDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.FieldTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Field rid {rid} does not exist"); diff --git a/src/DotNet/FileDef.cs b/src/DotNet/FileDef.cs index d817ada0d..9f65542b0 100644 --- a/src/DotNet/FileDef.cs +++ b/src/DotNet/FileDef.cs @@ -67,7 +67,7 @@ public byte[] HashValue { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -92,7 +92,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -197,7 +197,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public FileDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.FileTable.IsInvalidRID(rid)) throw new BadImageFormatException($"File rid {rid} does not exist"); diff --git a/src/DotNet/FrameworkRedirect.cs b/src/DotNet/FrameworkRedirect.cs index 69ee0cb83..a361008c7 100644 --- a/src/DotNet/FrameworkRedirect.cs +++ b/src/DotNet/FrameworkRedirect.cs @@ -317,7 +317,7 @@ public static bool TryApplyFrameworkRedirect(IAssembly assembly, ModuleDef sourc TryApplyFrameworkRedirectCore(assembly, sourceModule, out redirectedAssembly); static bool TryApplyFrameworkRedirectCore(IAssembly assembly, ModuleDef sourceModule, out IAssembly redirectedAssembly) { - if (sourceModule != null) { + if (!(sourceModule is null)) { if (sourceModule.IsClr40) return TryApplyFrameworkRedirect(assembly, frmRedir4, out redirectedAssembly); if (sourceModule.IsClr20) diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index 8c8f4102c..6cbd9f698 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -47,7 +47,7 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type) { return td.Module != module; var tr = type as TypeRef; - if (tr == null) + if (tr is null) return true; if (tr.ResolutionScope == AssemblyRef.CurrentAssembly) return false; @@ -55,7 +55,7 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type) { return true; // If it's present in this module, but it's a corlib type, then we will need the // assembly name. - return module.Find(tr) != null; + return !(module.Find(tr) is null); } /// @@ -212,7 +212,7 @@ public static string PropertyFullName(string declaringType, UTF8String name, Cal /// Property full name public static StringBuilder PropertyFullNameSB(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (typeGenArgs != null) { + if (!(typeGenArgs is null)) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } @@ -244,7 +244,7 @@ public static string EventFullName(string declaringType, UTF8String name, ITypeD /// Property full name public static StringBuilder EventFullNameSB(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (typeGenArgs != null) { + if (!(typeGenArgs is null)) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } @@ -276,7 +276,7 @@ public static string FieldFullName(string declaringType, string name, FieldSig f /// Field full name public static StringBuilder FieldFullNameSB(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (typeGenArgs != null) { + if (!(typeGenArgs is null)) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } @@ -312,11 +312,11 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Method full name public static StringBuilder MethodFullNameSB(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (typeGenArgs != null || methodGenArgs != null) + if (!(typeGenArgs is null) || !(methodGenArgs is null)) fnc.genericArguments = new GenericArguments(); - if (typeGenArgs != null) + if (!(typeGenArgs is null)) fnc.genericArguments.PushTypeArgs(typeGenArgs); - if (methodGenArgs != null) + if (!(methodGenArgs is null)) fnc.genericArguments.PushMethodArgs(methodGenArgs); fnc.CreateMethodFullName(declaringType, name, methodSig, gppMethod); return fnc.sb ?? new StringBuilder(); @@ -795,11 +795,11 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameFacto /// The full name public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFullNameFactoryHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, helper, sb); - if (typeGenArgs != null || methodGenArgs != null) + if (!(typeGenArgs is null) || !(methodGenArgs is null)) fnc.genericArguments = new GenericArguments(); - if (typeGenArgs != null) + if (!(typeGenArgs is null)) fnc.genericArguments.PushTypeArgs(typeGenArgs); - if (methodGenArgs != null) + if (!(methodGenArgs is null)) fnc.genericArguments.PushMethodArgs(methodGenArgs); fnc.CreateFullName(typeSig); return fnc.sb ?? new StringBuilder(); @@ -997,7 +997,7 @@ public static ModuleDef OwnerModule(ExportedType exportedType) => } bool MustUseAssemblyName(IType type) { - if (helper == null) + if (helper is null) return true; return helper.MustUseAssemblyName(GetDefinitionType(type)); } @@ -1013,7 +1013,7 @@ IType GetDefinitionType(IType type) { GenericInstSig gis; if (sig is TypeDefOrRefSig tdr) type = GetDefinitionType(tdr.TypeDefOrRef); - else if ((gis = sig as GenericInstSig) != null) + else if (!((gis = sig as GenericInstSig) is null)) type = GetDefinitionType(gis.GenericType); else type = GetDefinitionType(sig.Next); @@ -1068,7 +1068,7 @@ void CreateAssemblyQualifiedName(ITypeDefOrRef typeDefOrRef) { } void CreateAssemblyQualifiedName(TypeRef typeRef) { - if (typeRef == null) { + if (typeRef is null) { sb.Append(NULLVALUE); return; } @@ -1085,7 +1085,7 @@ void CreateAssemblyQualifiedName(TypeRef typeRef) { } void CreateFullName(TypeRef typeRef) { - if (typeRef == null) { + if (typeRef is null) { sb.Append(NULLVALUE); return; } @@ -1107,7 +1107,7 @@ void CreateFullName(TypeRef typeRef) { } void CreateNamespace(TypeRef typeRef) { - if (typeRef == null) { + if (typeRef is null) { sb.Append(NULLVALUE); return; } @@ -1115,7 +1115,7 @@ void CreateNamespace(TypeRef typeRef) { } void CreateName(TypeRef typeRef) { - if (typeRef == null) { + if (typeRef is null) { sb.Append(NULLVALUE); return; } @@ -1123,7 +1123,7 @@ void CreateName(TypeRef typeRef) { } void CreateAssemblyQualifiedName(TypeDef typeDef) { - if (typeDef == null) { + if (typeDef is null) { sb.Append(NULLVALUE); return; } @@ -1140,7 +1140,7 @@ void CreateAssemblyQualifiedName(TypeDef typeDef) { } void CreateFullName(TypeDef typeDef) { - if (typeDef == null) { + if (typeDef is null) { sb.Append(NULLVALUE); return; } @@ -1150,7 +1150,7 @@ void CreateFullName(TypeDef typeDef) { } var declaringTypeDef = typeDef.DeclaringType; - if (declaringTypeDef != null) { + if (!(declaringTypeDef is null)) { CreateFullName(declaringTypeDef); AddNestedTypeSeparator(); } @@ -1163,7 +1163,7 @@ void CreateFullName(TypeDef typeDef) { } void CreateNamespace(TypeDef typeDef) { - if (typeDef == null) { + if (typeDef is null) { sb.Append(NULLVALUE); return; } @@ -1171,7 +1171,7 @@ void CreateNamespace(TypeDef typeDef) { } void CreateName(TypeDef typeDef) { - if (typeDef == null) { + if (typeDef is null) { sb.Append(NULLVALUE); return; } @@ -1179,7 +1179,7 @@ void CreateName(TypeDef typeDef) { } void CreateAssemblyQualifiedName(TypeSpec typeSpec) { - if (typeSpec == null) { + if (typeSpec is null) { sb.Append(NULLVALUE); return; } @@ -1187,7 +1187,7 @@ void CreateAssemblyQualifiedName(TypeSpec typeSpec) { } void CreateFullName(TypeSpec typeSpec) { - if (typeSpec == null) { + if (typeSpec is null) { sb.Append(NULLVALUE); return; } @@ -1195,7 +1195,7 @@ void CreateFullName(TypeSpec typeSpec) { } void CreateNamespace(TypeSpec typeSpec) { - if (typeSpec == null) { + if (typeSpec is null) { sb.Append(NULLVALUE); return; } @@ -1203,7 +1203,7 @@ void CreateNamespace(TypeSpec typeSpec) { } void CreateName(TypeSpec typeSpec) { - if (typeSpec == null) { + if (typeSpec is null) { sb.Append(NULLVALUE); return; } @@ -1212,7 +1212,7 @@ void CreateName(TypeSpec typeSpec) { void CreateAssemblyQualifiedName(TypeSig typeSig) { - if (typeSig == null) { + if (typeSig is null) { sb.Append(NULLVALUE); return; } @@ -1233,7 +1233,7 @@ void CreateAssemblyQualifiedName(TypeSig typeSig) { void CreateName(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAME); TypeSig ReplaceGenericArg(TypeSig typeSig) { - if (genericArguments == null) + if (genericArguments is null) return typeSig; var newTypeSig = genericArguments.Resolve(typeSig); if (newTypeSig != typeSig) @@ -1244,7 +1244,7 @@ TypeSig ReplaceGenericArg(TypeSig typeSig) { const int TYPESIG_NAMESPACE = 1; const int TYPESIG_NAME = 2; void CreateTypeSigName(TypeSig typeSig, int flags) { - if (typeSig == null) { + if (typeSig is null) { sb.Append(NULLVALUE); return; } @@ -1411,7 +1411,7 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { if (mustWriteAssembly) { sb.Append(", "); var asm = GetDefinitionAssembly(genArg); - if (asm == null) + if (asm is null) sb.Append(NULLVALUE); else sb.Append(EscapeAssemblyName(GetAssemblyName(asm))); @@ -1441,7 +1441,7 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { if (createName) { var gs = (GenericSig)typeSig; var gp = gs.GenericParam; - if (gp == null || !AddName(gp.Name)) { + if (gp is null || !AddName(gp.Name)) { sb.Append(gs.IsMethodVar ? "!!" : "!"); sb.Append(gs.Number); } @@ -1472,7 +1472,7 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { } void CreateAssemblyQualifiedName(ExportedType exportedType) { - if (exportedType == null) { + if (exportedType is null) { sb.Append(NULLVALUE); return; } @@ -1489,7 +1489,7 @@ void CreateAssemblyQualifiedName(ExportedType exportedType) { } void CreateFullName(ExportedType exportedType) { - if (exportedType == null) { + if (exportedType is null) { sb.Append(NULLVALUE); return; } @@ -1511,7 +1511,7 @@ void CreateFullName(ExportedType exportedType) { } void CreateNamespace(ExportedType exportedType) { - if (exportedType == null) { + if (exportedType is null) { sb.Append(NULLVALUE); return; } @@ -1519,7 +1519,7 @@ void CreateNamespace(ExportedType exportedType) { } void CreateName(ExportedType exportedType) { - if (exportedType == null) { + if (exportedType is null) { sb.Append(NULLVALUE); return; } @@ -1571,7 +1571,7 @@ bool AddName(UTF8String name) { void AddAssemblyName(IAssembly assembly) { sb.Append(", "); - if (assembly == null) + if (assembly is null) sb.Append(NULLVALUE); else { var pkt = assembly.PublicKeyOrToken; @@ -1656,14 +1656,14 @@ ModuleDef GetOwnerModule(ITypeDefOrRef typeDefOrRef) { } IAssembly GetDefinitionAssembly(TypeRef typeRef) { - if (typeRef == null) + if (typeRef is null) return null; if (!recursionCounter.Increment()) return null; IAssembly result; var scope = typeRef.ResolutionScope; - if (scope == null) + if (scope is null) result = null; //TODO: Check ownerModule's ExportedType table else if (scope is TypeRef) result = GetDefinitionAssembly((TypeRef)scope); @@ -1683,7 +1683,7 @@ IAssembly GetDefinitionAssembly(TypeRef typeRef) { } IScope GetScope(TypeRef typeRef) { - if (typeRef == null) + if (typeRef is null) return null; if (!recursionCounter.Increment()) return null; @@ -1694,15 +1694,15 @@ IScope GetScope(TypeRef typeRef) { ModuleDef modDef; var scope = typeRef.ResolutionScope; - if (scope == null) + if (scope is null) result = null; //TODO: Check ownerModule's ExportedType table - else if ((tr = scope as TypeRef) != null) + else if (!((tr = scope as TypeRef) is null)) result = GetScope(tr); - else if ((asmRef = scope as AssemblyRef) != null) + else if (!((asmRef = scope as AssemblyRef) is null)) result = asmRef; - else if ((modRef = scope as ModuleRef) != null) + else if (!((modRef = scope as ModuleRef) is null)) result = modRef; - else if ((modDef = scope as ModuleDef) != null) + else if (!((modDef = scope as ModuleDef) is null)) result = modDef; else result = null; // Should never be reached @@ -1712,7 +1712,7 @@ IScope GetScope(TypeRef typeRef) { } ModuleDef GetOwnerModule(TypeRef typeRef) { - if (typeRef == null) + if (typeRef is null) return null; return typeRef.Module; } @@ -1720,13 +1720,13 @@ ModuleDef GetOwnerModule(TypeRef typeRef) { IAssembly GetDefinitionAssembly(TypeDef typeDef) => GetOwnerModule(typeDef)?.Assembly; ModuleDef GetOwnerModule(TypeDef typeDef) { - if (typeDef == null) + if (typeDef is null) return null; ModuleDef result = null; for (int i = recursionCounter.Counter; i < RecursionCounter.MAX_RECURSION_COUNT; i++) { var declaringType = typeDef.DeclaringType; - if (declaringType == null) { + if (declaringType is null) { result = typeDef.Module2; break; } @@ -1737,31 +1737,31 @@ ModuleDef GetOwnerModule(TypeDef typeDef) { } IAssembly GetDefinitionAssembly(TypeSpec typeSpec) { - if (typeSpec == null) + if (typeSpec is null) return null; return GetDefinitionAssembly(typeSpec.TypeSig); } IScope GetScope(TypeSpec typeSpec) { - if (typeSpec == null) + if (typeSpec is null) return null; return GetScope(typeSpec.TypeSig); } ITypeDefOrRef GetScopeType(TypeSpec typeSpec) { - if (typeSpec == null) + if (typeSpec is null) return null; return GetScopeType(typeSpec.TypeSig); } ModuleDef GetOwnerModule(TypeSpec typeSpec) { - if (typeSpec == null) + if (typeSpec is null) return null; return GetOwnerModule(typeSpec.TypeSig); } IAssembly GetDefinitionAssembly(TypeSig typeSig) { - if (typeSig == null) + if (typeSig is null) return null; if (!recursionCounter.Increment()) return null; @@ -1830,7 +1830,7 @@ IAssembly GetDefinitionAssembly(TypeSig typeSig) { } ITypeDefOrRef GetScopeType(TypeSig typeSig) { - if (typeSig == null) + if (typeSig is null) return null; if (!recursionCounter.Increment()) return null; @@ -1897,7 +1897,7 @@ ITypeDefOrRef GetScopeType(TypeSig typeSig) { } IScope GetScope(TypeSig typeSig) { - if (typeSig == null) + if (typeSig is null) return null; if (!recursionCounter.Increment()) return null; @@ -1964,7 +1964,7 @@ IScope GetScope(TypeSig typeSig) { } ModuleDef GetOwnerModule(TypeSig typeSig) { - if (typeSig == null) + if (typeSig is null) return null; if (!recursionCounter.Increment()) return null; @@ -2031,7 +2031,7 @@ ModuleDef GetOwnerModule(TypeSig typeSig) { } IAssembly GetDefinitionAssembly(ExportedType exportedType) { - if (exportedType == null) + if (exportedType is null) return null; if (!recursionCounter.Increment()) return null; @@ -2041,7 +2041,7 @@ IAssembly GetDefinitionAssembly(ExportedType exportedType) { var scope = exportedType.Implementation; if (scope is ExportedType et) result = GetDefinitionAssembly(et); - else if ((asmRef = scope as AssemblyRef) != null) + else if (!((asmRef = scope as AssemblyRef) is null)) result = asmRef; else if (scope is FileDef) { var ownerModule = GetOwnerModule(exportedType); @@ -2057,7 +2057,7 @@ IAssembly GetDefinitionAssembly(ExportedType exportedType) { ITypeDefOrRef GetScopeType(ExportedType exportedType) => null; IScope GetScope(ExportedType exportedType) { - if (exportedType == null) + if (exportedType is null) return null; if (!recursionCounter.Increment()) return null; @@ -2068,13 +2068,13 @@ IScope GetScope(ExportedType exportedType) { var scope = exportedType.Implementation; if (scope is ExportedType et) result = GetScope(et); - else if ((asmRef = scope as AssemblyRef) != null) + else if (!((asmRef = scope as AssemblyRef) is null)) result = asmRef; - else if ((file = scope as FileDef) != null) { + else if (!((file = scope as FileDef) is null)) { var ownerModule = GetOwnerModule(exportedType); //TODO: Not all modules' names are equal to the name in FileDef.Name var modRef = new ModuleRefUser(ownerModule, file.Name); - if (ownerModule != null) + if (!(ownerModule is null)) ownerModule.UpdateRowId(modRef); result = modRef; } @@ -2086,7 +2086,7 @@ IScope GetScope(ExportedType exportedType) { } ModuleDef GetOwnerModule(ExportedType exportedType) { - if (exportedType == null) + if (exportedType is null) return null; return exportedType.Module; } @@ -2095,27 +2095,27 @@ void CreateFieldFullName(string declaringType, string name, FieldSig fieldSig) { CreateFullName(fieldSig?.Type); sb.Append(' '); - if (declaringType != null) { + if (!(declaringType is null)) { sb.Append(declaringType); sb.Append("::"); } - if (name != null) + if (!(name is null)) sb.Append(name); } void CreateMethodFullName(string declaringType, string name, MethodBaseSig methodSig, MethodDef gppMethod) { - if (methodSig == null) { + if (methodSig is null) { sb.Append(NULLVALUE); return; } CreateFullName(methodSig.RetType); sb.Append(' '); - if (declaringType != null) { + if (!(declaringType is null)) { sb.Append(declaringType); sb.Append("::"); } - if (name != null) + if (!(name is null)) sb.Append(name); if (methodSig.Generic) { @@ -2137,7 +2137,7 @@ void CreateMethodFullName(string declaringType, string name, MethodBaseSig metho } int PrintMethodArgList(IList args, bool hasPrintedArgs, bool isAfterSentinel) { - if (args == null) + if (args is null) return 0; if (isAfterSentinel) { if (hasPrintedArgs) @@ -2164,7 +2164,7 @@ void CreatePropertyFullName(string declaringType, UTF8String name, CallingConven void CreateEventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef) { CreateFullName(typeDefOrRef); sb.Append(' '); - if (declaringType != null) { + if (!(declaringType is null)) { sb.Append(declaringType); sb.Append("::"); } diff --git a/src/DotNet/GenericArguments.cs b/src/DotNet/GenericArguments.cs index 3df52028d..866b5f766 100644 --- a/src/DotNet/GenericArguments.cs +++ b/src/DotNet/GenericArguments.cs @@ -46,7 +46,7 @@ public TypeSig Resolve(uint number) { return null; var typeSig = args[(int)number]; var gvar = typeSig as GenericSig; - if (gvar == null || gvar.IsTypeVar != isTypeVar) + if (gvar is null || gvar.IsTypeVar != isTypeVar) return typeSig; result = gvar; number = gvar.Number; @@ -95,21 +95,21 @@ sealed class GenericArguments { /// New which is never null unless /// is null public TypeSig Resolve(TypeSig typeSig) { - if (typeSig == null) + if (typeSig is null) return null; var sig = typeSig; if (sig is GenericMVar genericMVar) { var newSig = methodArgsStack.Resolve(genericMVar.Number); - if (newSig == null || newSig == sig) + if (newSig is null || newSig == sig) return sig; return newSig; } if (sig is GenericVar genericVar) { var newSig = typeArgsStack.Resolve(genericVar.Number); - if (newSig == null || newSig == sig) + if (newSig is null || newSig == sig) return sig; return newSig; } diff --git a/src/DotNet/GenericParam.cs b/src/DotNet/GenericParam.cs index 70f040ee2..06ea94e6e 100644 --- a/src/DotNet/GenericParam.cs +++ b/src/DotNet/GenericParam.cs @@ -101,7 +101,7 @@ public ITypeDefOrRef Kind { /// public IList GenericParamConstraints { get { - if (genericParamConstraints == null) + if (genericParamConstraints is null) InitializeGenericParamConstraints(); return genericParamConstraints; } @@ -117,7 +117,7 @@ protected virtual void InitializeGenericParamConstraints() => /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -142,7 +142,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -272,7 +272,7 @@ internal virtual void OnLazyAdd2(int index, ref GenericParamConstraint value) { /// void IListListener.OnAdd(int index, GenericParamConstraint value) { - if (value.Owner != null) + if (!(value.Owner is null)) throw new InvalidOperationException("Generic param constraint is already owned by another generic param. Set Owner to null first."); value.Owner = this; } @@ -390,7 +390,7 @@ static GenericParamContext GetGenericParamContext(ITypeOrMethodDef tmOwner) { /// If is invalid public GenericParamMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.GenericParamTable.IsInvalidRID(rid)) throw new BadImageFormatException($"GenericParam rid {rid} does not exist"); diff --git a/src/DotNet/GenericParamConstraint.cs b/src/DotNet/GenericParamConstraint.cs index dfb787821..9b340cb14 100644 --- a/src/DotNet/GenericParamConstraint.cs +++ b/src/DotNet/GenericParamConstraint.cs @@ -54,7 +54,7 @@ public ITypeDefOrRef Constraint { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -79,7 +79,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -147,7 +147,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public GenericParamConstraintMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.GenericParamConstraintTable.IsInvalidRID(rid)) throw new BadImageFormatException($"GenericParamConstraint rid {rid} does not exist"); diff --git a/src/DotNet/GenericParamContext.cs b/src/DotNet/GenericParamContext.cs index 8ac14394a..07b3304ca 100644 --- a/src/DotNet/GenericParamContext.cs +++ b/src/DotNet/GenericParamContext.cs @@ -18,7 +18,7 @@ public readonly struct GenericParamContext { /// /// true if and are both null /// - public bool IsEmpty => Type == null && Method == null; + public bool IsEmpty => Type is null && Method is null; /// /// Creates a new instance and initializes the @@ -28,7 +28,7 @@ public readonly struct GenericParamContext { /// Method /// A new instance public static GenericParamContext Create(MethodDef method) { - if (method == null) + if (method is null) return new GenericParamContext(); return new GenericParamContext(method.DeclaringType, method); } diff --git a/src/DotNet/IAssemblyResolver.cs b/src/DotNet/IAssemblyResolver.cs index 8758ae452..448287708 100644 --- a/src/DotNet/IAssemblyResolver.cs +++ b/src/DotNet/IAssemblyResolver.cs @@ -27,7 +27,7 @@ public static partial class Extensions { /// An instance owned by the assembly resolver or /// null if the assembly couldn't be found. public static AssemblyDef Resolve(this IAssemblyResolver self, AssemblyName assembly, ModuleDef sourceModule) { - if (assembly == null) + if (assembly is null) return null; return self.Resolve(new AssemblyNameInfo(assembly), sourceModule); } @@ -41,7 +41,7 @@ public static AssemblyDef Resolve(this IAssemblyResolver self, AssemblyName asse /// An instance owned by the assembly resolver or /// null if the assembly couldn't be found. public static AssemblyDef Resolve(this IAssemblyResolver self, string asmFullName, ModuleDef sourceModule) { - if (asmFullName == null) + if (asmFullName is null) return null; return self.Resolve(new AssemblyNameInfo(asmFullName), sourceModule); } @@ -55,10 +55,10 @@ public static AssemblyDef Resolve(this IAssemblyResolver self, string asmFullNam /// An instance owned by the assembly resolver /// If the assembly couldn't be found. public static AssemblyDef ResolveThrow(this IAssemblyResolver self, IAssembly assembly, ModuleDef sourceModule) { - if (assembly == null) + if (assembly is null) return null; var asm = self.Resolve(assembly, sourceModule); - if (asm != null) + if (!(asm is null)) return asm; throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); } @@ -72,10 +72,10 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, IAssembly as /// An instance owned by the assembly resolver /// If the assembly couldn't be found. public static AssemblyDef ResolveThrow(this IAssemblyResolver self, AssemblyName assembly, ModuleDef sourceModule) { - if (assembly == null) + if (assembly is null) return null; var asm = self.Resolve(new AssemblyNameInfo(assembly), sourceModule); - if (asm != null) + if (!(asm is null)) return asm; throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); } @@ -89,10 +89,10 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, AssemblyName /// An instance owned by the assembly resolver /// If the assembly couldn't be found. public static AssemblyDef ResolveThrow(this IAssemblyResolver self, string asmFullName, ModuleDef sourceModule) { - if (asmFullName == null) + if (asmFullName is null) return null; var asm = self.Resolve(new AssemblyNameInfo(asmFullName), sourceModule); - if (asm != null) + if (!(asm is null)) return asm; throw new AssemblyResolveException($"Could not resolve assembly: {asmFullName}"); } diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index 6bca24beb..621ce6fb8 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -163,15 +163,15 @@ public static partial class Extensions { public static bool IsCorLib(this IAssembly asm) { if (asm is AssemblyDef asmDef) { var manifestModule = asmDef.ManifestModule; - if (manifestModule != null) { + if (!(manifestModule is null)) { var isCorModule = manifestModule.IsCoreLibraryModule; - if (isCorModule != null) + if (!(isCorModule is null)) return isCorModule.Value; } } string asmName; - return asm != null && + return !(asm is null) && UTF8String.IsNullOrEmpty(asm.Culture) && ((asmName = UTF8String.ToSystemStringOrEmpty(asm.Name)).Equals("mscorlib", StringComparison.OrdinalIgnoreCase) || asmName.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) || @@ -187,7 +187,7 @@ public static bool IsCorLib(this IAssembly asm) { /// The assembly /// A new instance public static AssemblyRef ToAssemblyRef(this IAssembly asm) { - if (asm == null) + if (asm is null) return null; // Always create a new one, even if it happens to be an AssemblyRef return new AssemblyRefUser(asm.Name, asm.Version, asm.PublicKeyOrToken, asm.Culture) { Attributes = asm.Attributes }; @@ -202,24 +202,24 @@ public static AssemblyRef ToAssemblyRef(this IAssembly asm) { /// A instance or null if /// is invalid public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType = true) { - if (type == null) + if (type is null) return null; var module = type.Module; - if (module != null) { + if (!(module is null)) { var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); - if (corLibType != null) + if (!(corLibType is null)) return corLibType; } var td = type as TypeDef; - if (td != null) + if (!(td is null)) return CreateClassOrValueType(type, checkValueType ? td.IsValueType : false); if (type is TypeRef tr) { if (checkValueType) td = tr.Resolve(); - return CreateClassOrValueType(type, td == null ? false : td.IsValueType); + return CreateClassOrValueType(type, td is null ? false : td.IsValueType); } if (type is TypeSpec ts) @@ -242,7 +242,7 @@ static TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { /// public static TypeDefOrRefSig TryGetTypeDefOrRefSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as TypeDefOrRefSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as TypeDefOrRefSig; } /// @@ -253,7 +253,7 @@ public static TypeDefOrRefSig TryGetTypeDefOrRefSig(this ITypeDefOrRef type) { /// public static ClassOrValueTypeSig TryGetClassOrValueTypeSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ClassOrValueTypeSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ClassOrValueTypeSig; } /// @@ -264,7 +264,7 @@ public static ClassOrValueTypeSig TryGetClassOrValueTypeSig(this ITypeDefOrRef t /// public static ValueTypeSig TryGetValueTypeSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ValueTypeSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ValueTypeSig; } /// @@ -275,7 +275,7 @@ public static ValueTypeSig TryGetValueTypeSig(this ITypeDefOrRef type) { /// public static ClassSig TryGetClassSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ClassSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ClassSig; } /// @@ -286,7 +286,7 @@ public static ClassSig TryGetClassSig(this ITypeDefOrRef type) { /// public static GenericSig TryGetGenericSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericSig; } /// @@ -297,7 +297,7 @@ public static GenericSig TryGetGenericSig(this ITypeDefOrRef type) { /// public static GenericVar TryGetGenericVar(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericVar; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericVar; } /// @@ -308,7 +308,7 @@ public static GenericVar TryGetGenericVar(this ITypeDefOrRef type) { /// public static GenericMVar TryGetGenericMVar(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericMVar; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericMVar; } /// @@ -319,7 +319,7 @@ public static GenericMVar TryGetGenericMVar(this ITypeDefOrRef type) { /// public static GenericInstSig TryGetGenericInstSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig; } /// @@ -330,7 +330,7 @@ public static GenericInstSig TryGetGenericInstSig(this ITypeDefOrRef type) { /// public static PtrSig TryGetPtrSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as PtrSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as PtrSig; } /// @@ -341,7 +341,7 @@ public static PtrSig TryGetPtrSig(this ITypeDefOrRef type) { /// public static ByRefSig TryGetByRefSig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ByRefSig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ByRefSig; } /// @@ -352,7 +352,7 @@ public static ByRefSig TryGetByRefSig(this ITypeDefOrRef type) { /// public static ArraySig TryGetArraySig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ArraySig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ArraySig; } /// @@ -363,7 +363,7 @@ public static ArraySig TryGetArraySig(this ITypeDefOrRef type) { /// public static SZArraySig TryGetSZArraySig(this ITypeDefOrRef type) { var ts = type as TypeSpec; - return ts == null ? null : ts.TypeSig.RemovePinnedAndModifiers() as SZArraySig; + return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as SZArraySig; } /// @@ -394,21 +394,21 @@ public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnReso } var ts = tdr as TypeSpec; - if (ts == null) + if (ts is null) return null; var git = ts.TypeSig.ToGenericInstSig(); - if (git != null) + if (!(git is null)) tdr = git.GenericType?.TypeDefOrRef; else tdr = ts.TypeSig.ToTypeDefOrRefSig()?.TypeDefOrRef; td = tdr as TypeDef; - if (td != null) + if (!(td is null)) return td.BaseType; tr = tdr as TypeRef; - if (tr != null) { + if (!(tr is null)) { td = throwOnResolveFailure ? tr.ResolveThrow() : tr.Resolve(); return td?.BaseType; } @@ -429,16 +429,16 @@ public static TypeDef ResolveTypeDef(this ITypeDefOrRef tdr) { if (tdr is TypeRef tr) return tr.Resolve(); - if (tdr == null) + if (tdr is null) return null; tdr = tdr.ScopeType; td = tdr as TypeDef; - if (td != null) + if (!(td is null)) return td; tr = tdr as TypeRef; - if (tr != null) + if (!(tr is null)) return tr.Resolve(); return null; @@ -457,16 +457,16 @@ public static TypeDef ResolveTypeDefThrow(this ITypeDefOrRef tdr) { if (tdr is TypeRef tr) return tr.ResolveThrow(); - if (tdr == null) + if (tdr is null) throw new TypeResolveException("Can't resolve a null pointer"); tdr = tdr.ScopeType; td = tdr as TypeDef; - if (td != null) + if (!(td is null)) return td; tr = tdr as TypeRef; - if (tr != null) + if (!(tr is null)) return tr.ResolveThrow(); throw new TypeResolveException($"Could not resolve type: {tdr} ({tdr?.DefinitionAssembly})"); @@ -525,11 +525,11 @@ public static MethodDef ResolveMethodDef(this IMethod method) { if (method is MethodSpec ms) { md = ms.Method as MethodDef; - if (md != null) + if (!(md is null)) return md; mr = ms.Method as MemberRef; - if (mr != null) + if (!(mr is null)) return mr.ResolveMethod(); } @@ -553,11 +553,11 @@ public static MethodDef ResolveMethodDefThrow(this IMethod method) { if (method is MethodSpec ms) { md = ms.Method as MethodDef; - if (md != null) + if (!(md is null)) return md; mr = ms.Method as MemberRef; - if (mr != null) + if (!(mr is null)) return mr.ResolveMethodThrow(); } @@ -570,7 +570,7 @@ public static MethodDef ResolveMethodDefThrow(this IMethod method) { /// Member reference /// static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { - if (mr == null) + if (mr is null) return null; var parent = mr.Class; @@ -1015,12 +1015,12 @@ public static partial class Extensions { /// /// The sig public static ITypeDefOrRef ToTypeDefOrRef(this TypeSig sig) { - if (sig == null) + if (sig is null) return null; if (sig is TypeDefOrRefSig tdrSig) return tdrSig.TypeDefOrRef; var module = sig.Module; - if (module == null) + if (module is null) return new TypeSpecUser(sig); return module.UpdateRowId(new TypeSpecUser(sig)); } @@ -1031,7 +1031,7 @@ public static ITypeDefOrRef ToTypeDefOrRef(this TypeSig sig) { /// Type /// internal static bool IsPrimitive(this IType tdr) { - if (tdr == null) + if (tdr is null) return false; if (!tdr.DefinitionAssembly.IsCorLib()) return false; diff --git a/src/DotNet/ICorLibTypes.cs b/src/DotNet/ICorLibTypes.cs index 2eb82350a..13b4b9ec3 100644 --- a/src/DotNet/ICorLibTypes.cs +++ b/src/DotNet/ICorLibTypes.cs @@ -120,14 +120,14 @@ public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, ITypeDefOrR CorLibTypeSig corLibType; if (type is TypeDef td && - td.DeclaringType == null && - (corLibType = self.GetCorLibTypeSig(td.Namespace, td.Name, td.DefinitionAssembly)) != null) { + td.DeclaringType is null && + !((corLibType = self.GetCorLibTypeSig(td.Namespace, td.Name, td.DefinitionAssembly)) is null)) { return corLibType; } if (type is TypeRef tr && !(tr.ResolutionScope is TypeRef) && - (corLibType = self.GetCorLibTypeSig(tr.Namespace, tr.Name, tr.DefinitionAssembly)) != null) { + !((corLibType = self.GetCorLibTypeSig(tr.Namespace, tr.Name, tr.DefinitionAssembly)) is null)) { return corLibType; } @@ -158,7 +158,7 @@ public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, UTF8String public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, string @namespace, string name, IAssembly defAsm) { if (@namespace != "System") return null; - if (defAsm == null || !defAsm.IsCorLib()) + if (defAsm is null || !defAsm.IsCorLib()) return null; switch (name) { case "Void": return self.Void; diff --git a/src/DotNet/ILogger.cs b/src/DotNet/ILogger.cs index 494c2ac29..cce66bbcc 100644 --- a/src/DotNet/ILogger.cs +++ b/src/DotNet/ILogger.cs @@ -410,24 +410,24 @@ public sealed class DummyLogger : ILogger { /// errors. It must have a public constructor that takes a as the only /// argument. public DummyLogger(Type exceptionToThrow) { - if (exceptionToThrow != null) { + if (!(exceptionToThrow is null)) { if (!exceptionToThrow.IsSubclassOf(typeof(Exception))) throw new ArgumentException($"Not a System.Exception sub class: {exceptionToThrow.GetType()}"); ctor = exceptionToThrow.GetConstructor(new Type[] { typeof(string) }); - if (ctor == null) + if (ctor is null) throw new ArgumentException($"Exception type {exceptionToThrow.GetType()} doesn't have a public constructor that takes a string as the only argument"); } } /// public void Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) { - if (loggerEvent == LoggerEvent.Error && ctor != null) + if (loggerEvent == LoggerEvent.Error && !(ctor is null)) throw (Exception)ctor.Invoke(new object[] { string.Format(format, args) }); } /// public bool IgnoresEvent(LoggerEvent loggerEvent) { - if (ctor == null) + if (ctor is null) return true; return loggerEvent != LoggerEvent.Error; } diff --git a/src/DotNet/IResolver.cs b/src/DotNet/IResolver.cs index 70c92bb9e..78ed3419d 100644 --- a/src/DotNet/IResolver.cs +++ b/src/DotNet/IResolver.cs @@ -61,7 +61,7 @@ public static partial class Extensions { /// If the type couldn't be resolved public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef, ModuleDef sourceModule) { var type = self.Resolve(typeRef, sourceModule); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not resolve type: {typeRef} ({typeRef?.DefinitionAssembly})"); } @@ -75,7 +75,7 @@ public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef, Mod /// If the method/field couldn't be resolved public static IMemberForwarded ResolveThrow(this IMemberRefResolver self, MemberRef memberRef) { var memberDef = self.Resolve(memberRef); - if (memberDef != null) + if (!(memberDef is null)) return memberDef; throw new MemberRefResolveException($"Could not resolve method/field: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); } diff --git a/src/DotNet/IType.cs b/src/DotNet/IType.cs index 520d79251..5f81b50a3 100644 --- a/src/DotNet/IType.cs +++ b/src/DotNet/IType.cs @@ -89,15 +89,15 @@ public static partial class Extensions { /// this /// The scope type public static ITypeDefOrRef GetNonNestedTypeRefScope(this IType type) { - if (type == null) + if (type is null) return null; var scopeType = type.ScopeType; var tr = scopeType as TypeRef; - if (tr == null) + if (tr is null) return scopeType; for (int i = 0; i < 100; i++) { var dt = tr.ResolutionScope as TypeRef; - if (dt == null) + if (dt is null) return tr; tr = dt; } diff --git a/src/DotNet/ITypeDefFinder.cs b/src/DotNet/ITypeDefFinder.cs index 2f4ba4836..3efa6956a 100644 --- a/src/DotNet/ITypeDefFinder.cs +++ b/src/DotNet/ITypeDefFinder.cs @@ -35,7 +35,7 @@ public static partial class Extensions { /// If type couldn't be found public static TypeDef FindThrow(this ITypeDefFinder self, TypeRef typeRef) { var type = self.Find(typeRef); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not find type: {typeRef}"); } @@ -52,7 +52,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, TypeRef typeRef) { /// If type couldn't be found public static TypeDef FindThrow(this ITypeDefFinder self, string fullName, bool isReflectionName) { var type = self.Find(fullName, isReflectionName); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not find type: {fullName}"); } @@ -74,7 +74,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, string fullName, bool /// If type couldn't be found public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) { var type = self.Find(fullName, false); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not find type: {fullName}"); } @@ -96,7 +96,7 @@ public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) /// If type couldn't be found public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullName) { var type = self.Find(fullName, true); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not find type: {fullName}"); } @@ -108,7 +108,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// The type ref /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) => self.Find(typeRef) != null; + public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) => !(self.Find(typeRef) is null); /// /// Checks whether a exists @@ -119,7 +119,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// type names are separated by a + character. If false, nested type names /// are separated by a / character. /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, string fullName, bool isReflectionName) => self.Find(fullName, isReflectionName) != null; + public static bool TypeExists(this ITypeDefFinder self, string fullName, bool isReflectionName) => !(self.Find(fullName, isReflectionName) is null); /// /// Checks whether a exists @@ -127,7 +127,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// Full name of the type (no assembly information). Nested types are separated by / /// true if the exists, false otherwise - public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) => self.Find(fullName, false) != null; + public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) => !(self.Find(fullName, false) is null); /// /// Checks whether a exists @@ -135,6 +135,6 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// Full name of the type (no assembly information). Nested types are separated by + /// true if the exists, false otherwise - public static bool TypeExistsReflection(this ITypeDefFinder self, string fullName) => self.Find(fullName, true) != null; + public static bool TypeExistsReflection(this ITypeDefFinder self, string fullName) => !(self.Find(fullName, true) is null); } } diff --git a/src/DotNet/ImplMap.cs b/src/DotNet/ImplMap.cs index 3d3748e0d..215f5c830 100644 --- a/src/DotNet/ImplMap.cs +++ b/src/DotNet/ImplMap.cs @@ -209,7 +209,7 @@ public bool IsPinvokeMethod(string dllName, string funcName) { if (name != funcName) return false; var mod = module; - if (mod == null) + if (mod is null) return false; return GetDllName(dllName).Equals(GetDllName(mod.Name), StringComparison.OrdinalIgnoreCase); } @@ -262,7 +262,7 @@ sealed class ImplMapMD : ImplMap, IMDTokenProviderMD { /// If is invalid public ImplMapMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ImplMapTable.IsInvalidRID(rid)) throw new BadImageFormatException($"ImplMap rid {rid} does not exist"); diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 8dadb62b3..0e031a0cd 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -185,7 +185,7 @@ public ITypeDefOrRef Import(Type type, IList requiredModifiers, IList ImportAsTypeSig(type, false); TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { - if (type == null) + if (type is null) return null; switch (treatAsGenericInst ? ElementType.GenericInst : type.GetElementType2()) { case ElementType.Void: return module.CorLibTypes.Void; @@ -244,28 +244,28 @@ TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { } ITypeDefOrRef TryResolve(TypeRef tr) { - if (!TryToUseTypeDefs || tr == null) + if (!TryToUseTypeDefs || tr is null) return tr; if (!IsThisModule(tr)) return tr; var td = tr.Resolve(); - if (td == null || td.Module != module) + if (td is null || td.Module != module) return tr; return td; } IMethodDefOrRef TryResolveMethod(IMethodDefOrRef mdr) { - if (!TryToUseMethodDefs || mdr == null) + if (!TryToUseMethodDefs || mdr is null) return mdr; var mr = mdr as MemberRef; - if (mr == null) + if (mr is null) return mdr; if (!mr.IsMethodRef) return mr; var declType = GetDeclaringType(mr); - if (declType == null) + if (declType is null) return mr; if (declType.Module != module) return mr; @@ -273,14 +273,14 @@ IMethodDefOrRef TryResolveMethod(IMethodDefOrRef mdr) { } IField TryResolveField(MemberRef mr) { - if (!TryToUseFieldDefs || mr == null) + if (!TryToUseFieldDefs || mr is null) return mr; if (!mr.IsFieldRef) return mr; var declType = GetDeclaringType(mr); - if (declType == null) + if (declType is null) return mr; if (declType.Module != module) return mr; @@ -288,14 +288,14 @@ IField TryResolveField(MemberRef mr) { } TypeDef GetDeclaringType(MemberRef mr) { - if (mr == null) + if (mr is null) return null; if (mr.Class is TypeDef td) return td; td = TryResolve(mr.Class as TypeRef) as TypeDef; - if (td != null) + if (!(td is null)) return td; var modRef = mr.Class as ModuleRef; @@ -306,10 +306,10 @@ TypeDef GetDeclaringType(MemberRef mr) { } bool IsThisModule(TypeRef tr) { - if (tr == null) + if (tr is null) return false; var scopeType = tr.ScopeType.GetNonNestedTypeRefScope() as TypeRef; - if (scopeType == null) + if (scopeType is null) return false; if (module == scopeType.ResolutionScope) @@ -323,14 +323,14 @@ bool IsThisModule(TypeRef tr) { } bool IsThisModule(ModuleRef modRef) => - modRef != null && + !(modRef is null) && module.Name == modRef.Name && Equals(module.Assembly, modRef.DefinitionAssembly); static bool Equals(IAssembly a, IAssembly b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; return Utils.Equals(a.Version, b.Version) && PublicKeyBase.TokenEquals(a.PublicKeyOrToken, b.PublicKeyOrToken) && @@ -347,11 +347,11 @@ TypeRef CreateTypeRef2(Type type) { } IResolutionScope CreateScopeReference(Type type) { - if (type == null) + if (type is null) return null; var asmName = type.Assembly.GetName(); var modAsm = module.Assembly; - if (modAsm != null) { + if (!(modAsm is null)) { if (UTF8String.ToSystemStringOrEmpty(modAsm.Name).Equals(asmName.Name, StringComparison.OrdinalIgnoreCase)) { if (UTF8String.ToSystemStringOrEmpty(module.Name).Equals(type.Module.ScopeName, StringComparison.OrdinalIgnoreCase)) return module; @@ -359,7 +359,7 @@ IResolutionScope CreateScopeReference(Type type) { } } var pkt = asmName.GetPublicKeyToken(); - if (pkt == null || pkt.Length == 0) + if (pkt is null || pkt.Length == 0) pkt = null; return module.UpdateRowId(new AssemblyRefUser(asmName.Name, asmName.Version, PublicKeyBase.CreatePublicKeyToken(pkt), asmName.CultureInfo.Name)); } @@ -375,7 +375,7 @@ public TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList requiredModifiers, IList optionalModifiers, bool treatAsGenericInst) { - if (type == null) + if (type is null) return null; if (IsEmpty(requiredModifiers) && IsEmpty(optionalModifiers)) return ImportAsTypeSig(type, treatAsGenericInst); @@ -387,12 +387,12 @@ TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList op // Assume all required modifiers are closer to the real type. // Assume all modifiers should be applied in the same order as in the lists. - if (requiredModifiers != null) { + if (!(requiredModifiers is null)) { foreach (var modifier in requiredModifiers) ts = new CModReqdSig(Import(modifier), ts); } - if (optionalModifiers != null) { + if (!(optionalModifiers is null)) { foreach (var modifier in optionalModifiers) ts = new CModOptSig(Import(modifier), ts); } @@ -400,7 +400,7 @@ TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList op return ts; } - static bool IsEmpty(IList list) => list == null || list.Count == 0; + static bool IsEmpty(IList list) => list is null || list.Count == 0; /// /// Imports a as a . This will be either @@ -428,7 +428,7 @@ public IMethod Import(MethodBase methodBase, bool forceFixSignature) { IMethod ImportInternal(MethodBase methodBase) => ImportInternal(methodBase, false); IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { - if (methodBase == null) + if (methodBase is null) return null; if (forceFixSignature) { @@ -455,13 +455,13 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { } else { IMemberRefParent parent; - if (methodBase.DeclaringType == null) { + if (methodBase.DeclaringType is null) { // It's the global type. We can reference it with a ModuleRef token. parent = GetModuleParent(methodBase.Module); } else parent = Import(methodBase.DeclaringType); - if (parent == null) + if (parent is null) return null; MethodBase origMethod; @@ -548,7 +548,7 @@ GenericInstMethodSig CreateGenericInstMethodSig(MethodBase mb) { IMemberRefParent GetModuleParent(Module module2) { // If we have no assembly, assume this is a netmodule in the same assembly as module var modAsm = module.Assembly; - bool isSameAssembly = modAsm == null || + bool isSameAssembly = modAsm is null || UTF8String.ToSystemStringOrEmpty(modAsm.Name).Equals(module2.Assembly.GetName().Name, StringComparison.OrdinalIgnoreCase); if (!isSameAssembly) return null; @@ -573,7 +573,7 @@ IMemberRefParent GetModuleParent(Module module2) { /// or if we failed to import the field public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { FixSignature = false; - if (fieldInfo == null) + if (fieldInfo is null) return null; if (forceFixSignature) { @@ -581,13 +581,13 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { } IMemberRefParent parent; - if (fieldInfo.DeclaringType == null) { + if (fieldInfo.DeclaringType is null) { // It's the global type. We can reference it with a ModuleRef token. parent = GetModuleParent(fieldInfo.Module); } else parent = Import(fieldInfo.DeclaringType); - if (parent == null) + if (parent is null) return null; FieldInfo origField; @@ -604,13 +604,13 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { if (origField.FieldType.ContainsGenericParameters) { var origDeclType = origField.DeclaringType; var asm = module.Context.AssemblyResolver.Resolve(origDeclType.Module.Assembly.GetName(), module); - if (asm == null || asm.FullName != origDeclType.Assembly.FullName) + if (asm is null || asm.FullName != origDeclType.Assembly.FullName) throw new Exception("Couldn't resolve the correct assembly"); var mod = asm.FindModule(origDeclType.Module.ScopeName) as ModuleDefMD; - if (mod == null) + if (mod is null) throw new Exception("Couldn't resolve the correct module"); var fieldDef = mod.ResolveField((uint)(origField.MetadataToken & 0x00FFFFFF)); - if (fieldDef == null) + if (fieldDef is null) throw new Exception("Couldn't resolve the correct field"); var fieldSig = new FieldSig(Import(fieldDef.FieldSig.GetFieldType())); @@ -633,7 +633,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { /// The type /// The imported type or null public IType Import(IType type) { - if (type == null) + if (type is null) return null; if (!recursionCounter.Increment()) return null; @@ -644,13 +644,13 @@ public IType Import(IType type) { TypeSpec ts; TypeSig sig; - if ((td = type as TypeDef) != null) + if (!((td = type as TypeDef) is null)) result = Import(td); - else if ((tr = type as TypeRef) != null) + else if (!((tr = type as TypeRef) is null)) result = Import(tr); - else if ((ts = type as TypeSpec) != null) + else if (!((ts = type as TypeSpec) is null)) result = Import(ts); - else if ((sig = type as TypeSig) != null) + else if (!((sig = type as TypeSig) is null)) result = Import(sig); else result = null; @@ -665,25 +665,25 @@ public IType Import(IType type) { /// The type /// The imported type or null public ITypeDefOrRef Import(TypeDef type) { - if (type == null) + if (type is null) return null; if (TryToUseTypeDefs && type.Module == module) return type; var mapped = mapper?.Map(type); - if (mapped != null) + if (!(mapped is null)) return mapped; return Import2(type); } TypeRef Import2(TypeDef type) { - if (type == null) + if (type is null) return null; if (!recursionCounter.Increment()) return null; TypeRef result; var declType = type.DeclaringType; - if (declType != null) + if (!(declType is null)) result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, Import2(declType))); else result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, CreateScopeReference(type.DefinitionAssembly, type.Module))); @@ -693,10 +693,10 @@ TypeRef Import2(TypeDef type) { } IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { - if (defAsm == null) + if (defAsm is null) return null; var modAsm = module.Assembly; - if (defMod != null && defAsm != null && modAsm != null) { + if (!(defMod is null) && !(defAsm is null) && !(modAsm is null)) { if (UTF8String.CaseInsensitiveEquals(modAsm.Name, defAsm.Name)) { if (UTF8String.CaseInsensitiveEquals(module.Name, defMod.Name)) return module; @@ -716,21 +716,21 @@ IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { /// The imported type or null public ITypeDefOrRef Import(TypeRef type) { var mapped = mapper?.Map(type); - if (mapped != null) + if (!(mapped is null)) return mapped; return TryResolve(Import2(type)); } TypeRef Import2(TypeRef type) { - if (type == null) + if (type is null) return null; if (!recursionCounter.Increment()) return null; TypeRef result; var declaringType = type.DeclaringType; - if (declaringType != null) + if (!(declaringType is null)) result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, Import2(declaringType))); else result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, CreateScopeReference(type.DefinitionAssembly, type.Module))); @@ -745,7 +745,7 @@ TypeRef Import2(TypeRef type) { /// The type /// The imported type or null public TypeSpec Import(TypeSpec type) { - if (type == null) + if (type is null) return null; return module.UpdateRowId(new TypeSpecUser(Import(type.TypeSig))); } @@ -756,7 +756,7 @@ public TypeSpec Import(TypeSpec type) { /// The type /// The imported type or null public TypeSig Import(TypeSig type) { - if (type == null) + if (type is null) return null; if (!recursionCounter.Increment()) return null; @@ -832,7 +832,7 @@ public TypeSig Import(TypeSig type) { TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); - if (corLibType != null) + if (!(corLibType is null)) return corLibType; if (isValueType) @@ -846,7 +846,7 @@ TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { /// The sig /// The imported sig or null if input is invalid public CallingConventionSig Import(CallingConventionSig sig) { - if (sig == null) + if (sig is null) return null; if (!recursionCounter.Increment()) return null; @@ -876,7 +876,7 @@ public CallingConventionSig Import(CallingConventionSig sig) { /// The sig /// The imported sig or null if input is invalid public FieldSig Import(FieldSig sig) { - if (sig == null) + if (sig is null) return null; if (!recursionCounter.Increment()) return null; @@ -893,7 +893,7 @@ public FieldSig Import(FieldSig sig) { /// The sig /// The imported sig or null if input is invalid public MethodSig Import(MethodSig sig) { - if (sig == null) + if (sig is null) return null; if (!recursionCounter.Increment()) return null; @@ -910,7 +910,7 @@ T Import(T sig, T old) where T : MethodBaseSig { sig.Params.Add(Import(p)); sig.GenParamCount = old.GenParamCount; var paramsAfterSentinel = sig.ParamsAfterSentinel; - if (paramsAfterSentinel != null) { + if (!(paramsAfterSentinel is null)) { foreach (var p in old.ParamsAfterSentinel) paramsAfterSentinel.Add(Import(p)); } @@ -923,7 +923,7 @@ T Import(T sig, T old) where T : MethodBaseSig { /// The sig /// The imported sig or null if input is invalid public PropertySig Import(PropertySig sig) { - if (sig == null) + if (sig is null) return null; if (!recursionCounter.Increment()) return null; @@ -940,7 +940,7 @@ public PropertySig Import(PropertySig sig) { /// The sig /// The imported sig or null if input is invalid public LocalSig Import(LocalSig sig) { - if (sig == null) + if (sig is null) return null; if (!recursionCounter.Increment()) return null; @@ -959,7 +959,7 @@ public LocalSig Import(LocalSig sig) { /// The sig /// The imported sig or null if input is invalid public GenericInstMethodSig Import(GenericInstMethodSig sig) { - if (sig == null) + if (sig is null) return null; if (!recursionCounter.Increment()) return null; @@ -978,7 +978,7 @@ public GenericInstMethodSig Import(GenericInstMethodSig sig) { /// The field /// The imported type or null if is invalid public IField Import(IField field) { - if (field == null) + if (field is null) return null; if (!recursionCounter.Increment()) return null; @@ -987,9 +987,9 @@ public IField Import(IField field) { MemberRef mr; FieldDef fd; - if ((fd = field as FieldDef) != null) + if (!((fd = field as FieldDef) is null)) result = Import(fd); - else if ((mr = field as MemberRef) != null) + else if (!((mr = field as MemberRef) is null)) result = Import(mr); else result = null; @@ -1004,7 +1004,7 @@ public IField Import(IField field) { /// The method /// The imported method or null if is invalid public IMethod Import(IMethod method) { - if (method == null) + if (method is null) return null; if (!recursionCounter.Increment()) return null; @@ -1014,11 +1014,11 @@ public IMethod Import(IMethod method) { MethodSpec ms; MemberRef mr; - if ((md = method as MethodDef) != null) + if (!((md = method as MethodDef) is null)) result = Import(md); - else if ((ms = method as MethodSpec) != null) + else if (!((ms = method as MethodSpec) is null)) result = Import(ms); - else if ((mr = method as MemberRef) != null) + else if (!((mr = method as MemberRef) is null)) result = Import(mr); else result = null; @@ -1033,14 +1033,14 @@ public IMethod Import(IMethod method) { /// The field /// The imported type or null if is invalid public IField Import(FieldDef field) { - if (field == null) + if (field is null) return null; if (TryToUseFieldDefs && field.Module == module) return field; if (!recursionCounter.Increment()) return null; var mapped = mapper?.Map(field); - if (mapped != null) { + if (!(mapped is null)) { recursionCounter.Decrement(); return mapped; } @@ -1054,7 +1054,7 @@ public IField Import(FieldDef field) { } IMemberRefParent ImportParent(TypeDef type) { - if (type == null) + if (type is null) return null; if (type.IsGlobalModuleType) return module.UpdateRowId(new ModuleRefUser(module, type.Module?.Name)); @@ -1067,14 +1067,14 @@ IMemberRefParent ImportParent(TypeDef type) { /// The method /// The imported method or null if is invalid public IMethod Import(MethodDef method) { - if (method == null) + if (method is null) return null; if (TryToUseMethodDefs && method.Module == module) return method; if (!recursionCounter.Increment()) return null; var mapped = mapper?.Map(method); - if (mapped != null) { + if (!(mapped is null)) { recursionCounter.Decrement(); return mapped; } @@ -1093,7 +1093,7 @@ public IMethod Import(MethodDef method) { /// The method /// The imported method or null if is invalid public MethodSpec Import(MethodSpec method) { - if (method == null) + if (method is null) return null; if (!recursionCounter.Increment()) return null; @@ -1111,12 +1111,12 @@ public MethodSpec Import(MethodSpec method) { /// The member ref /// The imported member ref or null if is invalid public MemberRef Import(MemberRef memberRef) { - if (memberRef == null) + if (memberRef is null) return null; if (!recursionCounter.Increment()) return null; var mapped = mapper?.Map(memberRef); - if (mapped != null) { + if (!(mapped is null)) { recursionCounter.Decrement(); return mapped; } @@ -1124,7 +1124,7 @@ public MemberRef Import(MemberRef memberRef) { MemberRef result = module.UpdateRowId(new MemberRefUser(module, memberRef.Name)); result.Signature = Import(memberRef.Signature); result.Class = Import(memberRef.Class); - if (result.Class == null) // Will be null if memberRef.Class is null or a MethodDef + if (result.Class is null) // Will be null if memberRef.Class is null or a MethodDef result = null; recursionCounter.Decrement(); @@ -1143,7 +1143,7 @@ IMemberRefParent Import(IMemberRefParent parent) { if (parent is MethodDef method) { var dt = method.DeclaringType; - return dt == null || dt.Module != module ? null : method; + return dt is null || dt.Module != module ? null : method; } return null; diff --git a/src/DotNet/InterfaceImpl.cs b/src/DotNet/InterfaceImpl.cs index ca7699b7a..3ab5af660 100644 --- a/src/DotNet/InterfaceImpl.cs +++ b/src/DotNet/InterfaceImpl.cs @@ -45,7 +45,7 @@ public ITypeDefOrRef Interface { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -70,7 +70,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -138,7 +138,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public InterfaceImplMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.InterfaceImplTable.IsInvalidRID(rid)) throw new BadImageFormatException($"InterfaceImpl rid {rid} does not exist"); diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index d06a91830..f0b87eda1 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -32,7 +32,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui var sh = mdHeader.StreamHeaders[i]; switch (sh.Name) { case "#Strings": - if (stringsStream == null) { + if (stringsStream is null) { stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(stringsStream); continue; @@ -40,7 +40,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#US": - if (usStream == null) { + if (usStream is null) { usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(usStream); continue; @@ -48,7 +48,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#Blob": - if (blobStream == null) { + if (blobStream is null) { blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(blobStream); continue; @@ -56,7 +56,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#GUID": - if (guidStream == null) { + if (guidStream is null) { guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(guidStream); continue; @@ -64,7 +64,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#~": - if (tablesStream == null) { + if (tablesStream is null) { tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(tablesStream); continue; @@ -72,7 +72,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#Pdb": - if (isStandalonePortablePdb && pdbStream == null) { + if (isStandalonePortablePdb && pdbStream is null) { pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(pdbStream); continue; @@ -90,10 +90,10 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui allStreams = newAllStreams; } - if (tablesStream == null) + if (tablesStream is null) throw new BadImageFormatException("Missing MD stream"); - if (pdbStream != null) + if (!(pdbStream is null)) tablesStream.Initialize(pdbStream.TypeSystemTableRows); else tablesStream.Initialize(null); diff --git a/src/DotNet/MD/DotNetStream.cs b/src/DotNet/MD/DotNetStream.cs index 3ca79224f..f43a36d80 100644 --- a/src/DotNet/MD/DotNetStream.cs +++ b/src/DotNet/MD/DotNetStream.cs @@ -44,7 +44,7 @@ public abstract class DotNetStream : IFileSection, IDisposable { /// /// Gets the name of the stream /// - public string Name => streamHeader == null ? string.Empty : streamHeader.Name; + public string Name => streamHeader is null ? string.Empty : streamHeader.Name; /// /// Gets a data reader that can read the full stream @@ -78,7 +78,7 @@ protected DotNetStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffse void DataReaderFactory_DataReaderInvalidated(object sender, EventArgs e) => RecreateReader(mdReaderFactory, metadataBaseOffset, streamHeader, notifyThisClass: true); void RecreateReader(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader, bool notifyThisClass) { - if (mdReaderFactory == null || streamHeader == null) + if (mdReaderFactory is null || streamHeader is null) dataReader = default; else dataReader = mdReaderFactory.CreateReader(metadataBaseOffset + streamHeader.Offset, streamHeader.StreamSize); @@ -104,7 +104,7 @@ public void Dispose() { protected virtual void Dispose(bool disposing) { if (disposing) { var mdReaderFactory = this.mdReaderFactory; - if (mdReaderFactory != null) + if (!(mdReaderFactory is null)) mdReaderFactory.DataReaderInvalidated -= DataReaderFactory_DataReaderInvalidated; streamHeader = null; this.mdReaderFactory = null; diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index b3ec15bf4..736faee96 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -39,7 +39,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui foreach (var sh in mdHeader.StreamHeaders) { switch (sh.Name.ToUpperInvariant()) { case "#STRINGS": - if (stringsStream == null) { + if (stringsStream is null) { stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(stringsStream); continue; @@ -47,7 +47,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#US": - if (usStream == null) { + if (usStream is null) { usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(usStream); continue; @@ -55,7 +55,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#BLOB": - if (blobStream == null) { + if (blobStream is null) { blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(blobStream); continue; @@ -63,7 +63,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui break; case "#GUID": - if (guidStream == null) { + if (guidStream is null) { guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(guidStream); continue; @@ -72,7 +72,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui case "#~": // Only if #Schema is used case "#-": - if (tablesStream == null) { + if (tablesStream is null) { tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(tablesStream); continue; @@ -82,7 +82,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui case "#PDB": // Case sensitive comparison since it's a stream that's not read by the CLR, // only by other libraries eg. System.Reflection.Metadata. - if (isStandalonePortablePdb && pdbStream == null && sh.Name == "#Pdb") { + if (isStandalonePortablePdb && pdbStream is null && sh.Name == "#Pdb") { pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(pdbStream); continue; @@ -98,10 +98,10 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui dns?.Dispose(); } - if (tablesStream == null) + if (tablesStream is null) throw new BadImageFormatException("Missing MD stream"); - if (pdbStream != null) + if (!(pdbStream is null)) tablesStream.Initialize(pdbStream.TypeSystemTableRows); else tablesStream.Initialize(null); @@ -388,7 +388,7 @@ protected override uint BinarySearch(MDTable tableSource, int keyColIndex, uint /// Key /// The rid of the found row, or 0 if none found uint LinearSearch(MDTable tableSource, int keyColIndex, uint key) { - if (tableSource == null) + if (tableSource is null) return 0; var keyColumn = tableSource.TableInfo.Columns[keyColIndex]; for (uint rid = 1; rid <= tableSource.Rows; rid++) { diff --git a/src/DotNet/MD/MetadataBase.cs b/src/DotNet/MD/MetadataBase.cs index 36dc8866c..92903e054 100644 --- a/src/DotNet/MD/MetadataBase.cs +++ b/src/DotNet/MD/MetadataBase.cs @@ -214,7 +214,7 @@ protected MetadataBase(IPEImage peImage, ImageCor20Header cor20Header, MetadataH isStandalonePortablePdb = false; } catch { - if (peImage != null) + if (!(peImage is null)) peImage.Dispose(); throw; } @@ -234,21 +234,21 @@ internal MetadataBase(MetadataHeader mdHeader, bool isStandalonePortablePdb) { public void Initialize(DataReaderFactory mdReaderFactory) { mdReaderFactoryToDisposeLater = mdReaderFactory; uint metadataBaseOffset; - if (peImage != null) { - Debug.Assert(mdReaderFactory == null); - Debug.Assert(cor20Header != null); + if (!(peImage is null)) { + Debug.Assert(mdReaderFactory is null); + Debug.Assert(!(cor20Header is null)); metadataBaseOffset = (uint)peImage.ToFileOffset(cor20Header.Metadata.VirtualAddress); mdReaderFactory = peImage.DataReaderFactory; } else { - Debug.Assert(mdReaderFactory != null); + Debug.Assert(!(mdReaderFactory is null)); metadataBaseOffset = 0; } InitializeInternal(mdReaderFactory, metadataBaseOffset); - if (tablesStream == null) + if (tablesStream is null) throw new BadImageFormatException("Missing MD stream"); - if (isStandalonePortablePdb && pdbStream == null) + if (isStandalonePortablePdb && pdbStream is null) throw new BadImageFormatException("Missing #Pdb stream"); InitializeNonExistentHeaps(); } @@ -257,13 +257,13 @@ public void Initialize(DataReaderFactory mdReaderFactory) { /// Creates empty heap objects if they're not present in the metadata /// protected void InitializeNonExistentHeaps() { - if (stringsStream == null) + if (stringsStream is null) stringsStream = new StringsStream(); - if (usStream == null) + if (usStream is null) usStream = new USStream(); - if (blobStream == null) + if (blobStream is null) blobStream = new BlobStream(); - if (guidStream == null) + if (guidStream is null) guidStream = new GuidStream(); } @@ -394,7 +394,7 @@ public override uint GetEventMapRid(uint typeDefRid) { // The EventMap and PropertyMap tables can only be trusted to be sorted if it's // an NGen image and it's the normal #- stream. The IsSorted bit must not be used // to check whether the tables are sorted. See coreclr: md/inc/metamodel.h / IsVerified() - if (eventMapSortedTable == null) + if (eventMapSortedTable is null) Interlocked.CompareExchange(ref eventMapSortedTable, new SortedTable(tablesStream.EventMapTable, 0), null); var list = eventMapSortedTable.FindAllRows(typeDefRid); return list.Count == 0 ? 0 : list[0]; @@ -402,7 +402,7 @@ public override uint GetEventMapRid(uint typeDefRid) { public override uint GetPropertyMapRid(uint typeDefRid) { // Always unsorted, see comment in GetEventMapRid() above - if (propertyMapSortedTable == null) + if (propertyMapSortedTable is null) Interlocked.CompareExchange(ref propertyMapSortedTable, new SortedTable(tablesStream.PropertyMapTable, 0), null); var list = propertyMapSortedTable.FindAllRows(typeDefRid); return list.Count == 0 ? 0 : list[0]; @@ -416,7 +416,7 @@ public override uint GetConstantRid(Table table, uint rid) { } public override uint GetOwnerTypeOfField(uint fieldRid) { - if (fieldRidToTypeDefRid == null) + if (fieldRidToTypeDefRid is null) InitializeInverseFieldOwnerRidList(); uint index = fieldRid - 1; if (index >= fieldRidToTypeDefRid.LongLength) @@ -425,7 +425,7 @@ public override uint GetOwnerTypeOfField(uint fieldRid) { } void InitializeInverseFieldOwnerRidList() { - if (fieldRidToTypeDefRid != null) + if (!(fieldRidToTypeDefRid is null)) return; var newFieldRidToTypeDefRid = new uint[tablesStream.FieldTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -443,7 +443,7 @@ void InitializeInverseFieldOwnerRidList() { } public override uint GetOwnerTypeOfMethod(uint methodRid) { - if (methodRidToTypeDefRid == null) + if (methodRidToTypeDefRid is null) InitializeInverseMethodOwnerRidList(); uint index = methodRid - 1; if (index >= methodRidToTypeDefRid.LongLength) @@ -452,7 +452,7 @@ public override uint GetOwnerTypeOfMethod(uint methodRid) { } void InitializeInverseMethodOwnerRidList() { - if (methodRidToTypeDefRid != null) + if (!(methodRidToTypeDefRid is null)) return; var newMethodRidToTypeDefRid = new uint[tablesStream.MethodTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -470,7 +470,7 @@ void InitializeInverseMethodOwnerRidList() { } public override uint GetOwnerTypeOfEvent(uint eventRid) { - if (eventRidToTypeDefRid == null) + if (eventRidToTypeDefRid is null) InitializeInverseEventOwnerRidList(); uint index = eventRid - 1; if (index >= eventRidToTypeDefRid.LongLength) @@ -479,7 +479,7 @@ public override uint GetOwnerTypeOfEvent(uint eventRid) { } void InitializeInverseEventOwnerRidList() { - if (eventRidToTypeDefRid != null) + if (!(eventRidToTypeDefRid is null)) return; var newEventRidToTypeDefRid = new uint[tablesStream.EventTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -497,7 +497,7 @@ void InitializeInverseEventOwnerRidList() { } public override uint GetOwnerTypeOfProperty(uint propertyRid) { - if (propertyRidToTypeDefRid == null) + if (propertyRidToTypeDefRid is null) InitializeInversePropertyOwnerRidList(); uint index = propertyRid - 1; if (index >= propertyRidToTypeDefRid.LongLength) @@ -506,7 +506,7 @@ public override uint GetOwnerTypeOfProperty(uint propertyRid) { } void InitializeInversePropertyOwnerRidList() { - if (propertyRidToTypeDefRid != null) + if (!(propertyRidToTypeDefRid is null)) return; var newPropertyRidToTypeDefRid = new uint[tablesStream.PropertyTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -530,7 +530,7 @@ public override uint GetOwnerOfGenericParam(uint gpRid) { // if ever will this occur, but could happen if some obfuscator has // added it. - if (gpRidToOwnerRid == null) + if (gpRidToOwnerRid is null) InitializeInverseGenericParamOwnerRidList(); uint index = gpRid - 1; if (index >= gpRidToOwnerRid.LongLength) @@ -539,7 +539,7 @@ public override uint GetOwnerOfGenericParam(uint gpRid) { } void InitializeInverseGenericParamOwnerRidList() { - if (gpRidToOwnerRid != null) + if (!(gpRidToOwnerRid is null)) return; var gpTable = tablesStream.GenericParamTable; var newGpRidToOwnerRid = new uint[gpTable.Rows]; @@ -575,7 +575,7 @@ public override uint GetOwnerOfGenericParamConstraint(uint gpcRid) { // Don't use GenericParamConstraint.Owner column for the same reason // as described in GetOwnerOfGenericParam(). - if (gpcRidToOwnerRid == null) + if (gpcRidToOwnerRid is null) InitializeInverseGenericParamConstraintOwnerRidList(); uint index = gpcRid - 1; if (index >= gpcRidToOwnerRid.LongLength) @@ -584,7 +584,7 @@ public override uint GetOwnerOfGenericParamConstraint(uint gpcRid) { } void InitializeInverseGenericParamConstraintOwnerRidList() { - if (gpcRidToOwnerRid != null) + if (!(gpcRidToOwnerRid is null)) return; var gpcTable = tablesStream.GenericParamConstraintTable; var newGpcRidToOwnerRid = new uint[gpcTable.Rows]; @@ -613,7 +613,7 @@ void InitializeInverseGenericParamConstraintOwnerRidList() { } public override uint GetOwnerOfParam(uint paramRid) { - if (paramRidToOwnerRid == null) + if (paramRidToOwnerRid is null) InitializeInverseParamOwnerRidList(); uint index = paramRid - 1; if (index >= paramRidToOwnerRid.LongLength) @@ -622,7 +622,7 @@ public override uint GetOwnerOfParam(uint paramRid) { } void InitializeInverseParamOwnerRidList() { - if (paramRidToOwnerRid != null) + if (!(paramRidToOwnerRid is null)) return; var newParamRidToOwnerRid = new uint[tablesStream.ParamTable.Rows]; @@ -640,7 +640,7 @@ void InitializeInverseParamOwnerRidList() { } public override RidList GetNestedClassRidList(uint typeDefRid) { - if (typeDefRidToNestedClasses == null) + if (typeDefRidToNestedClasses is null) InitializeNestedClassesDictionary(); if (typeDefRidToNestedClasses.TryGetValue(typeDefRid, out var ridList)) return RidList.Create(ridList); @@ -662,7 +662,7 @@ void InitializeNestedClassesDictionary() { var nestedRidsDict = new Dictionary((int)table.Rows); var nestedRids = new List((int)table.Rows); // Need it so we add the rids in correct order for (uint rid = 1; rid <= table.Rows; rid++) { - if (validTypeDefRids != null && !validTypeDefRids.ContainsKey(rid)) + if (!(validTypeDefRids is null) && !validTypeDefRids.ContainsKey(rid)) continue; if (!tablesStream.TryReadNestedClassRow(rid, out var row)) continue; // Should never happen since rid is valid @@ -687,7 +687,7 @@ void InitializeNestedClassesDictionary() { var newNonNestedTypes = new List((int)(destTable.Rows - nestedRidsDict.Count)); for (uint rid = 1; rid <= destTable.Rows; rid++) { - if (validTypeDefRids != null && !validTypeDefRids.ContainsKey(rid)) + if (!(validTypeDefRids is null) && !validTypeDefRids.ContainsKey(rid)) continue; if (nestedRidsDict.ContainsKey(rid)) continue; @@ -703,7 +703,7 @@ void InitializeNestedClassesDictionary() { public override RidList GetNonNestedClassRidList() { // Check typeDefRidToNestedClasses and not nonNestedTypes since // InitializeNestedClassesDictionary() writes to typeDefRidToNestedClasses last. - if (typeDefRidToNestedClasses == null) + if (typeDefRidToNestedClasses is null) InitializeNestedClassesDictionary(); return nonNestedTypes.Value; } @@ -740,7 +740,7 @@ protected virtual void Dispose(bool disposing) { guidStream?.Dispose(); tablesStream?.Dispose(); var as2 = allStreams; - if (as2 != null) { + if (!(as2 is null)) { foreach (var stream in as2) stream?.Dispose(); } diff --git a/src/DotNet/MD/MetadataFactory.cs b/src/DotNet/MD/MetadataFactory.cs index e307381f7..f6fcf1961 100644 --- a/src/DotNet/MD/MetadataFactory.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -27,7 +27,7 @@ internal static MetadataBase Load(string fileName) { return Load(peImage = new PEImage(fileName)); } catch { - if (peImage != null) + if (!(peImage is null)) peImage.Dispose(); throw; } @@ -44,7 +44,7 @@ internal static MetadataBase Load(byte[] data) { return Load(peImage = new PEImage(data)); } catch { - if (peImage != null) + if (!(peImage is null)) peImage.Dispose(); throw; } @@ -63,7 +63,7 @@ internal static MetadataBase Load(IntPtr addr) { return Load(peImage = new PEImage(addr, ImageLayout.Memory, true)); } catch { - if (peImage != null) + if (!(peImage is null)) peImage.Dispose(); peImage = null; } @@ -72,7 +72,7 @@ internal static MetadataBase Load(IntPtr addr) { return Load(peImage = new PEImage(addr, ImageLayout.File, true)); } catch { - if (peImage != null) + if (!(peImage is null)) peImage.Dispose(); throw; } @@ -90,7 +90,7 @@ internal static MetadataBase Load(IntPtr addr, ImageLayout imageLayout) { return Load(peImage = new PEImage(addr, imageLayout, true)); } catch { - if (peImage != null) + if (!(peImage is null)) peImage.Dispose(); throw; } @@ -163,7 +163,7 @@ static MetadataBase Create(IPEImage peImage, bool verify) { return md; } catch { - if (md != null) + if (!(md is null)) md.Dispose(); throw; } @@ -212,7 +212,7 @@ internal static MetadataBase CreateStandalonePortablePDB(DataReaderFactory mdRea static MetadataType GetMetadataType(IList streamHeaders) { MetadataType? mdType = null; foreach (var sh in streamHeaders) { - if (mdType == null) { + if (mdType is null) { if (sh.Name == "#~") mdType = MetadataType.Compressed; else if (sh.Name == "#-") @@ -221,7 +221,7 @@ static MetadataType GetMetadataType(IList streamHeaders) { if (sh.Name == "#Schema") mdType = MetadataType.ENC; } - if (mdType == null) + if (mdType is null) return MetadataType.Unknown; return mdType.Value; } diff --git a/src/DotNet/MD/RidList.cs b/src/DotNet/MD/RidList.cs index c61c9b503..fe1a54c29 100644 --- a/src/DotNet/MD/RidList.cs +++ b/src/DotNet/MD/RidList.cs @@ -54,7 +54,7 @@ namespace dnlib.DotNet.MD { /// A rid or 0 if is invalid public uint this[int index] { get { - if (rids != null) { + if (!(rids is null)) { if ((uint)index >= (uint)rids.Count) return 0; return rids[index]; @@ -106,7 +106,7 @@ public void Dispose() { } /// /// public bool MoveNext() { - if (rids == null && index < length) { + if (rids is null && index < length) { current = startRid + index; index++; return true; @@ -119,7 +119,7 @@ bool MoveNextOther() { current = 0; return false; } - if (rids != null) + if (!(rids is null)) current = rids[(int)index]; else current = startRid + index; diff --git a/src/DotNet/MD/StringsStream.cs b/src/DotNet/MD/StringsStream.cs index 47df5ea4c..e2defdf50 100644 --- a/src/DotNet/MD/StringsStream.cs +++ b/src/DotNet/MD/StringsStream.cs @@ -28,7 +28,7 @@ public UTF8String Read(uint offset) { var reader = dataReader; reader.Position = offset; data = reader.TryReadBytesUntil(0); - if (data == null) + if (data is null) return null; return new UTF8String(data); } diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 054185228..f05d873ec 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -196,7 +196,7 @@ public void Initialize(uint[] typeSystemTableRows) { var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out int maxPresentTables); - if (typeSystemTableRows != null) + if (!(typeSystemTableRows is null)) maxPresentTables = DotNetTableSizes.normalMaxTables; mdTables = new MDTable[tableInfos.Length]; @@ -217,7 +217,7 @@ public void Initialize(uint[] typeSystemTableRows) { extraData = reader.ReadUInt32(); var debugSizes = sizes; - if (typeSystemTableRows != null) { + if (!(typeSystemTableRows is null)) { debugSizes = new uint[sizes.Length]; for (int i = 0; i < 64; i++) { if (DotNetTableSizes.IsSystemTable((Table)i)) @@ -315,9 +315,9 @@ void InitializeTables() { protected override void Dispose(bool disposing) { if (disposing) { var mt = mdTables; - if (mt != null) { + if (!(mt is null)) { foreach (var mdTable in mt) { - if (mdTable != null) + if (!(mdTable is null)) mdTable.Dispose(); } mdTables = null; diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index 4cd038c7d..7ff05fbc1 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -142,7 +142,7 @@ public bool TryReadMethodRow(uint rid, out RawMethodRow row) { return false; } var mrr = methodRowReader; - if (mrr != null && mrr.TryReadRow(rid, out row)) + if (!(mrr is null) && mrr.TryReadRow(rid, out row)) return true; var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; @@ -890,7 +890,7 @@ public bool TryReadGenericParamRow(uint rid, out RawGenericParamRow row) { } var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - if (table.Column4 == null) { + if (table.Column4 is null) { row = new RawGenericParamRow( reader.Unsafe_ReadUInt16(), reader.Unsafe_ReadUInt16(), @@ -1142,7 +1142,7 @@ public bool TryReadColumn(MDTable table, uint rid, ColumnInfo column, out uint v return false; } var cr = columnReader; - if (cr != null && cr.ReadColumn(table, rid, column, out value)) + if (!(cr is null) && cr.ReadColumn(table, rid, column, out value)) return true; var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize + (uint)column.Offset; @@ -1160,7 +1160,7 @@ internal bool TryReadColumn24(MDTable table, uint rid, ColumnInfo column, out ui return false; } var cr = columnReader; - if (cr != null && cr.ReadColumn(table, rid, column, out value)) + if (!(cr is null) && cr.ReadColumn(table, rid, column, out value)) return true; var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize + (uint)column.Offset; diff --git a/src/DotNet/ManifestResource.cs b/src/DotNet/ManifestResource.cs index 23582d8bc..c907349a2 100644 --- a/src/DotNet/ManifestResource.cs +++ b/src/DotNet/ManifestResource.cs @@ -75,7 +75,7 @@ public IImplementation Implementation { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -100,7 +100,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -218,7 +218,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public ManifestResourceMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ManifestResourceTable.IsInvalidRID(rid)) throw new BadImageFormatException($"ManifestResource rid {rid} does not exist"); diff --git a/src/DotNet/MarshalBlobReader.cs b/src/DotNet/MarshalBlobReader.cs index efa36fe2c..0a8b7b3c8 100644 --- a/src/DotNet/MarshalBlobReader.cs +++ b/src/DotNet/MarshalBlobReader.cs @@ -86,7 +86,7 @@ MarshalType Read() { case NativeType.SafeArray: var vt = CanRead() ? (VariantType)reader.ReadCompressedUInt32() : VariantType.NotInitialized; var udtName = CanRead() ? ReadUTF8String() : null; - var udtRef = (object)udtName == null ? null : TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(udtName), null, gpContext); + var udtRef = udtName is null ? null : TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(udtName), null, gpContext); returnValue = new SafeArrayMarshalType(vt, udtRef); break; diff --git a/src/DotNet/MarshalType.cs b/src/DotNet/MarshalType.cs index f42a23160..066f230bc 100644 --- a/src/DotNet/MarshalType.cs +++ b/src/DotNet/MarshalType.cs @@ -121,7 +121,7 @@ public ITypeDefOrRef UserDefinedSubType { /// /// true if is valid /// - public bool IsUserDefinedSubTypeValid => userDefinedSubType != null; + public bool IsUserDefinedSubTypeValid => !(userDefinedSubType is null); /// /// Default constructor @@ -160,7 +160,7 @@ public SafeArrayMarshalType(VariantType vt, ITypeDefOrRef userDefinedSubType) /// public override string ToString() { var udt = userDefinedSubType; - if (udt != null) + if (!(udt is null)) return $"{nativeType} ({vt}, {udt})"; return $"{nativeType} ({vt})"; } diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index 6239c0b7e..330209cd6 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -114,7 +114,7 @@ public MemberFinder FindAll(ModuleDef module) { } void Push(object mr) { - if (mr == null) + if (mr is null) return; objectStack.Push(mr); } @@ -143,7 +143,7 @@ void ProcessAll() { readonly Dictionary toObjectType = new Dictionary(); ObjectType GetObjectType(object o) { - if (o == null) + if (o is null) return ObjectType.Unknown; var type = o.GetType(); if (toObjectType.TryGetValue(type, out var mrType)) @@ -180,7 +180,7 @@ void Add(ModuleDef mod) { } void Add(VTableFixups fixups) { - if (fixups == null) + if (fixups is null) return; foreach (var fixup in fixups) { foreach (var method in fixup) @@ -189,14 +189,14 @@ void Add(VTableFixups fixups) { } void Add(AssemblyDef asm) { - if (asm == null) + if (asm is null) return; Add(asm.DeclSecurities); Add(asm.CustomAttributes); } void Add(CallingConventionSig sig) { - if (sig == null) + if (sig is null) return; if (sig is FieldSig fs) { @@ -221,13 +221,13 @@ void Add(CallingConventionSig sig) { } void Add(FieldSig sig) { - if (sig == null) + if (sig is null) return; Add(sig.Type); } void Add(MethodBaseSig sig) { - if (sig == null) + if (sig is null) return; Add(sig.RetType); Add(sig.Params); @@ -235,26 +235,26 @@ void Add(MethodBaseSig sig) { } void Add(LocalSig sig) { - if (sig == null) + if (sig is null) return; Add(sig.Locals); } void Add(GenericInstMethodSig sig) { - if (sig == null) + if (sig is null) return; Add(sig.GenericArguments); } void Add(IEnumerable cas) { - if (cas == null) + if (cas is null) return; foreach (var ca in cas) Add(ca); } void Add(CustomAttribute ca) { - if (ca == null || CustomAttributes.ContainsKey(ca)) + if (ca is null || CustomAttributes.ContainsKey(ca)) return; CustomAttributes[ca] = true; Push(ca.Constructor); @@ -263,7 +263,7 @@ void Add(CustomAttribute ca) { } void Add(IEnumerable args) { - if (args == null) + if (args is null) return; foreach (var arg in args) Add(arg); @@ -275,42 +275,42 @@ void Add(CAArgument arg) { } void Add(IEnumerable args) { - if (args == null) + if (args is null) return; foreach (var arg in args) Add(arg); } void Add(CANamedArgument arg) { - if (arg == null) + if (arg is null) return; Add(arg.Type); Add(arg.Argument); } void Add(IEnumerable decls) { - if (decls == null) + if (decls is null) return; foreach (var decl in decls) Add(decl); } void Add(DeclSecurity decl) { - if (decl == null) + if (decl is null) return; Add(decl.SecurityAttributes); Add(decl.CustomAttributes); } void Add(IEnumerable secAttrs) { - if (secAttrs == null) + if (secAttrs is null) return; foreach (var secAttr in secAttrs) Add(secAttr); } void Add(SecurityAttribute secAttr) { - if (secAttr == null) + if (secAttr is null) return; Add(secAttr.AttributeType); Add(secAttr.NamedArguments); @@ -334,16 +334,16 @@ void Add(ITypeDefOrRef tdr) { } void Add(IEnumerable eds) { - if (eds == null) + if (eds is null) return; foreach (var ed in eds) Add(ed); } void Add(EventDef ed) { - if (ed == null || EventDefs.ContainsKey(ed)) + if (ed is null || EventDefs.ContainsKey(ed)) return; - if (ed.DeclaringType != null && ed.DeclaringType.Module != validModule) + if (!(ed.DeclaringType is null) && ed.DeclaringType.Module != validModule) return; EventDefs[ed] = true; Push(ed.EventType); @@ -356,16 +356,16 @@ void Add(EventDef ed) { } void Add(IEnumerable fds) { - if (fds == null) + if (fds is null) return; foreach (var fd in fds) Add(fd); } void Add(FieldDef fd) { - if (fd == null || FieldDefs.ContainsKey(fd)) + if (fd is null || FieldDefs.ContainsKey(fd)) return; - if (fd.DeclaringType != null && fd.DeclaringType.Module != validModule) + if (!(fd.DeclaringType is null) && fd.DeclaringType.Module != validModule) return; FieldDefs[fd] = true; Add(fd.CustomAttributes); @@ -375,14 +375,14 @@ void Add(FieldDef fd) { } void Add(IEnumerable gps) { - if (gps == null) + if (gps is null) return; foreach (var gp in gps) Add(gp); } void Add(GenericParam gp) { - if (gp == null || GenericParams.ContainsKey(gp)) + if (gp is null || GenericParams.ContainsKey(gp)) return; GenericParams[gp] = true; Push(gp.Owner); @@ -392,14 +392,14 @@ void Add(GenericParam gp) { } void Add(IEnumerable gpcs) { - if (gpcs == null) + if (gpcs is null) return; foreach (var gpc in gpcs) Add(gpc); } void Add(GenericParamConstraint gpc) { - if (gpc == null) + if (gpc is null) return; Add(gpc.Owner); Push(gpc.Constraint); @@ -407,7 +407,7 @@ void Add(GenericParamConstraint gpc) { } void Add(MemberRef mr) { - if (mr == null || MemberRefs.ContainsKey(mr)) + if (mr is null || MemberRefs.ContainsKey(mr)) return; if (mr.Module != validModule) return; @@ -418,16 +418,16 @@ void Add(MemberRef mr) { } void Add(IEnumerable methods) { - if (methods == null) + if (methods is null) return; foreach (var m in methods) Add(m); } void Add(MethodDef md) { - if (md == null || MethodDefs.ContainsKey(md)) + if (md is null || MethodDefs.ContainsKey(md)) return; - if (md.DeclaringType != null && md.DeclaringType.Module != validModule) + if (!(md.DeclaringType is null) && md.DeclaringType.Module != validModule) return; MethodDefs[md] = true; Add(md.Signature); @@ -446,7 +446,7 @@ void Add(MethodBody mb) { } void Add(CilBody cb) { - if (cb == null) + if (cb is null) return; Add(cb.Instructions); Add(cb.ExceptionHandlers); @@ -454,10 +454,10 @@ void Add(CilBody cb) { } void Add(IEnumerable instrs) { - if (instrs == null) + if (instrs is null) return; foreach (var instr in instrs) { - if (instr == null) + if (instr is null) continue; switch (instr.OpCode.OperandType) { case OperandType.InlineTok: @@ -474,12 +474,12 @@ void Add(IEnumerable instrs) { case OperandType.InlineVar: case OperandType.ShortInlineVar: var local = instr.Operand as Local; - if (local != null) { + if (!(local is null)) { Add(local); break; } var arg = instr.Operand as Parameter; - if (arg != null) { + if (!(arg is null)) { Add(arg); break; } @@ -489,48 +489,48 @@ void Add(IEnumerable instrs) { } void Add(IEnumerable ehs) { - if (ehs == null) + if (ehs is null) return; foreach (var eh in ehs) Push(eh.CatchType); } void Add(IEnumerable locals) { - if (locals == null) + if (locals is null) return; foreach (var local in locals) Add(local); } void Add(Local local) { - if (local == null) + if (local is null) return; Add(local.Type); } void Add(IEnumerable ps) { - if (ps == null) + if (ps is null) return; foreach (var p in ps) Add(p); } void Add(Parameter param) { - if (param == null) + if (param is null) return; Add(param.Type); Add(param.Method); } void Add(IEnumerable pds) { - if (pds == null) + if (pds is null) return; foreach (var pd in pds) Add(pd); } void Add(ParamDef pd) { - if (pd == null) + if (pd is null) return; Add(pd.DeclaringMethod); Add(pd.CustomAttributes); @@ -538,7 +538,7 @@ void Add(ParamDef pd) { } void Add(MarshalType mt) { - if (mt == null) + if (mt is null) return; switch (mt.NativeType) { @@ -553,7 +553,7 @@ void Add(MarshalType mt) { } void Add(IEnumerable mos) { - if (mos == null) + if (mos is null) return; foreach (var mo in mos) Add(mo); @@ -566,9 +566,9 @@ void Add(MethodOverride mo) { } void Add(MethodSpec ms) { - if (ms == null || MethodSpecs.ContainsKey(ms)) + if (ms is null || MethodSpecs.ContainsKey(ms)) return; - if (ms.Method != null && ms.Method.DeclaringType != null && ms.Method.DeclaringType.Module != validModule) + if (!(ms.Method is null) && !(ms.Method.DeclaringType is null) && ms.Method.DeclaringType.Module != validModule) return; MethodSpecs[ms] = true; Push(ms.Method); @@ -577,16 +577,16 @@ void Add(MethodSpec ms) { } void Add(IEnumerable pds) { - if (pds == null) + if (pds is null) return; foreach (var pd in pds) Add(pd); } void Add(PropertyDef pd) { - if (pd == null || PropertyDefs.ContainsKey(pd)) + if (pd is null || PropertyDefs.ContainsKey(pd)) return; - if (pd.DeclaringType != null && pd.DeclaringType.Module != validModule) + if (!(pd.DeclaringType is null) && pd.DeclaringType.Module != validModule) return; PropertyDefs[pd] = true; Add(pd.Type); @@ -598,14 +598,14 @@ void Add(PropertyDef pd) { } void Add(IEnumerable tds) { - if (tds == null) + if (tds is null) return; foreach (var td in tds) Add(td); } void Add(TypeDef td) { - if (td == null || TypeDefs.ContainsKey(td)) + if (td is null || TypeDefs.ContainsKey(td)) return; if (td.Module != validModule) return; @@ -624,21 +624,21 @@ void Add(TypeDef td) { } void Add(IEnumerable iis) { - if (iis == null) + if (iis is null) return; foreach (var ii in iis) Add(ii); } void Add(InterfaceImpl ii) { - if (ii == null) + if (ii is null) return; Push(ii.Interface); Add(ii.CustomAttributes); } void Add(TypeRef tr) { - if (tr == null || TypeRefs.ContainsKey(tr)) + if (tr is null || TypeRefs.ContainsKey(tr)) return; if (tr.Module != validModule) return; @@ -648,20 +648,20 @@ void Add(TypeRef tr) { } void Add(IEnumerable tss) { - if (tss == null) + if (tss is null) return; foreach (var ts in tss) Add(ts); } void Add(TypeSig ts) { - if (ts == null || TypeSigs.ContainsKey(ts)) + if (ts is null || TypeSigs.ContainsKey(ts)) return; if (ts.Module != validModule) return; TypeSigs[ts] = true; - for (; ts != null; ts = ts.Next) { + for (; !(ts is null); ts = ts.Next) { switch (ts.ElementType) { case ElementType.Void: case ElementType.Boolean: @@ -724,7 +724,7 @@ void Add(TypeSig ts) { } void Add(TypeSpec ts) { - if (ts == null || TypeSpecs.ContainsKey(ts)) + if (ts is null || TypeSpecs.ContainsKey(ts)) return; if (ts.Module != validModule) return; @@ -734,14 +734,14 @@ void Add(TypeSpec ts) { } void Add(IEnumerable ets) { - if (ets == null) + if (ets is null) return; foreach (var et in ets) Add(et); } void Add(ExportedType et) { - if (et == null || ExportedTypes.ContainsKey(et)) + if (et is null || ExportedTypes.ContainsKey(et)) return; if (et.Module != validModule) return; diff --git a/src/DotNet/MemberMDInitializer.cs b/src/DotNet/MemberMDInitializer.cs index 927cec4f9..93f1470b5 100644 --- a/src/DotNet/MemberMDInitializer.cs +++ b/src/DotNet/MemberMDInitializer.cs @@ -13,7 +13,7 @@ static class MemberMDInitializer { /// Collection element type /// Collection public static void Initialize(IEnumerable coll) { - if (coll == null) + if (coll is null) return; foreach (var c in coll) { } diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index 87109018a..d21eccc57 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -75,7 +75,7 @@ public CallingConventionSig Signature { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -100,7 +100,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -124,7 +124,7 @@ public ITypeDefOrRef DeclaringType { if (owner is ModuleRef mr) { var tr = GetGlobalTypeRef(mr); - if (module != null) + if (!(module is null)) return module.UpdateRowId(tr); return tr; } @@ -134,26 +134,26 @@ public ITypeDefOrRef DeclaringType { } TypeRefUser GetGlobalTypeRef(ModuleRef mr) { - if (module == null) + if (module is null) return CreateDefaultGlobalTypeRef(mr); var globalType = module.GlobalType; - if (globalType != null && new SigComparer().Equals(module, mr)) + if (!(globalType is null) && new SigComparer().Equals(module, mr)) return new TypeRefUser(module, globalType.Namespace, globalType.Name, mr); var asm = module.Assembly; - if (asm == null) + if (asm is null) return CreateDefaultGlobalTypeRef(mr); var mod = asm.FindModule(mr.Name); - if (mod == null) + if (mod is null) return CreateDefaultGlobalTypeRef(mr); globalType = mod.GlobalType; - if (globalType == null) + if (globalType is null) return CreateDefaultGlobalTypeRef(mr); return new TypeRefUser(module, globalType.Namespace, globalType.Name, mr); } TypeRefUser CreateDefaultGlobalTypeRef(ModuleRef mr) { var tr = new TypeRefUser(module, string.Empty, "", mr); - if (module != null) + if (!(module is null)) module.UpdateRowId(tr); return tr; } @@ -175,12 +175,12 @@ TypeRefUser CreateDefaultGlobalTypeRef(ModuleRef mr) { /// /// true if this is a method reference ( != null) /// - public bool IsMethodRef => MethodSig != null; + public bool IsMethodRef => !(MethodSig is null); /// /// true if this is a field reference ( != null) /// - public bool IsFieldRef => FieldSig != null; + public bool IsFieldRef => !(FieldSig is null); /// /// Gets/sets the method sig @@ -207,7 +207,7 @@ public FieldSig FieldSig { public bool HasThis { get { var ms = MethodSig; - return ms == null ? false : ms.HasThis; + return ms is null ? false : ms.HasThis; } } @@ -217,7 +217,7 @@ public bool HasThis { public bool ExplicitThis { get { var ms = MethodSig; - return ms == null ? false : ms.ExplicitThis; + return ms is null ? false : ms.ExplicitThis; } } @@ -227,7 +227,7 @@ public bool ExplicitThis { public CallingConvention CallingConvention { get { var ms = MethodSig; - return ms == null ? 0 : ms.CallingConvention & CallingConvention.Mask; + return ms is null ? 0 : ms.CallingConvention & CallingConvention.Mask; } } @@ -238,7 +238,7 @@ public TypeSig ReturnType { get => MethodSig?.RetType; set { var ms = MethodSig; - if (ms != null) + if (!(ms is null)) ms.RetType = value; } } @@ -258,10 +258,10 @@ public string FullName { typeGenArgs = sig.GenericArguments; } var methodSig = MethodSig; - if (methodSig != null) + if (!(methodSig is null)) return FullNameFactory.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null, null, null); var fieldSig = FieldSig; - if (fieldSig != null) + if (!(fieldSig is null)) return FullNameFactory.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs, null); return string.Empty; } @@ -274,7 +274,7 @@ public string FullName { public string GetDeclaringTypeFullName() => GetDeclaringTypeFullName(@class); string GetDeclaringTypeFullName(IMemberRefParent parent) { - if (parent == null) + if (parent is null) return null; if (parent is ITypeDefOrRef) return ((ITypeDefOrRef)parent).FullName; @@ -293,7 +293,7 @@ string GetDeclaringTypeFullName(IMemberRefParent parent) { /// A or a instance or null /// if it couldn't be resolved. public IMemberForwarded Resolve() { - if (module == null) + if (module is null) return null; return module.Context.Resolver.Resolve(this); } @@ -305,7 +305,7 @@ public IMemberForwarded Resolve() { /// If the method/field couldn't be resolved public IMemberForwarded ResolveThrow() { var memberDef = Resolve(); - if (memberDef != null) + if (!(memberDef is null)) return memberDef; throw new MemberRefResolveException($"Could not resolve method/field: {this} ({this.GetDefinitionAssembly()})"); } @@ -323,7 +323,7 @@ public IMemberForwarded ResolveThrow() { /// If the field couldn't be resolved public FieldDef ResolveFieldThrow() { var field = ResolveField(); - if (field != null) + if (!(field is null)) return field; throw new MemberRefResolveException($"Could not resolve field: {this} ({this.GetDefinitionAssembly()})"); } @@ -341,7 +341,7 @@ public FieldDef ResolveFieldThrow() { /// If the method couldn't be resolved public MethodDef ResolveMethodThrow() { var method = ResolveMethod(); - if (method != null) + if (!(method is null)) return method; throw new MemberRefResolveException($"Could not resolve method: {this} ({this.GetDefinitionAssembly()})"); } @@ -474,7 +474,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public MemberRefMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.MemberRefTable.IsInvalidRID(rid)) throw new BadImageFormatException($"MemberRef rid {rid} does not exist"); diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 0e0ae44bf..8fb4aa5a4 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -118,7 +118,7 @@ public CallingConventionSig Signature { /// public IList ParamDefs { get { - if (paramDefs == null) + if (paramDefs is null) InitializeParamDefs(); return paramDefs; } @@ -132,7 +132,7 @@ protected virtual void InitializeParamDefs() => /// public IList GenericParameters { get { - if (genericParameters == null) + if (genericParameters is null) InitializeGenericParameters(); return genericParameters; } @@ -146,7 +146,7 @@ protected virtual void InitializeGenericParameters() => /// public IList DeclSecurities { get { - if (declSecurities == null) + if (declSecurities is null) InitializeDeclSecurities(); return declSecurities; } @@ -269,7 +269,7 @@ public void FreeMethodBody() { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -291,7 +291,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -307,7 +307,7 @@ protected virtual void InitializeCustomDebugInfos() => /// public IList Overrides { get { - if (overrides == null) + if (overrides is null) InitializeOverrides(); return overrides; } @@ -348,9 +348,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (currentDeclaringType != null) + if (!(currentDeclaringType is null)) currentDeclaringType.Methods.Remove(this); // Will set DeclaringType2 = null - if (value != null) + if (!(value is null)) value.Methods.Add(this); // Will set DeclaringType2 = value } } @@ -419,7 +419,7 @@ public NativeMethodBody NativeBody { /// /// true if it has a /// - public bool HasBody => Body != null; + public bool HasBody => !(Body is null); /// /// true if there's at least one in @@ -429,7 +429,7 @@ public NativeMethodBody NativeBody { /// /// true if is not null /// - public bool HasImplMap => ImplMap != null; + public bool HasImplMap => !(ImplMap is null); /// /// Gets the full name @@ -453,7 +453,7 @@ public MethodSig MethodSig { int IGenericParameterProvider.NumberOfGenericParameters { get { var sig = MethodSig; - return sig == null ? 0 : (int)sig.GenParamCount; + return sig is null ? 0 : (int)sig.GenParamCount; } } @@ -463,7 +463,7 @@ int IGenericParameterProvider.NumberOfGenericParameters { public bool HasThis { get { var ms = MethodSig; - return ms == null ? false : ms.HasThis; + return ms is null ? false : ms.HasThis; } } @@ -473,7 +473,7 @@ public bool HasThis { public bool ExplicitThis { get { var ms = MethodSig; - return ms == null ? false : ms.ExplicitThis; + return ms is null ? false : ms.ExplicitThis; } } @@ -483,7 +483,7 @@ public bool ExplicitThis { public CallingConvention CallingConvention { get { var ms = MethodSig; - return ms == null ? 0 : ms.CallingConvention & CallingConvention.Mask; + return ms is null ? 0 : ms.CallingConvention & CallingConvention.Mask; } } @@ -494,7 +494,7 @@ public TypeSig ReturnType { get => MethodSig?.RetType; set { var ms = MethodSig; - if (ms != null) + if (!(ms is null)) ms.RetType = value; } } @@ -934,7 +934,7 @@ internal virtual void OnLazyAdd2(int index, ref GenericParam value) { /// void IListListener.OnAdd(int index, GenericParam value) { - if (value.Owner != null) + if (!(value.Owner is null)) throw new InvalidOperationException("Generic param is already owned by another type/method. Set Owner to null first."); value.Owner = this; } @@ -964,7 +964,7 @@ internal virtual void OnLazyAdd2(int index, ref ParamDef value) { /// void IListListener.OnAdd(int index, ParamDef value) { - if (value.DeclaringMethod != null) + if (!(value.DeclaringMethod is null)) throw new InvalidOperationException("Param is already owned by another method. Set DeclaringMethod to null first."); value.DeclaringMethod = this; } @@ -1107,7 +1107,7 @@ protected override void InitializeCustomAttributes() { /// protected override void InitializeCustomDebugInfos() { var list = new List(); - if (Interlocked.CompareExchange(ref customDebugInfos, list, null) == null) { + if (Interlocked.CompareExchange(ref customDebugInfos, list, null) is null) { var body = Body; readerModule.InitializeCustomDebugInfos(this, body, list); } @@ -1116,7 +1116,7 @@ protected override void InitializeCustomDebugInfos() { /// protected override void InitializeOverrides() { var dt = declaringType2 as TypeDefMD; - var tmp = dt == null ? new List() : dt.GetMethodOverrides(this, new GenericParamContext(declaringType2, this)); + var tmp = dt is null ? new List() : dt.GetMethodOverrides(this, new GenericParamContext(declaringType2, this)); Interlocked.CompareExchange(ref overrides, tmp, null); } @@ -1136,7 +1136,7 @@ protected override void InitializeSemanticsAttributes() { /// If is invalid public MethodDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.MethodTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Method rid {rid} does not exist"); diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index 1b1ed6aeb..0f612ba54 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -54,7 +54,7 @@ public CallingConventionSig Instantiation { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -79,7 +79,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -95,7 +95,7 @@ MethodSig IMethod.MethodSig { get => method?.MethodSig; set { var m = method; - if (m != null) + if (!(m is null)) m.MethodSig = value; } } @@ -104,11 +104,11 @@ MethodSig IMethod.MethodSig { public UTF8String Name { get { var m = method; - return m == null ? UTF8String.Empty : m.Name; + return m is null ? UTF8String.Empty : m.Name; } set { var m = method; - if (m != null) + if (!(m is null)) m.Name = value; } } @@ -142,7 +142,7 @@ public string FullName { if (m is MemberRef memberRef) { var methodSig = memberRef.MethodSig; - if (methodSig != null) { + if (!(methodSig is null)) { var gis = (memberRef.Class as TypeSpec)?.TypeSig as GenericInstSig; var typeGenArgs = gis?.GenericArguments; return FullNameFactory.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs, null, null); @@ -238,7 +238,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public MethodSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.MethodSpecTable.IsInvalidRID(rid)) throw new BadImageFormatException($"MethodSpec rid {rid} does not exist"); diff --git a/src/DotNet/ModuleContext.cs b/src/DotNet/ModuleContext.cs index 1696c12f2..9f4fb270f 100644 --- a/src/DotNet/ModuleContext.cs +++ b/src/DotNet/ModuleContext.cs @@ -15,7 +15,7 @@ public class ModuleContext { /// public IAssemblyResolver AssemblyResolver { get { - if (assemblyResolver == null) + if (assemblyResolver is null) Interlocked.CompareExchange(ref assemblyResolver, NullResolver.Instance, null); return assemblyResolver; } @@ -27,7 +27,7 @@ public IAssemblyResolver AssemblyResolver { /// public IResolver Resolver { get { - if (resolver == null) + if (resolver is null) Interlocked.CompareExchange(ref resolver, NullResolver.Instance, null); return resolver; } @@ -64,7 +64,7 @@ public ModuleContext(IResolver resolver) public ModuleContext(IAssemblyResolver assemblyResolver, IResolver resolver) { this.assemblyResolver = assemblyResolver; this.resolver = resolver; - if (resolver == null && assemblyResolver != null) + if (resolver is null && !(assemblyResolver is null)) this.resolver = new Resolver(assemblyResolver); } } diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 57517c3d2..1b19b3a79 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -139,7 +139,7 @@ public Guid? EncBaseId { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -161,7 +161,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -188,7 +188,7 @@ public AssemblyDef Assembly { /// public IList Types { get { - if (types == null) + if (types is null) InitializeTypes(); return types; } @@ -204,7 +204,7 @@ protected virtual void InitializeTypes() => /// public IList ExportedTypes { get { - if (exportedTypes == null) + if (exportedTypes is null) InitializeExportedTypes(); return exportedTypes; } @@ -305,19 +305,19 @@ public MethodDef EntryPoint { /// /// true if is non-null /// - public bool IsManagedEntryPointValid => ManagedEntryPoint != null; + public bool IsManagedEntryPointValid => !(ManagedEntryPoint is null); /// /// true if is non-null /// - public bool IsEntryPointValid => EntryPoint != null; + public bool IsEntryPointValid => !(EntryPoint is null); /// /// Gets a list of all s /// public ResourceCollection Resources { get { - if (resources == null) + if (resources is null) InitializeResources(); return resources; } @@ -408,7 +408,7 @@ public string Location { /// TypeDefFinder TypeDefFinder { get { - if (typeDefFinder == null) + if (typeDefFinder is null) Interlocked.CompareExchange(ref typeDefFinder, new TypeDefFinder(Types), null); return typeDefFinder; } @@ -419,7 +419,7 @@ TypeDefFinder TypeDefFinder { /// public ModuleContext Context { get { - if (context == null) + if (context is null) Interlocked.CompareExchange(ref context, new ModuleContext(), null); return context; } @@ -449,7 +449,7 @@ public bool EnableTypeDefFindCache { public bool IsManifestModule { get { var asm = assembly; - return asm != null && asm.ManifestModule == this; + return !(asm is null) && asm.ManifestModule == this; } } @@ -551,7 +551,7 @@ public string RuntimeVersion { public WinMDStatus WinMDStatus { get { var cval = cachedWinMDStatus; - if (cval != null) + if (!(cval is null)) return cval.Value; cachedWinMDStatus = cval = CalculateWinMDStatus(RuntimeVersion); return cval.Value; @@ -582,7 +582,7 @@ public WinMDStatus WinMDStatus { public string RuntimeVersionWinMD { get { var rtver = runtimeVersionWinMD; - if (rtver != null) + if (!(rtver is null)) return rtver; runtimeVersionWinMD = rtver = CalculateRuntimeVersionWinMD(RuntimeVersion); return rtver; @@ -597,7 +597,7 @@ public string RuntimeVersionWinMD { public string WinMDVersion { get { var ver = winMDVersion; - if (ver != null) + if (!(ver is null)) return ver; winMDVersion = ver = CalculateWinMDVersion(RuntimeVersion); return ver; @@ -606,7 +606,7 @@ public string WinMDVersion { string winMDVersion; static WinMDStatus CalculateWinMDStatus(string version) { - if (version == null) + if (version is null) return WinMDStatus.None; if (!version.StartsWith("WindowsRuntime ", StringComparison.Ordinal)) return WinMDStatus.None; @@ -618,7 +618,7 @@ static string CalculateRuntimeVersionWinMD(string version) { // Original parser code: // CoreCLR file: src/md/winmd/adapter.cpp // Func: WinMDAdapter::Create(IMDCommon *pRawMDCommon, /*[out]*/ WinMDAdapter **ppAdapter) - if (version == null) + if (version is null) return null; if (!version.StartsWith("WindowsRuntime ", StringComparison.Ordinal)) return null; @@ -634,7 +634,7 @@ static string CalculateRuntimeVersionWinMD(string version) { } static string CalculateWinMDVersion(string version) { - if (version == null) + if (version is null) return null; if (!version.StartsWith("WindowsRuntime ", StringComparison.Ordinal)) return null; @@ -859,7 +859,7 @@ protected virtual void Dispose(bool disposing) { if (!disposing) return; var tdf = typeDefFinder; - if (tdf != null) { + if (!(tdf is null)) { tdf.Dispose(); typeDefFinder = null; } @@ -878,7 +878,7 @@ protected virtual void Dispose(bool disposing) { /// /// The to insert public void AddAsNonNestedType(TypeDef typeDef) { - if (typeDef == null) + if (typeDef is null) return; typeDef.DeclaringType = null; Types.Add(typeDef); @@ -1083,16 +1083,16 @@ public void Write(Stream dest, ModuleWriterOptions options) { /// /// New public void SetPdbState(PdbState pdbState) { - if (pdbState == null) + if (pdbState is null) throw new ArgumentNullException(nameof(pdbState)); var orig = Interlocked.CompareExchange(ref this.pdbState, pdbState, null); - if (orig != null) + if (!(orig is null)) throw new InvalidOperationException("PDB file has already been initialized"); } uint GetCor20RuntimeVersion() { var rtVer = Cor20HeaderRuntimeVersion; - if (rtVer != null) + if (!(rtVer is null)) return rtVer.Value; return IsClr1x ? 0x00020000U : 0x00020005; } @@ -1162,17 +1162,17 @@ public int GetPointerSize(int defaultPointerSize, int prefer32bitPointerSize) { /// void IListListener.OnLazyAdd(int index, ref TypeDef value) { #if DEBUG - if (value.DeclaringType != null) - throw new InvalidOperationException("Added type's DeclaringType != null"); + if (!(value.DeclaringType is null)) + throw new InvalidOperationException("Added type's !(DeclaringType is null)"); #endif value.Module2 = this; } /// void IListListener.OnAdd(int index, TypeDef value) { - if (value.DeclaringType != null) + if (!(value.DeclaringType is null)) throw new InvalidOperationException("Nested type is already owned by another type. Set DeclaringType to null first."); - if (value.Module != null) + if (!(value.Module is null)) throw new InvalidOperationException("Type is already owned by another module. Remove it from that module's type list."); value.Module2 = this; } @@ -1223,18 +1223,18 @@ public TypeDef Find(ITypeDefOrRef typeRef) { return Find(tr); var ts = typeRef as TypeSpec; - if (ts == null) + if (ts is null) return null; var sig = ts.TypeSig as TypeDefOrRefSig; - if (sig == null) + if (sig is null) return null; td = sig.TypeDef; - if (td != null) + if (!(td is null)) return td.Module == this ? td : null; tr = sig.TypeRef; - if (tr != null) + if (!(tr is null)) return Find(tr); return null; @@ -1315,7 +1315,7 @@ public static ModuleContext CreateModuleContext() { public IEnumerable GetAssemblyRefs() { for (uint rid = 1; ; rid++) { var asmRef = ResolveToken(new MDToken(Table.AssemblyRef, rid).Raw) as AssemblyRef; - if (asmRef == null) + if (asmRef is null) break; yield return asmRef; } @@ -1327,7 +1327,7 @@ public IEnumerable GetAssemblyRefs() { public IEnumerable GetModuleRefs() { for (uint rid = 1; ; rid++) { var modRef = ResolveToken(new MDToken(Table.ModuleRef, rid).Raw) as ModuleRef; - if (modRef == null) + if (modRef is null) break; yield return modRef; } @@ -1347,7 +1347,7 @@ public IEnumerable GetModuleRefs() { public IEnumerable GetMemberRefs(GenericParamContext gpContext) { for (uint rid = 1; ; rid++) { var mr = ResolveToken(new MDToken(Table.MemberRef, rid).Raw, gpContext) as MemberRef; - if (mr == null) + if (mr is null) break; yield return mr; } @@ -1359,7 +1359,7 @@ public IEnumerable GetMemberRefs(GenericParamContext gpContext) { public IEnumerable GetTypeRefs() { for (uint rid = 1; ; rid++) { var mr = ResolveToken(new MDToken(Table.TypeRef, rid).Raw) as TypeRef; - if (mr == null) + if (mr is null) break; yield return mr; } @@ -1390,11 +1390,11 @@ public AssemblyRef GetAssemblyRef(UTF8String simpleName) { /// New asm ref /// protected static bool IsGreaterAssemblyRefVersion(AssemblyRef found, AssemblyRef newOne) { - if (found == null) + if (found is null) return true; var foundVer = found.Version; var newVer = newOne.Version; - return foundVer == null || (newVer != null && newVer >= foundVer); + return foundVer is null || (!(newVer is null) && newVer >= foundVer); } ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { @@ -1508,10 +1508,10 @@ protected override void InitializeCustomDebugInfos() { /// If is null /// If is invalid internal ModuleDefMD2(ModuleDefMD readerModule, uint rid) { - if (rid == 1 && readerModule == null) + if (rid == 1 && readerModule is null) readerModule = (ModuleDefMD)this; #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (rid != 1 && readerModule.TablesStream.ModuleTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Module rid {rid} does not exist"); diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 629792a88..6835c5bdb 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -209,7 +209,7 @@ static ImageLayout GetImageLayout(System.Reflection.Module mod) { static IntPtr GetModuleHandle(System.Reflection.Module mod) { #if NETSTANDARD var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new[] { typeof(System.Reflection.Module) }); - if (GetHINSTANCE == null) + if (GetHINSTANCE is null) return IntPtr.Zero; return (IntPtr)GetHINSTANCE.Invoke(null, new[] { mod }); @@ -330,7 +330,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// A new instance /// If is null public static ModuleDefMD Load(Stream stream, ModuleCreationOptions options) { - if (stream == null) + if (stream is null) throw new ArgumentNullException(nameof(stream)); if (stream.Length > int.MaxValue) throw new ArgumentException("Stream is too big"); @@ -358,10 +358,10 @@ public static ModuleDefMD Load(Stream stream, ModuleCreationOptions options) { ModuleDefMD(MetadataBase metadata, ModuleCreationOptions options) : base(null, 1) { #if DEBUG - if (metadata == null) + if (metadata is null) throw new ArgumentNullException(nameof(metadata)); #endif - if (options == null) + if (options is null) options = ModuleCreationOptions.Default; this.metadata = metadata; context = options.Context; @@ -382,17 +382,17 @@ public static ModuleDefMD Load(Stream stream, ModuleCreationOptions options) { } void InitializePdb(ModuleCreationOptions options) { - if (options == null) + if (options is null) return; LoadPdb(CreateSymbolReader(options)); } SymbolReader CreateSymbolReader(ModuleCreationOptions options) { - if (options.PdbFileOrData != null) { + if (!(options.PdbFileOrData is null)) { var pdbFileName = options.PdbFileOrData as string; if (!string.IsNullOrEmpty(pdbFileName)) { var symReader = SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbFileName); - if (symReader != null) + if (!(symReader is null)) return symReader; } @@ -414,13 +414,13 @@ SymbolReader CreateSymbolReader(ModuleCreationOptions options) { /// /// PDB symbol reader public void LoadPdb(SymbolReader symbolReader) { - if (symbolReader == null) + if (symbolReader is null) return; - if (pdbState != null) + if (!(pdbState is null)) throw new InvalidOperationException("PDB file has already been initialized"); var orig = Interlocked.CompareExchange(ref pdbState, new PdbState(symbolReader, this), null); - if (orig != null) + if (!(orig is null)) throw new InvalidOperationException("PDB file has already been initialized"); } @@ -484,7 +484,7 @@ public void LoadPdb(PdbReaderOptions options) => internal void InitializeCustomDebugInfos(MDToken token, GenericParamContext gpContext, IList result) { var ps = pdbState; - if (ps == null) + if (ps is null) return; ps.InitializeCustomDebugInfos(token, gpContext, result); } @@ -538,7 +538,7 @@ void Initialize() { for (int i = 0; i < 64; i++) { var tbl = TablesStream.Get((Table)i); - lastUsedRids[i] = tbl == null ? 0 : (int)tbl.Rows; + lastUsedRids[i] = tbl is null ? 0 : (int)tbl.Rows; } } @@ -579,7 +579,7 @@ AssemblyRef FindCorLibAssemblyRef() { corLibAsmRef = asmRef; } } - if (corLibAsmRef != null) + if (!(corLibAsmRef is null)) return corLibAsmRef; for (uint i = 1; i <= numAsmRefs; i++) { @@ -589,7 +589,7 @@ AssemblyRef FindCorLibAssemblyRef() { if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) corLibAsmRef = asmRef; } - if (corLibAsmRef != null) + if (!(corLibAsmRef is null)) return corLibAsmRef; for (uint i = 1; i <= numAsmRefs; i++) { @@ -599,12 +599,12 @@ AssemblyRef FindCorLibAssemblyRef() { if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) corLibAsmRef = asmRef; } - if (corLibAsmRef != null) + if (!(corLibAsmRef is null)) return corLibAsmRef; // If we've loaded mscorlib itself, it won't have any AssemblyRefs to itself. var asm = Assembly; - if (asm != null && (asm.IsCorLib() || Find("System.Object", false) != null)) { + if (!(asm is null) && (asm.IsCorLib() || !(Find("System.Object", false) is null))) { IsCoreLibraryModule = true; return UpdateRowId(new AssemblyRefUser(asm)); } @@ -618,7 +618,7 @@ AssemblyRef FindCorLibAssemblyRef() { /// AssemblyRef CreateDefaultCorLibAssemblyRef() { var asmRef = GetAlternativeCorLibReference(); - if (asmRef != null) + if (!(asmRef is null)) return UpdateRowId(asmRef); if (IsClr40) @@ -648,7 +648,7 @@ static bool IsAssemblyRef(AssemblyRef asmRef, UTF8String name, PublicKeyToken to if (asmRef.Name != name) return false; var pkot = asmRef.PublicKeyOrToken; - if (pkot == null) + if (pkot is null) return false; return token.Equals(pkot.Token); } @@ -663,7 +663,7 @@ protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { var md = metadata; - if (md != null) + if (!(md is null)) md.Dispose(); metadata = null; } @@ -1365,12 +1365,12 @@ public CilBody ReadCilBody(IList parameters, RVA rva, GenericParamCon /// is invalid or if it's not a .NET module. internal ModuleDefMD ReadModule(uint fileRid, AssemblyDef owner) { var fileDef = ResolveFile(fileRid); - if (fileDef == null) + if (fileDef is null) return null; if (!fileDef.ContainsMetadata) return null; var fileName = GetValidFilename(GetBaseDirectoryOfImage(), UTF8String.ToSystemString(fileDef.Name)); - if (fileName == null) + if (fileName is null) return null; ModuleDefMD module; try { @@ -1379,12 +1379,12 @@ internal ModuleDefMD ReadModule(uint fileRid, AssemblyDef owner) { catch { module = null; } - if (module != null) { + if (!(module is null)) { // share context module.context = context; var asm = module.Assembly; - if (asm != null && asm != owner) + if (!(asm is null) && asm != owner) asm.Modules.Remove(module); } return module; @@ -1396,13 +1396,13 @@ internal ModuleDefMD ReadModule(uint fileRid, AssemblyDef owner) { /// /// A new instance internal RidList GetModuleRidList() { - if (moduleRidList == null) + if (moduleRidList is null) InitializeModuleList(); return moduleRidList.Value; } void InitializeModuleList() { - if (moduleRidList != null) + if (!(moduleRidList is null)) return; uint rows = TablesStream.FileTable.Rows; var newModuleRidList = new List((int)rows); @@ -1410,12 +1410,12 @@ void InitializeModuleList() { var baseDir = GetBaseDirectoryOfImage(); for (uint fileRid = 1; fileRid <= rows; fileRid++) { var fileDef = ResolveFile(fileRid); - if (fileDef == null) + if (fileDef is null) continue; // Should never happen if (!fileDef.ContainsMetadata) continue; var pathName = GetValidFilename(baseDir, UTF8String.ToSystemString(fileDef.Name)); - if (pathName != null) + if (!(pathName is null)) newModuleRidList.Add(fileRid); } Interlocked.CompareExchange(ref moduleRidList, new StrongBox(RidList.Create(newModuleRidList)), null); @@ -1428,7 +1428,7 @@ void InitializeModuleList() { /// File name /// Full path to the file or null if one of the inputs is invalid static string GetValidFilename(string baseDir, string name) { - if (baseDir == null) + if (baseDir is null) return null; string pathName; @@ -1479,7 +1479,7 @@ Resource CreateResource(uint rid) { return new EmbeddedResource(UTF8String.Empty, Array2.Empty(), 0) { Rid = rid }; var mr = ResolveManifestResource(rid); - if (mr == null) + if (mr is null) return new EmbeddedResource(UTF8String.Empty, Array2.Empty(), 0) { Rid = rid }; if (token.Rid == 0) { @@ -1669,7 +1669,7 @@ public IManagedEntryPoint GetManagedEntryPoint() { /// A or null if none internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, GenericParamContext gpContext) { var mDec = methodDecrypter; - if (mDec != null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out var mb)) { + if (!(mDec is null) && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out var mb)) { if (mb is CilBody cilBody) return InitializeBodyFromPdb(method, cilBody); return mb; @@ -1693,17 +1693,17 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// Returns originak value CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body) { var ps = pdbState; - if (ps != null) + if (!(ps is null)) ps.InitializeMethodBody(this, method, body); return body; } internal void InitializeCustomDebugInfos(MethodDefMD method, CilBody body, IList customDebugInfos) { - if (body == null) + if (body is null) return; var ps = pdbState; - if (ps != null) + if (!(ps is null)) ps.InitializeCustomDebugInfos(method, body, customDebugInfos); } @@ -1714,16 +1714,16 @@ internal void InitializeCustomDebugInfos(MethodDefMD method, CilBody body, IList /// A non-null string public string ReadUserString(uint token) { var sDec = stringDecrypter; - if (sDec != null) { + if (!(sDec is null)) { var s = sDec.ReadUserString(token); - if (s != null) + if (!(s is null)) return s; } return USStream.ReadNoNull(token & 0x00FFFFFF); } internal MethodExportInfo GetExportInfo(uint methodRid) { - if (methodExportInfoProvider == null) + if (methodExportInfoProvider is null) InitializeMethodExportInfoProvider(); return methodExportInfoProvider.GetMethodExportInfo(0x06000000 + methodRid); } diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index 44ca5ba97..380fe30ae 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -65,7 +65,7 @@ void Load() { void Process() { while (stack.Count != 0) { - if (cancellationToken != null) + if (!(cancellationToken is null)) cancellationToken.ThrowIfCancellationRequested(); var o = stack.Pop(); LoadObj(o); @@ -74,12 +74,12 @@ void Process() { void LoadAllTables() { var resolver = module as ITokenResolver; - if (resolver == null) + if (resolver is null) return; for (Table tbl = 0; tbl <= Table.GenericParamConstraint; tbl++) { for (uint rid = 1; ; rid++) { var o = resolver.ResolveToken(new MDToken(tbl, rid).Raw, new GenericParamContext()); - if (o == null) + if (o is null) break; Add(o); Process(); @@ -137,7 +137,7 @@ void LoadObj(object o) { } void Load(TypeSig ts) { - if (ts == null) + if (ts is null) return; Add(ts.Next); @@ -206,7 +206,7 @@ void Load(TypeSig ts) { } void Load(IMDTokenProvider mdt) { - if (mdt == null) + if (mdt is null) return; switch (mdt.MDToken.Table) { case Table.Module: Load((ModuleDef)mdt); break; @@ -236,13 +236,13 @@ void Load(IMDTokenProvider mdt) { case Table.ManifestResource: var rsrc = mdt as Resource; - if (rsrc != null) { + if (!(rsrc is null)) { Load(rsrc); break; } var mr = mdt as ManifestResource; - if (mr != null) { + if (!(mr is null)) { Load(mr); break; } @@ -287,7 +287,7 @@ void Load(IMDTokenProvider mdt) { } void Load(ModuleDef obj) { - if (obj == null || obj != module) + if (obj is null || obj != module) return; Add(obj.Generation); Add(obj.Name); @@ -312,7 +312,7 @@ void Load(ModuleDef obj) { } void Load(TypeRef obj) { - if (obj == null) + if (obj is null) return; Add(obj.ResolutionScope); Add(obj.Name); @@ -321,7 +321,7 @@ void Load(TypeRef obj) { } void Load(TypeDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Module2); Add(obj.Attributes); @@ -343,7 +343,7 @@ void Load(TypeDef obj) { } void Load(FieldDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.CustomAttributes); Add(obj.Attributes); @@ -359,7 +359,7 @@ void Load(FieldDef obj) { } void Load(MethodDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.RVA); Add(obj.ImplAttributes); @@ -379,7 +379,7 @@ void Load(MethodDef obj) { } void Load(ParamDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.DeclaringMethod); Add(obj.Attributes); @@ -391,14 +391,14 @@ void Load(ParamDef obj) { } void Load(InterfaceImpl obj) { - if (obj == null) + if (obj is null) return; Add(obj.Interface); Add(obj.CustomAttributes); } void Load(MemberRef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Class); Add(obj.Name); @@ -407,14 +407,14 @@ void Load(MemberRef obj) { } void Load(Constant obj) { - if (obj == null) + if (obj is null) return; Add(obj.Type); var o = obj.Value; } void Load(DeclSecurity obj) { - if (obj == null) + if (obj is null) return; Add(obj.Action); Add(obj.SecurityAttributes); @@ -423,21 +423,21 @@ void Load(DeclSecurity obj) { } void Load(ClassLayout obj) { - if (obj == null) + if (obj is null) return; Add(obj.PackingSize); Add(obj.ClassSize); } void Load(StandAloneSig obj) { - if (obj == null) + if (obj is null) return; Add(obj.Signature); Add(obj.CustomAttributes); } void Load(EventDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Attributes); Add(obj.Name); @@ -451,7 +451,7 @@ void Load(EventDef obj) { } void Load(PropertyDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Attributes); Add(obj.Name); @@ -465,14 +465,14 @@ void Load(PropertyDef obj) { } void Load(ModuleRef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Name); Add(obj.CustomAttributes); } void Load(TypeSpec obj) { - if (obj == null) + if (obj is null) return; Add(obj.TypeSig); Add(obj.ExtraData); @@ -480,7 +480,7 @@ void Load(TypeSpec obj) { } void Load(ImplMap obj) { - if (obj == null) + if (obj is null) return; Add(obj.Attributes); Add(obj.Name); @@ -488,7 +488,7 @@ void Load(ImplMap obj) { } void Load(AssemblyDef obj) { - if (obj == null) + if (obj is null) return; if (obj.ManifestModule != module) return; @@ -504,7 +504,7 @@ void Load(AssemblyDef obj) { } void Load(AssemblyRef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Version); Add(obj.Attributes); @@ -516,7 +516,7 @@ void Load(AssemblyRef obj) { } void Load(FileDef obj) { - if (obj == null) + if (obj is null) return; Add(obj.Flags); Add(obj.Name); @@ -525,7 +525,7 @@ void Load(FileDef obj) { } void Load(ExportedType obj) { - if (obj == null) + if (obj is null) return; Add(obj.CustomAttributes); Add(obj.Attributes); @@ -536,7 +536,7 @@ void Load(ExportedType obj) { } void Load(Resource obj) { - if (obj == null) + if (obj is null) return; Add(obj.Offset); @@ -565,7 +565,7 @@ void Load(Resource obj) { } void Load(ManifestResource obj) { - if (obj == null) + if (obj is null) return; Add(obj.Offset); Add(obj.Flags); @@ -575,7 +575,7 @@ void Load(ManifestResource obj) { } void Load(GenericParam obj) { - if (obj == null) + if (obj is null) return; Add(obj.Owner); Add(obj.Number); @@ -587,7 +587,7 @@ void Load(GenericParam obj) { } void Load(MethodSpec obj) { - if (obj == null) + if (obj is null) return; Add(obj.Method); Add(obj.Instantiation); @@ -595,7 +595,7 @@ void Load(MethodSpec obj) { } void Load(GenericParamConstraint obj) { - if (obj == null) + if (obj is null) return; Add(obj.Owner); Add(obj.Constraint); @@ -603,7 +603,7 @@ void Load(GenericParamConstraint obj) { } void Load(CANamedArgument obj) { - if (obj == null) + if (obj is null) return; Add(obj.Type); Add(obj.Name); @@ -611,20 +611,20 @@ void Load(CANamedArgument obj) { } void Load(Parameter obj) { - if (obj == null) + if (obj is null) return; Add(obj.Type); } void Load(SecurityAttribute obj) { - if (obj == null) + if (obj is null) return; Add(obj.AttributeType); Add(obj.NamedArguments); } void Load(CustomAttribute obj) { - if (obj == null) + if (obj is null) return; Add(obj.Constructor); Add(obj.RawData); @@ -662,7 +662,7 @@ void Load(CAArgument obj) { void Load(PdbMethod obj) { } void Load(ResourceDirectory obj) { - if (obj == null) + if (obj is null) return; Add(obj.Directories); Add(obj.Data); @@ -671,7 +671,7 @@ void Load(ResourceDirectory obj) { void Load(ResourceData obj) { } void AddToStack(T t) where T : class { - if (t == null) + if (t is null) return; if (seen.ContainsKey(t)) return; @@ -690,98 +690,98 @@ void Add(PdbMethod pdbMethod) { } void Add(ResourceData rd) => AddToStack(rd); void Add(IList list) where T : IMDTokenProvider { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Load(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Load(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(ParameterList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(IList list) { - if (list == null) + if (list is null) return; foreach (var item in list) Add(item); } void Add(VTableFixups vtf) { - if (vtf == null) + if (vtf is null) return; foreach (var fixup in vtf) { foreach (var method in fixup) @@ -790,7 +790,7 @@ void Add(VTableFixups vtf) { } void Add(Win32Resources vtf) { - if (vtf == null) + if (vtf is null) return; Add(vtf.Root); } @@ -816,11 +816,11 @@ void Add(CallingConventionSig sig) { return; } - Debug.Assert(sig == null); + Debug.Assert(sig is null); } void Add(MethodBaseSig msig) { - if (msig == null) + if (msig is null) return; Add(msig.ExtraData); Add(msig.RetType); @@ -829,28 +829,28 @@ void Add(MethodBaseSig msig) { } void Add(FieldSig fsig) { - if (fsig == null) + if (fsig is null) return; Add(fsig.ExtraData); Add(fsig.Type); } void Add(LocalSig lsig) { - if (lsig == null) + if (lsig is null) return; Add(lsig.ExtraData); Add(lsig.Locals); } void Add(GenericInstMethodSig gsig) { - if (gsig == null) + if (gsig is null) return; Add(gsig.ExtraData); Add(gsig.GenericArguments); } void Add(MarshalType mt) { - if (mt == null) + if (mt is null) return; Add(mt.NativeType); } @@ -866,17 +866,17 @@ void Add(MethodBody mb) { return; } - Debug.Assert(mb == null, "Unknown method body"); + Debug.Assert(mb is null, "Unknown method body"); } void Add(NativeMethodBody body) { - if (body == null) + if (body is null) return; Add(body.RVA); } void Add(CilBody body) { - if (body == null) + if (body is null) return; Add(body.Instructions); Add(body.ExceptionHandlers); @@ -885,7 +885,7 @@ void Add(CilBody body) { } void Add(Instruction instr) { - if (instr == null) + if (instr is null) return; if (instr.Operand is IMDTokenProvider mdt) { @@ -910,19 +910,19 @@ void Add(Instruction instr) { } void Add(ExceptionHandler eh) { - if (eh == null) + if (eh is null) return; Add(eh.CatchType); } void Add(Local local) { - if (local == null) + if (local is null) return; Add(local.Type); } void Add(PdbState state) { - if (state == null) + if (state is null) return; Add(state.UserEntryPoint); } diff --git a/src/DotNet/ModuleRef.cs b/src/DotNet/ModuleRef.cs index 7e20713d6..22cacc69b 100644 --- a/src/DotNet/ModuleRef.cs +++ b/src/DotNet/ModuleRef.cs @@ -61,7 +61,7 @@ public UTF8String Name { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -86,7 +86,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -106,7 +106,7 @@ protected virtual void InitializeCustomDebugInfos() => /// public ModuleDef DefinitionModule { get { - if (module == null) + if (module is null) return null; var n = name; if (UTF8String.CaseInsensitiveEquals(n, module.Name)) @@ -186,7 +186,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public ModuleRefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ModuleRefTable.IsInvalidRID(rid)) throw new BadImageFormatException($"ModuleRef rid {rid} does not exist"); diff --git a/src/DotNet/ParamDef.cs b/src/DotNet/ParamDef.cs index d071271a7..797cbba5e 100644 --- a/src/DotNet/ParamDef.cs +++ b/src/DotNet/ParamDef.cs @@ -170,7 +170,7 @@ void InitializeConstant() { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -195,7 +195,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -209,7 +209,7 @@ protected virtual void InitializeCustomDebugInfos() => /// /// true if is not null /// - public bool HasConstant => Constant != null; + public bool HasConstant => !(Constant is null); /// /// Gets the constant element type or if there's no constant @@ -217,14 +217,14 @@ protected virtual void InitializeCustomDebugInfos() => public ElementType ElementType { get { var c = Constant; - return c == null ? ElementType.End : c.Type; + return c is null ? ElementType.End : c.Type; } } /// /// true if is not null /// - public bool HasMarshalType => MarshalType != null; + public bool HasMarshalType => !(MarshalType is null); /// public string FullName { @@ -389,7 +389,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public ParamDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.ParamTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Param rid {rid} does not exist"); diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index d0dd96ab4..17b62ee0e 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -116,7 +116,7 @@ internal void UpdateThisParameterType(TypeDef methodDeclaringType) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (methodDeclaringType == null) + if (methodDeclaringType is null) hiddenThisParameter.Type = null; else if (methodDeclaringType.IsValueType) hiddenThisParameter.Type = new ByRefSig(new ValueTypeSig(methodDeclaringType)); @@ -135,7 +135,7 @@ public void UpdateParameterTypes() { theLock.EnterWriteLock(); try { #endif var sig = method.MethodSig; - if (sig == null) { + if (sig is null) { methodSigIndexBase = -1; parameters.Clear(); return; @@ -155,7 +155,7 @@ public void UpdateParameterTypes() { bool UpdateThisParameter_NoLock(MethodSig methodSig) { int newIndex; - if (methodSig == null) + if (methodSig is null) newIndex = -1; else newIndex = methodSig.ImplicitThis ? 1 : 0; @@ -201,7 +201,7 @@ ParamDef FindParamDef_NoLock(Parameter param) { int count = paramDefs.Count; for (int i = 0; i < count; i++) { var paramDef = paramDefs[i]; - if (paramDef != null && paramDef.Sequence == seq) + if (!(paramDef is null) && paramDef.Sequence == seq) return paramDef; } return null; @@ -209,7 +209,7 @@ ParamDef FindParamDef_NoLock(Parameter param) { internal void TypeUpdated(Parameter param) { var sig = method.MethodSig; - if (sig == null) + if (sig is null) return; int index = param.MethodSigIndex; if (index == Parameter.RETURN_TYPE_METHOD_SIG_INDEX) @@ -223,7 +223,7 @@ internal void CreateParamDef(Parameter param) { theLock.EnterWriteLock(); try { #endif var paramDef = FindParamDef_NoLock(param); - if (paramDef != null) + if (!(paramDef is null)) return; if (param.IsHiddenThisParameter) { hiddenThisParamDef = UpdateRowId_NoLock(new ParamDefUser(UTF8String.Empty, ushort.MaxValue, 0)); @@ -239,10 +239,10 @@ internal void CreateParamDef(Parameter param) { ParamDef UpdateRowId_NoLock(ParamDef pd) { var dt = method.DeclaringType; - if (dt == null) + if (dt is null) return pd; var module = dt.Module; - if (module == null) + if (module is null) return pd; return module.UpdateRowId(pd); } @@ -404,7 +404,7 @@ public TypeSig Type { get => typeSig; set { typeSig = value; - if (parameterList != null) + if (!(parameterList is null)) parameterList.TypeUpdated(this); } } @@ -422,7 +422,7 @@ public TypeSig Type { /// /// true if it has a /// - public bool HasParamDef => ParamDef != null; + public bool HasParamDef => !(ParamDef is null); /// /// Gets the name from . If is null, @@ -431,11 +431,11 @@ public TypeSig Type { public string Name { get { var paramDef = ParamDef; - return paramDef == null ? string.Empty : UTF8String.ToSystemStringOrEmpty(paramDef.Name); + return paramDef is null ? string.Empty : UTF8String.ToSystemStringOrEmpty(paramDef.Name); } set { var paramDef = ParamDef; - if (paramDef != null) + if (!(paramDef is null)) paramDef.Name = value; } } @@ -492,7 +492,7 @@ internal Parameter(ParameterList parameterList, int paramIndex, int methodSigInd /// Creates a if it doesn't already exist /// public void CreateParamDef() { - if (parameterList != null) + if (!(parameterList is null)) parameterList.CreateParamDef(this); } diff --git a/src/DotNet/Pdb/Dss/MDEmitter.cs b/src/DotNet/Pdb/Dss/MDEmitter.cs index 984ccc89e..1238debe3 100644 --- a/src/DotNet/Pdb/Dss/MDEmitter.cs +++ b/src/DotNet/Pdb/Dss/MDEmitter.cs @@ -20,11 +20,11 @@ public MDEmitter(Metadata metadata) { tokenToTypeDef = new Dictionary(metadata.TablesHeap.TypeDefTable.Rows); tokenToMethodDef = new Dictionary(metadata.TablesHeap.MethodTable.Rows); foreach (var type in metadata.Module.GetTypes()) { - if (type == null) + if (type is null) continue; tokenToTypeDef.Add(new MDToken(MD.Table.TypeDef, metadata.GetRid(type)).Raw, type); foreach (var method in type.Methods) { - if (method == null) + if (method is null) continue; tokenToMethodDef.Add(new MDToken(MD.Table.Method, metadata.GetRid(method)).Raw, method); } @@ -37,28 +37,28 @@ public override void GetMethodProps(uint mb, uint* pClass, ushort* szMethod, uin var method = tokenToMethodDef[mb]; var row = metadata.TablesHeap.MethodTable[mb & 0x00FFFFFF]; - if (pClass != null) + if (!(pClass is null)) *pClass = new MDToken(MD.Table.TypeDef, metadata.GetRid(method.DeclaringType)).Raw; - if (pdwAttr != null) + if (!(pdwAttr is null)) *pdwAttr = row.Flags; - if (ppvSigBlob != null) + if (!(ppvSigBlob is null)) *ppvSigBlob = IntPtr.Zero; - if (pcbSigBlob != null) + if (!(pcbSigBlob is null)) *pcbSigBlob = 0; - if (pulCodeRVA != null) + if (!(pulCodeRVA is null)) *pulCodeRVA = row.RVA; - if (pdwImplFlags != null) + if (!(pdwImplFlags is null)) *pdwImplFlags = row.ImplFlags; string name = method.Name.String ?? string.Empty; int len = (int)Math.Min((uint)name.Length + 1, cchMethod); - if (szMethod != null) { + if (!(szMethod is null)) { for (int i = 0; i < len - 1; i++, szMethod++) *szMethod = (ushort)name[i]; if (len > 0) *szMethod = 0; } - if (pchMethod != null) + if (!(pchMethod is null)) *pchMethod = (uint)len; } @@ -67,9 +67,9 @@ public override void GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef throw new ArgumentException(); var type = tokenToTypeDef[td]; var row = metadata.TablesHeap.TypeDefTable[td & 0x00FFFFFF]; - if (pdwTypeDefFlags != null) + if (!(pdwTypeDefFlags is null)) *pdwTypeDefFlags = row.Flags; - if (ptkExtends != null) + if (!(ptkExtends is null)) *ptkExtends = row.Extends; CopyTypeName(type.Namespace, type.Name, szTypeDef, cchTypeDef, pchTypeDef); } @@ -79,8 +79,8 @@ public override void GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingC throw new ArgumentException(); var type = tokenToTypeDef[tdNestedClass]; var declType = type.DeclaringType; - if (ptdEnclosingClass != null) { - if (declType == null) + if (!(ptdEnclosingClass is null)) { + if (declType is null) *ptdEnclosingClass = 0; else *ptdEnclosingClass = new MDToken(MD.Table.TypeDef, metadata.GetRid(declType)).Raw; diff --git a/src/DotNet/Pdb/Dss/MetaDataImport.cs b/src/DotNet/Pdb/Dss/MetaDataImport.cs index b41440e7c..1e90e1c7e 100644 --- a/src/DotNet/Pdb/Dss/MetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/MetaDataImport.cs @@ -13,12 +13,12 @@ unsafe abstract class MetaDataImport : IMetaDataImport { public virtual void GetTypeRefProps(uint tr, uint* ptkResolutionScope, ushort* szName, uint cchName, uint* pchName) => throw new NotImplementedException(); protected void CopyTypeName(string typeNamespace, string typeName, ushort* destBuffer, uint destBufferLen, uint* requiredLength) { - if (typeName == null) + if (typeName is null) typeName = string.Empty; - if (typeNamespace == null) + if (typeNamespace is null) typeNamespace = string.Empty; - if (destBuffer != null && destBufferLen > 0) { + if (!(destBuffer is null) && destBufferLen > 0) { uint maxChars = destBufferLen - 1; uint w = 0; if (typeNamespace.Length > 0) { @@ -35,10 +35,10 @@ protected void CopyTypeName(string typeNamespace, string typeName, ushort* destB *destBuffer = 0; } - if (requiredLength != null) { + if (!(requiredLength is null)) { int totalLen = typeNamespace.Length == 0 ? typeName.Length : typeNamespace.Length + 1 + typeName.Length; int copyLen = Math.Min(totalLen, (int)Math.Min(int.MaxValue, destBufferLen == 0 ? 0 : destBufferLen - 1)); - if (destBuffer != null) + if (!(destBuffer is null)) *requiredLength = (uint)copyLen; else *requiredLength = (uint)totalLen; diff --git a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs index 3a4bea139..85b9d236e 100644 --- a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs @@ -16,7 +16,7 @@ public ReaderMetaDataImport(Metadata metadata) { var reader = metadata.BlobStream.CreateReader(); addrToFree = Marshal.AllocHGlobal((int)reader.BytesLeft); blobPtr = (byte*)addrToFree; - if (blobPtr == null) + if (blobPtr is null) throw new OutOfMemoryException(); reader.ReadBytes(blobPtr, (int)reader.BytesLeft); } @@ -29,9 +29,9 @@ public override void GetTypeRefProps(uint tr, uint* ptkResolutionScope, ushort* throw new ArgumentException(); if (!metadata.TablesStream.TryReadTypeRefRow(token.Rid, out var row)) throw new ArgumentException(); - if (ptkResolutionScope != null) + if (!(ptkResolutionScope is null)) *ptkResolutionScope = row.ResolutionScope; - if (szName != null || pchName != null) { + if (!(szName is null) || !(pchName is null)) { var typeNamespace = metadata.StringsStream.ReadNoNull(row.Namespace); var typeName = metadata.StringsStream.ReadNoNull(row.Name); CopyTypeName(typeNamespace, typeName, szName, cchName, pchName); @@ -44,11 +44,11 @@ public override void GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef throw new ArgumentException(); if (!metadata.TablesStream.TryReadTypeDefRow(token.Rid, out var row)) throw new ArgumentException(); - if (pdwTypeDefFlags != null) + if (!(pdwTypeDefFlags is null)) *pdwTypeDefFlags = row.Flags; - if (ptkExtends != null) + if (!(ptkExtends is null)) *ptkExtends = row.Extends; - if (szTypeDef != null || pchTypeDef != null) { + if (!(szTypeDef is null) || !(pchTypeDef is null)) { var typeNamespace = metadata.StringsStream.ReadNoNull(row.Namespace); var typeName = metadata.StringsStream.ReadNoNull(row.Name); CopyTypeName(typeNamespace, typeName, szTypeDef, cchTypeDef, pchTypeDef); @@ -63,9 +63,9 @@ public override void GetSigFromToken(uint mdSig, byte** ppvSig, uint* pcbSig) { throw new ArgumentException(); if (!metadata.BlobStream.TryCreateReader(row.Signature, out var reader)) throw new ArgumentException(); - if (ppvSig != null) + if (!(ppvSig is null)) *ppvSig = blobPtr + (reader.StartOffset - (uint)metadata.BlobStream.StartOffset); - if (pcbSig != null) + if (!(pcbSig is null)) *pcbSig = reader.Length; } diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index af4cd620f..a6c50acf6 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -78,9 +78,9 @@ byte[] SourceCode { public override PdbCustomDebugInfo[] CustomDebugInfos { get { - if (customDebugInfos == null) { + if (customDebugInfos is null) { var sourceCode = SourceCode; - if (sourceCode != null) + if (!(sourceCode is null)) customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; else customDebugInfos = Array2.Empty(); diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs index 0101d28f3..fb333a68f 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs @@ -9,7 +9,7 @@ sealed class SymbolDocumentWriter : ISymbolDocumentWriter { public ISymUnmanagedDocumentWriter SymUnmanagedDocumentWriter => writer; public SymbolDocumentWriter(ISymUnmanagedDocumentWriter writer) => this.writer = writer; public void SetCheckSum(Guid algorithmId, byte[] checkSum) { - if (checkSum != null && checkSum.Length != 0 && algorithmId != Guid.Empty) + if (!(checkSum is null) && checkSum.Length != 0 && algorithmId != Guid.Empty) writer.SetCheckSum(algorithmId, (uint)checkSum.Length, checkSum); } public void SetSource(byte[] source) => writer.SetSource((uint)source.Length, source); diff --git a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs index c0785305e..bc96f6e34 100644 --- a/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolMethodImpl.cs @@ -27,9 +27,9 @@ public override int Token { public override SymbolScope RootScope { get { - if (rootScope == null) { + if (rootScope is null) { method.GetRootScope(out var scope); - Interlocked.CompareExchange(ref rootScope, scope == null ? null : new SymbolScopeImpl(scope, this, null), null); + Interlocked.CompareExchange(ref rootScope, scope is null ? null : new SymbolScopeImpl(scope, this, null), null); } return rootScope; } @@ -38,7 +38,7 @@ public override SymbolScope RootScope { public override IList SequencePoints { get { - if (sequencePoints == null) { + if (sequencePoints is null) { method.GetSequencePointCount(out uint seqPointCount); var seqPoints = new SymbolSequencePoint[seqPointCount]; @@ -70,7 +70,7 @@ public override IList SequencePoints { public int AsyncKickoffMethod { get { - if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) + if (asyncMethod is null || !asyncMethod.IsAsyncMethod()) return 0; return (int)asyncMethod.GetKickoffMethod(); } @@ -78,7 +78,7 @@ public int AsyncKickoffMethod { public uint? AsyncCatchHandlerILOffset { get { - if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) + if (asyncMethod is null || !asyncMethod.IsAsyncMethod()) return null; if (!asyncMethod.HasCatchHandlerILOffset()) return null; @@ -88,9 +88,9 @@ public uint? AsyncCatchHandlerILOffset { public IList AsyncStepInfos { get { - if (asyncMethod == null || !asyncMethod.IsAsyncMethod()) + if (asyncMethod is null || !asyncMethod.IsAsyncMethod()) return null; - if (asyncStepInfos == null) { + if (asyncStepInfos is null) { var stepInfoCount = asyncMethod.GetAsyncStepInfoCount(); var yieldOffsets = new uint[stepInfoCount]; var breakpointOffsets = new uint[stepInfoCount]; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index e0c6cbb3d..41e46a04d 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -38,7 +38,7 @@ public override int UserEntryPoint { public override IList Documents { get { - if (documents == null) { + if (documents is null) { reader.GetDocuments(0, out uint numDocs, null); var unDocs = new ISymUnmanagedDocument[numDocs]; reader.GetDocuments((uint)unDocs.Length, out numDocs, unDocs); @@ -59,12 +59,12 @@ public override SymbolMethod GetMethod(MethodDef method, int version) { if (hr == E_FAIL) return null; Marshal.ThrowExceptionForHR(hr); - return unMethod == null ? null : new SymbolMethodImpl(this, unMethod); + return unMethod is null ? null : new SymbolMethodImpl(this, unMethod); } internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { var asyncMethod = PseudoCustomDebugInfoFactory.TryCreateAsyncMethod(method.Module, method, body, symMethod.AsyncKickoffMethod, symMethod.AsyncStepInfos, symMethod.AsyncCatchHandlerILOffset); - if (asyncMethod != null) + if (!(asyncMethod is null)) result.Add(asyncMethod); const string CDI_NAME = "MD2"; @@ -83,10 +83,10 @@ public override void GetCustomDebugInfos(int token, GenericParamContext gpContex void GetCustomDebugInfos_ModuleDef(IList result) { var sourceLinkData = GetSourceLinkData(); - if (sourceLinkData != null) + if (!(sourceLinkData is null)) result.Add(new PdbSourceLinkCustomDebugInfo(sourceLinkData)); var sourceServerData = GetSourceServerData(); - if (sourceServerData != null) + if (!(sourceServerData is null)) result.Add(new PdbSourceServerCustomDebugInfo(sourceServerData)); } @@ -135,7 +135,7 @@ public override void Dispose() { void Dispose(bool disposing) { (reader as ISymUnmanagedDispose)?.Destroy(); var o = objsToKeepAlive; - if (o != null) { + if (!(o is null)) { foreach (var obj in o) (obj as IDisposable)?.Dispose(); } diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 1d06b94b2..0d98f9bc2 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -51,16 +51,16 @@ public static SymbolReader Create(PdbReaderContext pdbContext, MD.Metadata metad DataReaderIStream comPdbStream = null; bool error = true; try { - if (pdbStream == null) + if (pdbStream is null) return null; var debugDir = pdbContext.CodeViewDebugDirectory; - if (debugDir == null) + if (debugDir is null) return null; if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; unmanagedReader = CreateSymUnmanagedReader(pdbContext.Options); - if (unmanagedReader == null) + if (unmanagedReader is null) return null; mdImporter = new ReaderMetaDataImport(metadata); diff --git a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs index 3992aab41..ffbdc5816 100644 --- a/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolScopeImpl.cs @@ -36,7 +36,7 @@ public override int EndOffset { public override IList Children { get { - if (children == null) { + if (children is null) { scope.GetChildren(0, out uint numScopes, null); var unScopes = new ISymUnmanagedScope[numScopes]; scope.GetChildren((uint)unScopes.Length, out numScopes, unScopes); @@ -52,7 +52,7 @@ public override IList Children { public override IList Locals { get { - if (locals == null) { + if (locals is null) { scope.GetLocals(0, out uint numVars, null); var unVars = new ISymUnmanagedVariable[numVars]; scope.GetLocals((uint)unVars.Length, out numVars, unVars); @@ -68,7 +68,7 @@ public override IList Locals { public override IList Namespaces { get { - if (namespaces == null) { + if (namespaces is null) { scope.GetNamespaces(0, out uint numNss, null); var unNss = new ISymUnmanagedNamespace[numNss]; scope.GetNamespaces((uint)unNss.Length, out numNss, unNss); @@ -87,7 +87,7 @@ public override IList Namespaces { public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { var scope2 = scope as ISymUnmanagedScope2; - if (scope2 == null) + if (scope2 is null) return Array2.Empty(); scope2.GetConstants(0, out uint numCs, null); if (numCs == 0) diff --git a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index bbc24e2de..a480a3b13 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -19,7 +19,7 @@ sealed class SymbolWriterImpl : SymbolWriter { bool closeCalled; public override bool IsDeterministic => isDeterministic; - public override bool SupportsAsyncMethods => asyncMethodWriter != null; + public override bool SupportsAsyncMethods => !(asyncMethodWriter is null); public SymbolWriterImpl(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream, PdbWriterOptions options, bool ownsStream) { this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); @@ -41,7 +41,7 @@ public override void Close() { public override void CloseScope(int endOffset) => writer.CloseScope((uint)endOffset); public override void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod) { - if (asyncMethodWriter == null) + if (asyncMethodWriter is null) throw new InvalidOperationException(); if (yieldOffsets.Length != breakpointOffset.Length || yieldOffsets.Length != breakpointMethod.Length) throw new ArgumentException(); @@ -49,7 +49,7 @@ public override void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointO } public override void DefineCatchHandlerILOffset(uint catchHandlerOffset) { - if (asyncMethodWriter == null) + if (asyncMethodWriter is null) throw new InvalidOperationException(); asyncMethodWriter.DefineCatchHandlerILOffset(catchHandlerOffset); } @@ -58,18 +58,18 @@ public override void DefineCatchHandlerILOffset(uint catchHandlerOffset) { public override ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) { writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out var unDocWriter); - return unDocWriter == null ? null : new SymbolDocumentWriter(unDocWriter); + return unDocWriter is null ? null : new SymbolDocumentWriter(unDocWriter); } public override void DefineKickoffMethod(uint kickoffMethod) { - if (asyncMethodWriter == null) + if (asyncMethodWriter is null) throw new InvalidOperationException(); asyncMethodWriter.DefineKickoffMethod(kickoffMethod); } public override void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) { var doc = document as SymbolDocumentWriter; - if (doc == null) + if (doc is null) throw new ArgumentException("document isn't a non-null SymbolDocumentWriter instance"); writer.DefineSequencePoints(doc.SymUnmanagedDocumentWriter, arraySize, offsets, lines, columns, endLines, endColumns); } @@ -137,7 +137,7 @@ public override void Initialize(Metadata metadata) { } public override unsafe void SetSourceServerData(byte[] data) { - if (data == null) + if (data is null) return; if (writer is ISymUnmanagedWriter8 writer8) { fixed (void* p = data) @@ -146,7 +146,7 @@ public override unsafe void SetSourceServerData(byte[] data) { } public override unsafe void SetSourceLinkData(byte[] data) { - if (data == null) + if (data is null) return; if (writer is ISymUnmanagedWriter8 writer8) { fixed (void* p = data) diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index b8b1c2e6b..3c0de5f53 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -26,9 +26,9 @@ sealed class DbiDocument : SymbolDocument { public override PdbCustomDebugInfo[] CustomDebugInfos { get { - if (customDebugInfos == null) { + if (customDebugInfos is null) { var sourceCode = SourceCode; - if (sourceCode != null) + if (!(sourceCode is null)) customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; else customDebugInfos = Array2.Empty(); diff --git a/src/DotNet/Pdb/Managed/DbiFunction.cs b/src/DotNet/Pdb/Managed/DbiFunction.cs index 26d31d39d..0e543e0e2 100644 --- a/src/DotNet/Pdb/Managed/DbiFunction.cs +++ b/src/DotNet/Pdb/Managed/DbiFunction.cs @@ -58,7 +58,7 @@ void FixOffsets(RecursionCounter counter, DbiScope scope) { public override IList SequencePoints { get { var l = lines; - if (l == null) + if (l is null) return Array2.Empty(); return l; } @@ -68,7 +68,7 @@ public override IList SequencePoints { public int AsyncKickoffMethod { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data == null || data.Length < 4) + if (data is null || data.Length < 4) return 0; return BitConverter.ToInt32(data, 0); } @@ -77,7 +77,7 @@ public int AsyncKickoffMethod { public uint? AsyncCatchHandlerILOffset { get { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data == null || data.Length < 8) + if (data is null || data.Length < 8) return null; uint token = BitConverter.ToUInt32(data, 4); return token == uint.MaxValue ? (uint?)null : token; @@ -86,7 +86,7 @@ public uint? AsyncCatchHandlerILOffset { public IList AsyncStepInfos { get { - if (asyncStepInfos == null) + if (asyncStepInfos is null) asyncStepInfos = CreateSymbolAsyncStepInfos(); return asyncStepInfos; } @@ -95,7 +95,7 @@ public IList AsyncStepInfos { SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data == null || data.Length < 12) + if (data is null || data.Length < 12) return Array2.Empty(); int pos = 8; int count = BitConverter.ToInt32(data, pos); diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index a577e9425..2070f6b48 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -154,16 +154,16 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, ref var flags = reader.ReadUInt16(); reader.Position += 4; - if (funcs[found].Lines == null) { + if (funcs[found].Lines is null) { while (found > 0) { var prevFunc = funcs[found - 1]; - if (prevFunc != null || prevFunc.Address != address) + if (!(prevFunc is null) || prevFunc.Address != address) break; found--; } } else { - while (found < funcs.Length - 1 && funcs[found] != null) { + while (found < funcs.Length - 1 && !(funcs[found] is null)) { var nextFunc = funcs[found + 1]; if (nextFunc.Address != address) break; @@ -171,7 +171,7 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, ref } } var func = funcs[found]; - if (func.Lines != null) + if (!(func.Lines is null)) return; func.Lines = new List(); diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 00ef8f5ca..7e8b99a28 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -110,11 +110,11 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) } reader.Position += 4;// typeIndex or 0 name = ReadUnicodeString(ref reader, end); - Debug.Assert(name != null); - if (name == null) + Debug.Assert(!(name is null)); + if (name is null) break; var data = reader.ReadBytes((int)(end - reader.Position)); - if (oemInfos == null) + if (oemInfos is null) oemInfos = new List(1); oemInfos.Add(new OemInfo(name, data)); break; @@ -124,7 +124,7 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) if (!NumericReader.TryReadNumeric(ref reader, end, out value)) break; name = PdbReader.ReadCString(ref reader); - if (constants == null) + if (constants is null) constants = new List(); constants.Add(new ConstantInfo(name, signatureToken, value)); break; @@ -135,7 +135,7 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) } reader.Position = end; - if (child != null) { + if (!(child is null)) { child.Read(counter, ref reader, childEnd.Value); childrenList.Add(child); child = null; @@ -170,15 +170,15 @@ static bool ReadAndCompareBytes(ref DataReader reader, uint end, byte[] bytes) { } public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { - if (constants == null) + if (constants is null) return Array2.Empty(); var res = new PdbConstant[constants.Count]; for (int i = 0; i < res.Length; i++) { var info = constants[i]; TypeSig signature; var saSig = module.ResolveToken(info.SignatureToken, gpContext) as StandAloneSig; - var fieldSig = saSig == null ? null : saSig.Signature as FieldSig; - if (fieldSig == null) { + var fieldSig = saSig is null ? null : saSig.Signature as FieldSig; + if (fieldSig is null) { Debug.Fail("Constant without a signature"); signature = null; } @@ -190,7 +190,7 @@ public override IList GetConstants(ModuleDef module, GenericParamCo } internal byte[] GetSymAttribute(string name) { - if (oemInfos == null) + if (oemInfos is null) return null; foreach (var info in oemInfos) { if (info.Name == name) diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 6b5ec3de6..ea4a9e899 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -326,7 +326,7 @@ public override SymbolMethod GetMethod(MethodDef method, int version) { public override IList Documents { get { - if (documentsResult == null) { + if (documentsResult is null) { var docs = new SymbolDocument[documents.Count]; int i = 0; foreach (var kv in documents) @@ -343,11 +343,11 @@ public override IList Documents { internal void GetCustomDebugInfos(DbiFunction symMethod, MethodDef method, CilBody body, IList result) { const string CDI_NAME = "MD2"; var asyncMethod = PseudoCustomDebugInfoFactory.TryCreateAsyncMethod(method.Module, method, body, symMethod.AsyncKickoffMethod, symMethod.AsyncStepInfos, symMethod.AsyncCatchHandlerILOffset); - if (asyncMethod != null) + if (!(asyncMethod is null)) result.Add(asyncMethod); var cdiData = symMethod.Root.GetSymAttribute(CDI_NAME); - if (cdiData == null) + if (cdiData is null) return; PdbCustomDebugInfoReader.Read(method, body, result, cdiData); } @@ -358,9 +358,9 @@ public override void GetCustomDebugInfos(int token, GenericParamContext gpContex } void GetCustomDebugInfos_ModuleDef(IList result) { - if (sourcelinkData != null) + if (!(sourcelinkData is null)) result.Add(new PdbSourceLinkCustomDebugInfo(sourcelinkData)); - if (srcsrvData != null) + if (!(srcsrvData is null)) result.Add(new PdbSourceServerCustomDebugInfo(srcsrvData)); } } diff --git a/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs index ec3e8137e..8962eb631 100644 --- a/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/Managed/SymbolReaderFactory.cs @@ -16,11 +16,11 @@ static class SymbolReaderFactory { /// PDB file stream which is now owned by this method /// A new instance or null. public static SymbolReader Create(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { - if (pdbStream == null) + if (pdbStream is null) return null; try { var debugDir = pdbContext.CodeViewDebugDirectory; - if (debugDir == null) + if (debugDir is null) return null; if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) return null; diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs index 4b6da6836..be0d76657 100644 --- a/src/DotNet/Pdb/PdbConstant.cs +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -71,7 +71,7 @@ public PdbConstant(string name, TypeSig type, object value) { /// public override string ToString() { var type = Type; - return (type == null ? "" : type.ToString()) + " " + Name + " = " + (Value == null ? "null" : Value.ToString() + " (" + Value.GetType().FullName + ")"); + return (type is null ? "" : type.ToString()) + " " + Name + " = " + (Value is null ? "null" : Value.ToString() + " (" + Value.GetType().FullName + ")"); } } } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 73cf8e404..79a973783 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -279,7 +279,7 @@ public struct StateMachineHoistedLocalScope { /// /// true if it's a syntesized local ( and are both null) /// - public bool IsSynthesizedLocal => Start == null && End == null; + public bool IsSynthesizedLocal => Start is null && End is null; /// /// The instruction of the first operation in the scope. Can be null if it's a synthesized local @@ -421,7 +421,7 @@ public sealed class PdbDynamicLocal { public string Name { get { var n = name; - if (n != null) + if (!(n is null)) return n; return local?.Name; } @@ -431,12 +431,12 @@ public string Name { /// /// true if it's a constant and not a variable ( is null) /// - public bool IsConstant => Local == null; + public bool IsConstant => Local is null; /// /// true if it's a variable ( is not null) /// - public bool IsVariable => Local != null; + public bool IsVariable => !(Local is null); /// /// Gets/sets the local. Could be null if there's no local (it's a 'const' local). @@ -562,7 +562,7 @@ public sealed class PdbTupleElementNames { public string Name { get { var n = name; - if (n != null) + if (!(n is null)) return n; return local?.Name; } @@ -580,12 +580,12 @@ public Local Local { /// /// true if it's a constant. Constants have a scope ( and ) /// - public bool IsConstant => local == null; + public bool IsConstant => local is null; /// /// true if it's a variable. Variables don't have a scope ( and ) /// - public bool IsVariable => local != null; + public bool IsVariable => !(local is null); /// /// Gets/sets the start of the scope or null. Only constants have a scope. diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index a6f663b5d..b38fe311c 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -67,7 +67,7 @@ public PdbDocument(SymbolDocument symDoc) : this(symDoc, partial: false) { } PdbDocument(SymbolDocument symDoc, bool partial) { - if (symDoc == null) + if (symDoc is null) throw new ArgumentNullException(nameof(symDoc)); Url = symDoc.URL; if (!partial) @@ -112,7 +112,7 @@ public PdbDocument(string url, Guid language, Guid languageVendor, Guid document /// public override bool Equals(object obj) { var other = obj as PdbDocument; - if (other == null) + if (other is null) return false; return StringComparer.OrdinalIgnoreCase.Equals(Url ?? string.Empty, other.Url ?? string.Empty); } diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs index dbf505628..de6462022 100644 --- a/src/DotNet/Pdb/PdbReaderContext.cs +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -9,7 +9,7 @@ readonly struct PdbReaderContext { readonly IPEImage peImage; readonly ImageDebugDirectory codeViewDebugDir; - public bool HasDebugInfo => codeViewDebugDir != null; + public bool HasDebugInfo => !(codeViewDebugDir is null); public ImageDebugDirectory CodeViewDebugDirectory => codeViewDebugDir; public PdbReaderOptions Options { get; } @@ -48,11 +48,11 @@ public bool TryGetCodeViewData(out Guid guid, out uint age, out string pdbFilena guid = reader.ReadGuid(); age = reader.ReadUInt32(); pdbFilename = reader.TryReadZeroTerminatedUtf8String(); - return pdbFilename != null; + return !(pdbFilename is null); } DataReader GetCodeViewDataReader() { - if (codeViewDebugDir == null) + if (codeViewDebugDir is null) return default; return CreateReader(codeViewDebugDir.AddressOfRawData, codeViewDebugDir.SizeOfData); } diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index ed26bb3ea..daad8b8c1 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -74,7 +74,7 @@ public bool HasDocuments { /// Module /// PDB file kind public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { - if (module == null) + if (module is null) throw new ArgumentNullException(nameof(module)); compiler = CalculateCompiler(module); PdbFileKind = pdbFileKind; @@ -87,7 +87,7 @@ public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { /// A instance /// Owner module public PdbState(SymbolReader reader, ModuleDefMD module) { - if (module == null) + if (module is null) throw new ArgumentNullException(nameof(module)); this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); reader.Initialize(module); @@ -196,11 +196,11 @@ public List RemoveAllDocuments(bool returnDocs) { internal Compiler Compiler => compiler; internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { - if (reader == null) + if (reader is null) return; var method = reader.GetMethod(ownerMethod, 1); - if (method != null) { + if (!(method is null)) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); @@ -209,16 +209,16 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci } internal void InitializeCustomDebugInfos(MethodDef ownerMethod, CilBody body, IList customDebugInfos) { - if (reader == null) + if (reader is null) return; var method = reader.GetMethod(ownerMethod, 1); - if (method != null) + if (!(method is null)) method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); } static Compiler CalculateCompiler(ModuleDef module) { - if (module == null) + if (module is null) return Compiler.Other; foreach (var asmRef in module.GetAssemblyRefs()) { @@ -231,7 +231,7 @@ static Compiler CalculateCompiler(ModuleDef module) { // The VB runtime can also be embedded, and if so, it seems that "Microsoft.VisualBasic.Embedded" // attribute is added to the assembly's custom attributes. var asm = module.Assembly; - if (asm != null && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) + if (!(asm is null) && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) return Compiler.VisualBasic; #endif @@ -248,7 +248,7 @@ void AddSequencePoints(CilBody body, SymbolMethod method) { for (int i = 0; i < count; i++) { var sp = sequencePoints[i]; var instr = GetInstruction(body.Instructions, sp.Offset, ref instrIndex); - if (instr == null) + if (instr is null) continue; var seqPoint = new SequencePoint() { Document = Add_NoLock(sp.Document), @@ -269,7 +269,7 @@ struct CreateScopeState { } PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, SymbolScope symScope) { - if (symScope == null) + if (symScope is null) return null; // Don't use recursive calls @@ -319,7 +319,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody for (int i = 0; i < constants.Count; i++) { var constant = constants[i]; var type = constant.Type.RemovePinnedAndModifiers(); - if (type != null) { + if (!(type is null)) { // Fix a few values since they're stored as some other type in the PDB switch (type.ElementType) { case ElementType.Boolean: @@ -360,7 +360,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody // "" is stored as null, and null is stored as (int)0 if (constant.Value is int && (int)constant.Value == 0) constant.Value = null; - else if (constant.Value == null) + else if (constant.Value is null) constant.Value = string.Empty; } else @@ -382,7 +382,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody case ElementType.Var: case ElementType.MVar: var gp = ((GenericSig)type).GenericParam; - if (gp != null) { + if (!(gp is null)) { if (gp.HasNotNullableValueTypeConstraint) break; if (gp.HasReferenceTypeConstraint) diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index 18c036b02..e42486221 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -102,7 +102,7 @@ public void Read(uint imports, IList result) { import = null; break; } - if (import != null) + if (!(import is null)) result.Add(import); } Debug.Assert(reader.Position == reader.Length); @@ -114,13 +114,13 @@ ITypeDefOrRef TryReadType(uint codedToken) { if (!b) return null; var type = module.ResolveToken(token) as ITypeDefOrRef; - Debug.Assert(type != null); + Debug.Assert(!(type is null)); return type; } AssemblyRef TryReadAssemblyRef(uint rid) { var asmRef = module.ResolveToken(0x23000000 + rid) as AssemblyRef; - Debug.Assert(asmRef != null); + Debug.Assert(!(asmRef is null)); return asmRef; } diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index ac1880745..29c30d2d2 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -23,7 +23,7 @@ public static void Write(IWriterError helper, Metadata systemMetadata, DataWrite } uint WriteUTF8(string s) { - if (s == null) { + if (s is null) { helper.Error("String is null"); s = string.Empty; } @@ -101,7 +101,7 @@ void Write(DataWriter writer, IList imports) { } uint GetTypeDefOrRefEncodedToken(ITypeDefOrRef tdr) { - if (tdr == null) { + if (tdr is null) { helper.Error("ITypeDefOrRef is null"); return 0; } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index dcf32f581..dccf20ed1 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -190,7 +190,7 @@ bool ReadCore(out TypeSig type, out object value) { } } } - if (value == null && reader.Position != reader.Length) + if (value is null && reader.Position != reader.Length) value = reader.ReadRemainingBytes(); res = true; break; @@ -281,7 +281,7 @@ ITypeDefOrRef ReadTypeDefOrRef() { ISignatureReaderHelper helper = module; var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); var corType = module.CorLibTypes.GetCorLibTypeSig(tdr); - if (corType != null) + if (!(corType is null)) return corType.TypeDefOrRef; return tdr; } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index ef2d7f952..744989b94 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -21,7 +21,7 @@ public static void Write(IWriterError helper, Metadata systemMetadata, DataWrite void Write(DataWriter writer, TypeSig type, object value) { for (; ; type = type.Next) { - if (type == null) + if (type is null) return; var et = type.ElementType; @@ -59,7 +59,7 @@ void Write(DataWriter writer, TypeSig type, object value) { return; case ElementType.String: - if (value == null) + if (value is null) writer.WriteByte((byte)0xFF); else if (value is string) writer.WriteBytes(Encoding.Unicode.GetBytes((string)value)); @@ -78,7 +78,7 @@ void Write(DataWriter writer, TypeSig type, object value) { case ElementType.ValueType: var tdr = ((ValueTypeSig)type).TypeDefOrRef; var td = tdr.ResolveTypeDef(); - if (td == null) + if (td is null) helper.Error($"Couldn't resolve type 0x{tdr?.MDToken.Raw ?? 0:X8}"); else if (td.IsEnum) { var underlyingType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers(); @@ -134,7 +134,7 @@ void Write(DataWriter writer, TypeSig type, object value) { if (!valueWritten) { if (value is byte[]) writer.WriteBytes((byte[])value); - else if (value != null) { + else if (!(value is null)) { helper.Error("Unsupported constant: " + value.GetType().FullName); return; } @@ -146,7 +146,7 @@ void Write(DataWriter writer, TypeSig type, object value) { WriteTypeDefOrRef(writer, ((ClassSig)type).TypeDefOrRef); if (value is byte[]) writer.WriteBytes((byte[])value); - else if (value != null) + else if (!(value is null)) helper.Error("Expected a null constant"); return; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index 78b41f555..b0ae65488 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -65,7 +65,7 @@ PdbCustomDebugInfo Read(Guid kind) { } PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { - if (bodyOpt == null) + if (bodyOpt is null) return null; uint catchHandlerOffset = reader.ReadUInt32() - 1; Instruction catchHandler; @@ -73,35 +73,35 @@ PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { catchHandler = null; else { catchHandler = GetInstruction(catchHandlerOffset); - Debug.Assert(catchHandler != null); - if (catchHandler == null) + Debug.Assert(!(catchHandler is null)); + if (catchHandler is null) return null; } var asyncInfo = new PdbAsyncMethodSteppingInformationCustomDebugInfo(); asyncInfo.CatchHandler = catchHandler; while (reader.Position < reader.Length) { var yieldInstr = GetInstruction(reader.ReadUInt32()); - Debug.Assert(yieldInstr != null); - if (yieldInstr == null) + Debug.Assert(!(yieldInstr is null)); + if (yieldInstr is null) return null; uint resumeOffset = reader.ReadUInt32(); var moveNextRid = reader.ReadCompressedUInt32(); var moveNextToken = new MDToken(Table.Method, moveNextRid); MethodDef moveNextMethod; Instruction resumeInstr; - if (gpContext.Method != null && moveNextToken == gpContext.Method.MDToken) { + if (!(gpContext.Method is null) && moveNextToken == gpContext.Method.MDToken) { moveNextMethod = gpContext.Method; resumeInstr = GetInstruction(resumeOffset); } else { moveNextMethod = module.ResolveToken(moveNextToken, gpContext) as MethodDef; - Debug.Assert(moveNextMethod != null); - if (moveNextMethod == null) + Debug.Assert(!(moveNextMethod is null)); + if (moveNextMethod is null) return null; resumeInstr = GetInstruction(moveNextMethod, resumeOffset); } - Debug.Assert(resumeInstr != null); - if (resumeInstr == null) + Debug.Assert(!(resumeInstr is null)); + if (resumeInstr is null) return null; asyncInfo.AsyncStepInfos.Add(new PdbAsyncStepInfo(yieldInstr, moveNextMethod, resumeInstr)); } @@ -139,7 +139,7 @@ PdbCustomDebugInfo ReadEncLocalSlotMap(long recPosEnd) { PdbCustomDebugInfo ReadSourceLink() => new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { - if (bodyOpt == null) + if (bodyOpt is null) return null; int count = (int)(reader.Length / 8); var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); @@ -151,8 +151,8 @@ PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { else { var start = GetInstruction(startOffset); var end = GetInstruction(startOffset + length); - Debug.Assert(start != null); - if (start == null) + Debug.Assert(!(start is null)); + if (start is null) return null; smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); } @@ -192,10 +192,10 @@ Instruction GetInstruction(uint offset) { } static Instruction GetInstruction(MethodDef method, uint offset) { - if (method == null) + if (method is null) return null; var body = method.Body; - if (body == null) + if (body is null) return null; var instructions = body.Instructions; int lo = 0, hi = instructions.Count - 1; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 63700cbae..daf959bec 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -110,7 +110,7 @@ void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustom } else { var startInstr = scope.Start; - if (startInstr == null) { + if (startInstr is null) { helper.Error("Instruction is null"); return; } @@ -128,7 +128,7 @@ void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustom void WriteEditAndContinueLocalSlotMap(PdbEditAndContinueLocalSlotMapCustomDebugInfo cdi) { var d = cdi.Data; - if (d == null) { + if (d is null) { helper.Error("Data blob is null"); return; } @@ -137,7 +137,7 @@ void WriteEditAndContinueLocalSlotMap(PdbEditAndContinueLocalSlotMapCustomDebugI void WriteEditAndContinueLambdaMap(PdbEditAndContinueLambdaMapCustomDebugInfo cdi) { var d = cdi.Data; - if (d == null) { + if (d is null) { helper.Error("Data blob is null"); return; } @@ -146,7 +146,7 @@ void WriteEditAndContinueLambdaMap(PdbEditAndContinueLambdaMapCustomDebugInfo cd void WriteUnknown(PdbUnknownCustomDebugInfo cdi) { var d = cdi.Data; - if (d == null) { + if (d is null) { helper.Error("Data blob is null"); return; } @@ -158,7 +158,7 @@ void WriteTupleElementNames(PortablePdbTupleElementNamesCustomDebugInfo cdi) { int count = cdiNames.Count; for (int i = 0; i < count; i++) { var name = cdiNames[i]; - if (name == null) { + if (name is null) { helper.Error("Tuple name is null"); return; } @@ -168,7 +168,7 @@ void WriteTupleElementNames(PortablePdbTupleElementNamesCustomDebugInfo cdi) { void WriteDefaultNamespace(PdbDefaultNamespaceCustomDebugInfo cdi) { var ns = cdi.Namespace; - if (ns == null) { + if (ns is null) { helper.Error("Default namespace is null"); return; } @@ -194,7 +194,7 @@ static byte ToByte(bool[] flags, int index) { void WriteEmbeddedSource(PdbEmbeddedSourceCustomDebugInfo cdi) { var d = cdi.SourceCodeBlob; - if (d == null) { + if (d is null) { helper.Error("Source code blob is null"); return; } @@ -203,7 +203,7 @@ void WriteEmbeddedSource(PdbEmbeddedSourceCustomDebugInfo cdi) { void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { var d = cdi.FileBlob; - if (d == null) { + if (d is null) { helper.Error("Source link blob is null"); return; } @@ -217,7 +217,7 @@ void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { } uint catchHandlerOffset; - if (cdi.CatchHandlerInstruction == null) + if (cdi.CatchHandlerInstruction is null) catchHandlerOffset = 0; else catchHandlerOffset = methodContext.GetOffset(cdi.CatchHandlerInstruction) + 1; @@ -227,15 +227,15 @@ void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { int count = cdiStepInfos.Count; for (int i = 0; i < count; i++) { var info = cdiStepInfos[i]; - if (info.YieldInstruction == null) { + if (info.YieldInstruction is null) { helper.Error("YieldInstruction is null"); return; } - if (info.BreakpointMethod == null) { + if (info.BreakpointMethod is null) { helper.Error("BreakpointMethod is null"); return; } - if (info.BreakpointInstruction == null) { + if (info.BreakpointInstruction is null) { helper.Error("BreakpointInstruction is null"); return; } @@ -254,7 +254,7 @@ void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { uint GetOffsetSlow(MethodDef method, Instruction instr) { var body = method.Body; - if (body == null) { + if (body is null) { helper.Error("Method has no body"); return uint.MaxValue; } diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index e5a428a18..d4b893305 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -54,7 +54,7 @@ static Guid GetLanguageVendor(Guid language) { } SymbolDocument[] ReadDocuments() { - Debug.Assert(module != null); + Debug.Assert(!(module is null)); var docTbl = pdbMetadata.TablesStream.DocumentTable; var docs = new SymbolDocument[docTbl.Rows]; var nameReader = new DocumentNameReader(pdbMetadata.BlobStream); @@ -151,8 +151,8 @@ SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { else { // SequencePointRecord - Debug.Assert(document != null); - if (document == null) + Debug.Assert(!(document is null)); + if (document is null) return null; var symSeqPoint = new SymbolSequencePoint { @@ -233,15 +233,15 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { stack.RemoveAt(stack.Count - 1); } - Debug.Assert(parent != null || rootScopeOrNull == null); + Debug.Assert(!(parent is null) || rootScopeOrNull is null); custInfos.Clear(); GetCustomDebugInfos(token, gpContext, custInfos); var customDebugInfos = custInfos.Count == 0 ? Array2.Empty() : custInfos.ToArray(); var scope = new SymbolScopeImpl(this, parent, (int)startOffset, (int)endOffset, customDebugInfos); - if (rootScopeOrNull == null) + if (rootScopeOrNull is null) rootScopeOrNull = scope; stack.Add(scope); - if (parent != null) + if (!(parent is null)) parent.childrenList.Add(scope); scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext); @@ -283,9 +283,9 @@ PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReade return null; var scope = new PdbImportScope(); GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos); - if (result == null) + if (result is null) result = scope; - if (prevScope != null) + if (!(prevScope is null)) prevScope.Parent = scope; importScopeBlobReader.Read(row.Imports, scope.Imports); prevScope = scope; @@ -349,16 +349,16 @@ void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEn internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { Debug.Assert(method.Module == module); GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out var asyncStepInfo); - if (asyncStepInfo != null) { + if (!(asyncStepInfo is null)) { var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); - Debug.Assert(asyncMethod != null); - if (asyncMethod != null) + Debug.Assert(!(asyncMethod is null)); + if (!(asyncMethod is null)) result.Add(asyncMethod); } else if (symMethod.KickoffMethod != 0) { var iteratorMethod = TryCreateIteratorMethod(module, symMethod.KickoffMethod); - Debug.Assert(iteratorMethod != null); - if (iteratorMethod != null) + Debug.Assert(!(iteratorMethod is null)); + if (!(iteratorMethod is null)) result.Add(iteratorMethod); } } @@ -387,7 +387,7 @@ PdbIteratorMethodCustomDebugInfo TryCreateIteratorMethod(ModuleDef module, int i public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { GetCustomDebugInfos(token, gpContext, result, null, null, out var asyncStepInfo); - Debug.Assert(asyncStepInfo == null); + Debug.Assert(asyncStepInfo is null); } void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result, MethodDef methodOpt, CilBody bodyOpt, out PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo) { @@ -404,14 +404,14 @@ void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList GetConstants(ModuleDef module, GenericParamContext gpContext) { if (constantList >= constantListEnd) return Array2.Empty(); - Debug.Assert(constantsMetadata != null); + Debug.Assert(!(constantsMetadata is null)); var res = new PdbConstant[constantListEnd - constantList]; int w = 0; diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index 786d7ba29..686d425b8 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -66,12 +66,12 @@ static SymbolReader CreateCore(PdbReaderContext pdbContext, Metadata metadata, D if (!pdbContext.HasDebugInfo) return null; - if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && pdbStream != null && IsWindowsPdb(pdbStream.CreateReader())) + if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && !(pdbStream is null) && IsWindowsPdb(pdbStream.CreateReader())) symReader = Dss.SymbolReaderWriterFactory.Create(pdbContext, metadata, pdbStream); else symReader = CreateManaged(pdbContext, metadata, pdbStream); - if (symReader != null) { + if (!(symReader is null)) { error = false; return symReader; } @@ -105,7 +105,7 @@ static SymbolReader CreateManaged(PdbReaderContext pdbContext, Metadata metadata try { // Embedded PDBs have priority var embeddedReader = TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); - if (embeddedReader != null) { + if (!(embeddedReader is null)) { pdbStream?.Dispose(); return embeddedReader; } @@ -119,7 +119,7 @@ static SymbolReader CreateManaged(PdbReaderContext pdbContext, Metadata metadata } static SymbolReader CreateManagedCore(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { - if (pdbStream == null) + if (pdbStream is null) return null; try { var reader = pdbStream.CreateReader(); diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index 5855a28c7..e0b6dae90 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -81,11 +81,11 @@ void Read(IList result) { if (recVersion == CustomDebugInfoConstants.RecordVersion) { ulong recPosEnd = (ulong)reader.Position - 8 + (uint)recSize - (uint)alignmentSize; var cdi = ReadRecord(recKind, recPosEnd); - Debug.Assert(cdi != null); + Debug.Assert(!(cdi is null)); Debug.Assert(reader.Position <= recPosEnd); if (reader.Position > recPosEnd) return; - if (cdi != null) { + if (!(cdi is null)) { Debug.Assert(cdi.Kind == recKind); result.Add(cdi); } @@ -113,18 +113,18 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { case PdbCustomDebugInfoKind.ForwardMethodInfo: method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef; - if (method == null) + if (method is null) return null; return new PdbForwardMethodInfoCustomDebugInfo(method); case PdbCustomDebugInfoKind.ForwardModuleInfo: method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef; - if (method == null) + if (method is null) return null; return new PdbForwardModuleInfoCustomDebugInfo(method); case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: - if (bodyOpt == null) + if (bodyOpt is null) return null; count = reader.ReadInt32(); if (count < 0) @@ -143,7 +143,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { else { var start = GetInstruction(startOffset); var end = GetInstruction(endOffset + 1); - if (start == null) + if (start is null) return null; smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); } @@ -152,15 +152,15 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { case PdbCustomDebugInfoKind.StateMachineTypeName: var name = ReadUnicodeZ(recPosEnd, needZeroChar: true); - if (name == null) + if (name is null) return null; var type = GetNestedType(name); - if (type == null) + if (type is null) return null; return new PdbStateMachineTypeNameCustomDebugInfo(type); case PdbCustomDebugInfoKind.DynamicLocals: - if (bodyOpt == null) + if (bodyOpt is null) return null; count = reader.ReadInt32(); const int dynLocalRecSize = 64 + 4 + 4 + 2 * 64; @@ -191,9 +191,9 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { local = localIndex < bodyOpt.Variables.Count ? bodyOpt.Variables[localIndex] : null; // Roslyn writes 0 to localIndex if it's a 'const' local, try to undo that now - if (localIndex == 0 && local != null && local.Name != name) + if (localIndex == 0 && !(local is null) && local.Name != name) local = null; - if (local != null && local.Name == name) + if (!(local is null) && local.Name == name) name = null; dynLocRec.Name = name; dynLocRec.Local = local; @@ -210,7 +210,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { return new PdbEditAndContinueLambdaMapCustomDebugInfo(data); case PdbCustomDebugInfoKind.TupleElementNames: - if (bodyOpt == null) + if (bodyOpt is null) return null; count = reader.ReadInt32(); if (count < 0) @@ -224,7 +224,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { for (int j = 0; j < nameCount; j++) { var s = ReadUTF8Z(recPosEnd); - if (s == null) + if (s is null) return null; tupleInfo.TupleElementNames.Add(s); } @@ -233,7 +233,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { uint scopeStart = reader.ReadUInt32(); uint scopeEnd = reader.ReadUInt32(); name = ReadUTF8Z(recPosEnd); - if (name == null) + if (name is null) return null; Debug.Assert(localIndex >= -1); // -1 = 'const' local. Only 'const' locals have a scope @@ -243,7 +243,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { local = null; tupleInfo.ScopeStart = GetInstruction(scopeStart); tupleInfo.ScopeEnd = GetInstruction(scopeEnd); - if (tupleInfo.ScopeStart == null) + if (tupleInfo.ScopeStart is null) return null; } else { @@ -252,7 +252,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { local = bodyOpt.Variables[localIndex]; } - if (local != null && local.Name == name) + if (!(local is null) && local.Name == name) name = null; tupleInfo.Local = local; tupleInfo.Name = name; @@ -269,7 +269,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { } TypeDef GetNestedType(string name) { - if (typeOpt == null) + if (typeOpt is null) return null; var nestedTypes = typeOpt.NestedTypes; int count = nestedTypes.Count; diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs index 4a41f6bb3..fbfe6cb92 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs @@ -68,7 +68,7 @@ void InitializeInstructionDictionary() { Debug.Assert(!instructionToOffsetDictInitd); instructionToOffsetDict.Clear(); var body = method.Body; - if (body == null) + if (body is null) return; var instrs = body.Instructions; uint offset = 0; @@ -84,7 +84,7 @@ void InitializeInstructionDictionary() { uint GetInstructionOffset(Instruction instr, bool nullIsEndOfMethod) { if (!instructionToOffsetDictInitd) InitializeInstructionDictionary(); - if (instr == null) { + if (instr is null) { if (nullIsEndOfMethod) return bodySize; Error("Instruction is null"); @@ -112,7 +112,7 @@ byte[] Write(IList customDebugInfos) { for (int i = 0; i < customDebugInfos.Count; i++) { var info = customDebugInfos[i]; - if (info == null) { + if (info is null) { Error("Custom debug info is null"); return null; } @@ -132,7 +132,7 @@ byte[] Write(IList customDebugInfos) { switch (info.Kind) { case PdbCustomDebugInfoKind.UsingGroups: var usingRec = info as PdbUsingGroupsCustomDebugInfo; - if (usingRec == null) { + if (usingRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -148,7 +148,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.ForwardMethodInfo: var fwdMethodRec = info as PdbForwardMethodInfoCustomDebugInfo; - if (fwdMethodRec == null) { + if (fwdMethodRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -160,7 +160,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.ForwardModuleInfo: var fwdModRec = info as PdbForwardModuleInfoCustomDebugInfo; - if (fwdModRec == null) { + if (fwdModRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -172,7 +172,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: var smLocalScopesRec = info as PdbStateMachineHoistedLocalScopesCustomDebugInfo; - if (smLocalScopesRec == null) { + if (smLocalScopesRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -193,12 +193,12 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.StateMachineTypeName: var smTypeRec = info as PdbStateMachineTypeNameCustomDebugInfo; - if (smTypeRec == null) { + if (smTypeRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } var type = smTypeRec.Type; - if (type == null) { + if (type is null) { Error("State machine type is null"); return null; } @@ -207,7 +207,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.DynamicLocals: var dynLocListRec = info as PdbDynamicLocalsCustomDebugInfo; - if (dynLocListRec == null) { + if (dynLocListRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -215,7 +215,7 @@ byte[] Write(IList customDebugInfos) { writer.WriteInt32(count); for (j = 0; j < count; j++) { var dynLoc = dynLocListRec.Locals[j]; - if (dynLoc == null) { + if (dynLoc is null) { Error("Dynamic local is null"); return null; } @@ -224,7 +224,7 @@ byte[] Write(IList customDebugInfos) { return null; } var name = dynLoc.Name; - if (name == null) + if (name is null) name = string.Empty; if (name.Length > 64) { Error("Dynamic local name is longer than 64 chars"); @@ -241,7 +241,7 @@ byte[] Write(IList customDebugInfos) { writer.WriteByte(0); writer.WriteInt32(dynLoc.Flags.Count); - if (dynLoc.Local == null) + if (dynLoc.Local is null) writer.WriteInt32(0); else writer.WriteInt32(dynLoc.Local.Index); @@ -255,7 +255,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: var encLocalMapRec = info as PdbEditAndContinueLocalSlotMapCustomDebugInfo; - if (encLocalMapRec == null) { + if (encLocalMapRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -264,7 +264,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: var encLambdaRec = info as PdbEditAndContinueLambdaMapCustomDebugInfo; - if (encLambdaRec == null) { + if (encLambdaRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -273,7 +273,7 @@ byte[] Write(IList customDebugInfos) { case PdbCustomDebugInfoKind.TupleElementNames: var tupleListRec = info as PdbTupleElementNamesCustomDebugInfo; - if (tupleListRec == null) { + if (tupleListRec is null) { Error("Unsupported custom debug info type {0}", info.GetType()); return null; } @@ -281,7 +281,7 @@ byte[] Write(IList customDebugInfos) { writer.WriteInt32(count); for (j = 0; j < count; j++) { var tupleInfo = tupleListRec.Names[j]; - if (tupleInfo == null) { + if (tupleInfo is null) { Error("Tuple name info is null"); return null; } @@ -289,7 +289,7 @@ byte[] Write(IList customDebugInfos) { for (k = 0; k < tupleInfo.TupleElementNames.Count; k++) WriteUTF8Z(tupleInfo.TupleElementNames[k]); - if (tupleInfo.Local == null) { + if (tupleInfo.Local is null) { writer.WriteInt32(-1); writer.WriteUInt32(GetInstructionOffset(tupleInfo.ScopeStart, nullIsEndOfMethod: false)); writer.WriteUInt32(GetInstructionOffset(tupleInfo.ScopeEnd, nullIsEndOfMethod: true)); @@ -304,7 +304,7 @@ byte[] Write(IList customDebugInfos) { default: var unkRec = info as PdbUnknownCustomDebugInfo; - if (unkRec == null) { + if (unkRec is null) { Error("Unsupported custom debug info class {0}", info.GetType()); return null; } @@ -335,7 +335,7 @@ byte[] Write(IList customDebugInfos) { } string MetadataNameToRoslynName(string name) { - if (name == null) + if (name is null) return name; int index = name.LastIndexOf('`'); if (index < 0) @@ -344,7 +344,7 @@ string MetadataNameToRoslynName(string name) { } void WriteUnicodeZ(string s) { - if (s == null) { + if (s is null) { Error("String is null"); return; } @@ -360,7 +360,7 @@ void WriteUnicodeZ(string s) { } void WriteUTF8Z(string s) { - if (s == null) { + if (s is null) { Error("String is null"); return; } @@ -375,7 +375,7 @@ void WriteUTF8Z(string s) { } uint GetMethodToken(IMethodDefOrRef method) { - if (method == null) { + if (method is null) { Error("Method is null"); return 0; } diff --git a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs index 7cba6c42e..6b22f8ffc 100644 --- a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs +++ b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs @@ -17,17 +17,17 @@ public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef modul var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); asyncMethod.KickoffMethod = kickoffMethod; - if (asyncCatchHandlerILOffset != null) { + if (!(asyncCatchHandlerILOffset is null)) { asyncMethod.CatchHandlerInstruction = GetInstruction(body, asyncCatchHandlerILOffset.Value); - Debug.Assert(asyncMethod.CatchHandlerInstruction != null); + Debug.Assert(!(asyncMethod.CatchHandlerInstruction is null)); } int count = asyncStepInfos.Count; for (int i = 0; i < count; i++) { var rawInfo = asyncStepInfos[i]; var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); - Debug.Assert(yieldInstruction != null); - if (yieldInstruction == null) + Debug.Assert(!(yieldInstruction is null)); + if (yieldInstruction is null) continue; MethodDef breakpointMethod; Instruction breakpointInstruction; @@ -41,13 +41,13 @@ public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef modul if (breakpointMethodToken.Table != Table.Method) continue; breakpointMethod = module.ResolveToken(breakpointMethodToken) as MethodDef; - Debug.Assert(breakpointMethod != null); - if (breakpointMethod == null) + Debug.Assert(!(breakpointMethod is null)); + if (breakpointMethod is null) continue; breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); } - Debug.Assert(breakpointInstruction != null); - if (breakpointInstruction == null) + Debug.Assert(!(breakpointInstruction is null)); + if (breakpointInstruction is null) continue; asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); @@ -57,7 +57,7 @@ public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef modul } static Instruction GetInstruction(CilBody body, uint offset) { - if (body == null) + if (body is null) return null; var instructions = body.Instructions; int lo = 0, hi = instructions.Count - 1; diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 52c4f89dd..78fc1e2ec 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -22,9 +22,9 @@ sealed class WindowsPdbWriter : IDisposable { public WindowsPdbWriter(SymbolWriter writer, PdbState pdbState, Metadata metadata) : this(pdbState, metadata) { - if (pdbState == null) + if (pdbState is null) throw new ArgumentNullException(nameof(pdbState)); - if (metadata == null) + if (metadata is null) throw new ArgumentNullException(nameof(metadata)); this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); writer.Initialize(metadata); @@ -68,13 +68,13 @@ public void Write() { var cdiBuilder = new List(); foreach (var type in module.GetTypes()) { - if (type == null) + if (type is null) continue; var typeMethods = type.Methods; int count = typeMethods.Count; for (int i = 0; i < count; i++) { var method = typeMethods[i]; - if (method == null) + if (method is null) continue; if (!ShouldAddMethod(method)) continue; @@ -90,7 +90,7 @@ public void Write() { bool ShouldAddMethod(MethodDef method) { var body = method.Body; - if (body == null) + if (body is null) return false; if (body.HasPdbMethod) @@ -101,7 +101,7 @@ bool ShouldAddMethod(MethodDef method) { for (int i = 0; i < count; i++) { var local = bodyVariables[i]; // Don't check whether it's the empty string. Only check for null. - if (local.Name != null) + if (!(local.Name is null)) return true; if (local.Attributes != 0) return true; @@ -110,7 +110,7 @@ bool ShouldAddMethod(MethodDef method) { var bodyInstructions = body.Instructions; count = bodyInstructions.Count; for (int i = 0; i < count; i++) { - if (bodyInstructions[i].SequencePoint != null) + if (!(bodyInstructions[i].SequencePoint is null)) return true; } @@ -135,11 +135,11 @@ public void Write(WindowsPdbWriter pdbWriter, IList instrs) { for (int i = 0; i < instrs.Count; i++, instrOffset += instr.GetSize()) { instr = instrs[i]; var seqp = instr.SequencePoint; - if (seqp == null || seqp.Document == null) + if (seqp is null || seqp.Document is null) continue; if (checkedPdbDocs.ContainsKey(seqp.Document)) continue; - if (currPdbDoc == null) + if (currPdbDoc is null) currPdbDoc = seqp.Document; else if (currPdbDoc != seqp.Document) { otherDocsAvailable = true; @@ -169,7 +169,7 @@ public void Write(WindowsPdbWriter pdbWriter, IList instrs) { if (!otherDocsAvailable) break; - if (currPdbDoc != null) + if (!(currPdbDoc is null)) checkedPdbDocs.Add(currPdbDoc, true); } } @@ -198,7 +198,7 @@ public CurrentMethod(WindowsPdbWriter pdbWriter, MethodDef method, Dictionary cdiBuilder) { seqPointsHelper.Write(this, info.Method.Body.Instructions); var pdbMethod = body.PdbMethod; - if (pdbMethod == null) + if (pdbMethod is null) body.PdbMethod = pdbMethod = new PdbMethod(); var scope = pdbMethod.Scope; - if (scope == null) + if (scope is null) pdbMethod.Scope = scope = new PdbScope(); if (scope.Namespaces.Count == 0 && scope.Variables.Count == 0 && scope.Constants.Count == 0) { if (scope.Scopes.Count == 0) { @@ -250,11 +250,11 @@ void Write(MethodDef method, List cdiBuilder) { if (cdiBuilder.Count != 0) { customDebugInfoWriterContext.Logger = GetLogger(); var cdiData = PdbCustomDebugInfoWriter.Write(metadata, method, customDebugInfoWriterContext, cdiBuilder); - if (cdiData != null) + if (!(cdiData is null)) writer.SetSymAttribute(symbolToken, "MD2", cdiData); } - if (asyncMethod != null) { + if (!(asyncMethod is null)) { if (!writer.SupportsAsyncMethods) Error("PDB symbol writer doesn't support writing async methods"); else @@ -272,7 +272,7 @@ void GetPseudoCustomDebugInfos(IList customDebugInfos, List< var cdi = customDebugInfos[i]; switch (cdi.Kind) { case PdbCustomDebugInfoKind.AsyncMethod: - if (asyncMethod != null) + if (!(asyncMethod is null)) Error("Duplicate async method custom debug info"); else asyncMethod = (PdbAsyncMethodCustomDebugInfo)cdi; @@ -296,7 +296,7 @@ uint GetMethodToken(MethodDef method) { } void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyncMethod) { - if (asyncMethod.KickoffMethod == null) { + if (asyncMethod.KickoffMethod is null) { Error("KickoffMethod is null"); return; } @@ -304,7 +304,7 @@ void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyn uint kickoffMethod = GetMethodToken(asyncMethod.KickoffMethod); writer.DefineKickoffMethod(kickoffMethod); - if (asyncMethod.CatchHandlerInstruction != null) { + if (!(asyncMethod.CatchHandlerInstruction is null)) { int catchHandlerILOffset = info.GetOffset(asyncMethod.CatchHandlerInstruction); writer.DefineCatchHandlerILOffset((uint)catchHandlerILOffset); } @@ -315,15 +315,15 @@ void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyn var breakpointMethods = new uint[stepInfos.Count]; for (int i = 0; i < yieldOffsets.Length; i++) { var stepInfo = stepInfos[i]; - if (stepInfo.YieldInstruction == null) { + if (stepInfo.YieldInstruction is null) { Error("YieldInstruction is null"); return; } - if (stepInfo.BreakpointMethod == null) { + if (stepInfo.BreakpointMethod is null) { Error("BreakpointMethod is null"); return; } - if (stepInfo.BreakpointInstruction == null) { + if (stepInfo.BreakpointInstruction is null) { Error("BreakpointInstruction is null"); return; } @@ -338,7 +338,7 @@ int GetExternalInstructionOffset(ref CurrentMethod info, MethodDef method, Instr if (info.Method == method) return info.GetOffset(instr); var body = method.Body; - if (body == null) { + if (body is null) { Error("Method body is null"); return 0; } @@ -351,7 +351,7 @@ int GetExternalInstructionOffset(ref CurrentMethod info, MethodDef method, Instr return offset; offset += currInstr.GetSize(); } - if (instr == null) + if (instr is null) return offset; Error("Async method instruction has been removed but it's still being referenced by PDB info: BP Instruction: {0}, BP Method: {1} (0x{2:X8}), Current Method: {3} (0x{4:X8})", instr, method, method.MDToken.Raw, info.Method, info.Method.MDToken.Raw); return 0; @@ -401,7 +401,7 @@ void AddLocals(MethodDef method, IList locals, uint startOffset, uint for (int i = 0; i < count; i++) { var local = locals[i]; uint attrs = GetPdbLocalFlags(local.Attributes); - if (attrs == 0 && local.Name == null) + if (attrs == 0 && local.Name is null) continue; writer.DefineLocalVariable(local.Name ?? string.Empty, attrs, token, 1, (uint)local.Index, 0, 0, startOffset, endOffset); @@ -416,7 +416,7 @@ static uint GetPdbLocalFlags(PdbLocalAttributes attributes) { MDToken GetUserEntryPointToken() { var ep = pdbState.UserEntryPoint; - if (ep == null) + if (ep is null) return default; uint rid = metadata.GetRid(ep); if (rid == 0) { @@ -435,7 +435,7 @@ public bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge /// public void Dispose() { - if (writer != null) + if (!(writer is null)) Close(); writer?.Dispose(); writer = null; diff --git a/src/DotNet/PropertyDef.cs b/src/DotNet/PropertyDef.cs index 4d83e3eca..16a53bb20 100644 --- a/src/DotNet/PropertyDef.cs +++ b/src/DotNet/PropertyDef.cs @@ -117,7 +117,7 @@ void InitializeConstant() { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -139,7 +139,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -155,14 +155,14 @@ protected virtual void InitializeCustomDebugInfos() => /// public MethodDef GetMethod { get { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); return getMethods.Count == 0 ? null : getMethods[0]; } set { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); - if (value == null) + if (value is null) getMethods.Clear(); else if (getMethods.Count == 0) getMethods.Add(value); @@ -176,14 +176,14 @@ public MethodDef GetMethod { /// public MethodDef SetMethod { get { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); return setMethods.Count == 0 ? null : setMethods[0]; } set { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); - if (value == null) + if (value is null) setMethods.Clear(); else if (setMethods.Count == 0) setMethods.Add(value); @@ -197,7 +197,7 @@ public MethodDef SetMethod { /// public IList GetMethods { get { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); return getMethods; } @@ -208,7 +208,7 @@ public IList GetMethods { /// public IList SetMethods { get { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); return setMethods; } @@ -219,7 +219,7 @@ public IList SetMethods { /// public IList OtherMethods { get { - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods(); return otherMethods; } @@ -229,7 +229,7 @@ void InitializePropertyMethods() { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (otherMethods == null) + if (otherMethods is null) InitializePropertyMethods_NoLock(); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } @@ -276,7 +276,7 @@ protected virtual void InitializePropertyMethods_NoLock() { /// /// true if is not null /// - public bool HasConstant => Constant != null; + public bool HasConstant => !(Constant is null); /// /// Gets the constant element type or if there's no constant @@ -284,7 +284,7 @@ protected virtual void InitializePropertyMethods_NoLock() { public ElementType ElementType { get { var c = Constant; - return c == null ? ElementType.End : c.Type; + return c is null ? ElementType.End : c.Type; } } @@ -305,9 +305,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (currentDeclaringType != null) + if (!(currentDeclaringType is null)) currentDeclaringType.Properties.Remove(this); // Will set DeclaringType2 = null - if (value != null) + if (!(value is null)) value.Properties.Add(this); // Will set DeclaringType2 = value } } @@ -468,7 +468,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public PropertyDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.PropertyTable.IsInvalidRID(rid)) throw new BadImageFormatException($"Property rid {rid} does not exist"); @@ -499,12 +499,12 @@ internal PropertyDefMD InitializeAll() { /// protected override void InitializePropertyMethods_NoLock() { - if (otherMethods != null) + if (!(otherMethods is null)) return; IList newOtherMethods; IList newGetMethods, newSetMethods; var dt = declaringType2 as TypeDefMD; - if (dt == null) { + if (dt is null) { newGetMethods = new List(); newSetMethods = new List(); newOtherMethods = new List(); diff --git a/src/DotNet/PublicKey.cs b/src/DotNet/PublicKey.cs index 7a13b6591..14b75d98f 100644 --- a/src/DotNet/PublicKey.cs +++ b/src/DotNet/PublicKey.cs @@ -15,7 +15,7 @@ public sealed class PublicKey : PublicKeyBase { /// public override PublicKeyToken Token { get { - if (publicKeyToken == null && !IsNullOrEmpty) + if (publicKeyToken is null && !IsNullOrEmpty) Interlocked.CompareExchange(ref publicKeyToken, AssemblyHash.CreatePublicKeyToken(data), null); return publicKeyToken; } @@ -51,7 +51,7 @@ public override bool Equals(object obj) { if ((object)this == obj) return true; var other = obj as PublicKey; - if (other == null) + if (other is null) return false; return Utils.Equals(Data, other.Data); } diff --git a/src/DotNet/PublicKeyBase.cs b/src/DotNet/PublicKeyBase.cs index bd33a3884..201017433 100644 --- a/src/DotNet/PublicKeyBase.cs +++ b/src/DotNet/PublicKeyBase.cs @@ -15,12 +15,12 @@ public abstract class PublicKeyBase { /// /// Returns true if is null or empty /// - public bool IsNullOrEmpty => data == null || data.Length == 0; + public bool IsNullOrEmpty => data is null || data.Length == 0; /// /// Returns true if is null /// - public bool IsNull => Data == null; + public bool IsNull => Data is null; /// /// Gets/sets key data @@ -46,7 +46,7 @@ public abstract class PublicKeyBase { protected PublicKeyBase(string hexString) => data = Parse(hexString); static byte[] Parse(string hexString) { - if (hexString == null || hexString == "null") + if (hexString is null || hexString == "null") return null; return Utils.ParseBytes(hexString); } @@ -55,7 +55,7 @@ static byte[] Parse(string hexString) { /// Checks whether a public key or token is null or empty /// /// Public key or token instance - public static bool IsNullOrEmpty2(PublicKeyBase a) => a == null || a.IsNullOrEmpty; + public static bool IsNullOrEmpty2(PublicKeyBase a) => a is null || a.IsNullOrEmpty; /// /// Returns a @@ -125,7 +125,7 @@ public static int TokenCompareTo(PublicKeyToken a, PublicKeyToken b) { /// Public key token /// The hash code public static int GetHashCode(PublicKeyToken a) { - if (a == null) + if (a is null) return 0; return Utils.GetHashCode(a.Data); } @@ -137,7 +137,7 @@ public static int GetHashCode(PublicKeyToken a) { /// A new instance or null if /// was null public static PublicKey CreatePublicKey(byte[] data) { - if (data == null) + if (data is null) return null; return new PublicKey(data); } @@ -149,7 +149,7 @@ public static PublicKey CreatePublicKey(byte[] data) { /// A new instance or null if /// was null public static PublicKeyToken CreatePublicKeyToken(byte[] data) { - if (data == null) + if (data is null) return null; return new PublicKeyToken(data); } @@ -160,7 +160,7 @@ public static PublicKeyToken CreatePublicKeyToken(byte[] data) { /// The instance or null /// Raw public key / public key token data or null public static byte[] GetRawData(PublicKeyBase pkb) { - if (pkb == null) + if (pkb is null) return null; return pkb.Data; } @@ -168,7 +168,7 @@ public static byte[] GetRawData(PublicKeyBase pkb) { /// public override string ToString() { var d = Data; - if (d == null || d.Length == 0) + if (d is null || d.Length == 0) return "null"; return Utils.ToHex(d, false); } diff --git a/src/DotNet/PublicKeyToken.cs b/src/DotNet/PublicKeyToken.cs index 7bf0204ea..b6fc50591 100644 --- a/src/DotNet/PublicKeyToken.cs +++ b/src/DotNet/PublicKeyToken.cs @@ -30,7 +30,7 @@ public override bool Equals(object obj) { if ((object)this == obj) return true; var other = obj as PublicKeyToken; - if (other == null) + if (other is null) return false; return Utils.Equals(Data, other.Data); } diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index 713b11ed9..c6cde5e8f 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -13,10 +13,10 @@ static class ReflectionExtensions { /// /// The type public static bool IsSZArray(this Type self) { - if (self == null || !self.IsArray) + if (self is null || !self.IsArray) return false; var prop = self.GetType().GetProperty("IsSzArray", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (prop != null) + if (!(prop is null)) return (bool)prop.GetValue(self, Array2.Empty()); return (self.Name ?? string.Empty).EndsWith("[]"); } @@ -27,7 +27,7 @@ public static bool IsSZArray(this Type self) { /// The type /// The type's element type public static ElementType GetElementType2(this Type a) { - if (a == null) + if (a is null) return ElementType.End; // Any invalid one is good enough if (a.IsArray) return IsSZArray(a) ? ElementType.SZArray : ElementType.Array; @@ -36,7 +36,7 @@ public static ElementType GetElementType2(this Type a) { if (a.IsPointer) return ElementType.Ptr; if (a.IsGenericParameter) - return a.DeclaringMethod == null ? ElementType.Var : ElementType.MVar; + return a.DeclaringMethod is null ? ElementType.Var : ElementType.MVar; if (a.IsGenericType && !a.IsGenericTypeDefinition) return ElementType.GenericInst; @@ -68,7 +68,7 @@ public static ElementType GetElementType2(this Type a) { /// /// The method public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => - mb != null && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; + !(mb is null) && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; /// /// Checks whether a parameter/prop/event type should be treated as if it is really a @@ -80,7 +80,7 @@ public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => /// Declaring type of method/event/property /// Parameter/property/event type internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) => - declaringType != null && declaringType.IsGenericTypeDefinition && t == declaringType; + !(declaringType is null) && declaringType.IsGenericTypeDefinition && t == declaringType; /// /// Checks whether is a type definition and not a type spec @@ -88,6 +88,6 @@ internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Typ /// /// this public static bool IsTypeDef(this Type type) => - type != null && !type.HasElementType && (!type.IsGenericType || type.IsGenericTypeDefinition); + !(type is null) && !type.HasElementType && (!type.IsGenericType || type.IsGenericTypeDefinition); } } diff --git a/src/DotNet/Resolver.cs b/src/DotNet/Resolver.cs index 9a5fb6624..950ec7a49 100644 --- a/src/DotNet/Resolver.cs +++ b/src/DotNet/Resolver.cs @@ -30,37 +30,37 @@ public Resolver(IAssemblyResolver assemblyResolver) => /// public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { - if (typeRef == null) + if (typeRef is null) return null; if (ProjectWinMDRefs) typeRef = WinMDHelpers.ToCLR(typeRef.Module ?? sourceModule, typeRef) ?? typeRef; var nonNestedTypeRef = TypeRef.GetNonNestedTypeRef(typeRef); - if (nonNestedTypeRef == null) + if (nonNestedTypeRef is null) return null; var nonNestedResolutionScope = nonNestedTypeRef.ResolutionScope; var nonNestedModule = nonNestedTypeRef.Module; if (nonNestedResolutionScope is AssemblyRef asmRef) { var asm = assemblyResolver.Resolve(asmRef, sourceModule ?? nonNestedModule); - return asm == null ? null : asm.Find(typeRef) ?? ResolveExportedType(asm.Modules, typeRef, sourceModule); + return asm is null ? null : asm.Find(typeRef) ?? ResolveExportedType(asm.Modules, typeRef, sourceModule); } if (nonNestedResolutionScope is ModuleDef moduleDef) return moduleDef.Find(typeRef) ?? ResolveExportedType(new ModuleDef[] { moduleDef }, typeRef, sourceModule); if (nonNestedResolutionScope is ModuleRef moduleRef) { - if (nonNestedModule == null) + if (nonNestedModule is null) return null; if (new SigComparer().Equals(moduleRef, nonNestedModule)) return nonNestedModule.Find(typeRef) ?? ResolveExportedType(new ModuleDef[] { nonNestedModule }, typeRef, sourceModule); var nonNestedAssembly = nonNestedModule.Assembly; - if (nonNestedAssembly == null) + if (nonNestedAssembly is null) return null; var resolvedModule = nonNestedAssembly.FindModule(moduleRef.Name); - return resolvedModule == null ? null : resolvedModule.Find(typeRef) ?? + return resolvedModule is null ? null : resolvedModule.Find(typeRef) ?? ResolveExportedType(new ModuleDef[] { resolvedModule }, typeRef, sourceModule); } @@ -70,16 +70,16 @@ public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { TypeDef ResolveExportedType(IList modules, TypeRef typeRef, ModuleDef sourceModule) { for (int i = 0; i < 30; i++) { var exportedType = FindExportedType(modules, typeRef); - if (exportedType == null) + if (exportedType is null) return null; var asmResolver = modules[0].Context.AssemblyResolver; var etAsm = asmResolver.Resolve(exportedType.DefinitionAssembly, sourceModule ?? typeRef.Module); - if (etAsm == null) + if (etAsm is null) return null; var td = etAsm.Find(typeRef); - if (td != null) + if (!(td is null)) return td; modules = etAsm.Modules; @@ -89,7 +89,7 @@ TypeDef ResolveExportedType(IList modules, TypeRef typeRef, ModuleDef } static ExportedType FindExportedType(IList modules, TypeRef typeRef) { - if (typeRef == null) + if (typeRef is null) return null; int count = modules.Count; for (int i = 0; i < count; i++) { @@ -107,7 +107,7 @@ static ExportedType FindExportedType(IList modules, TypeRef typeRef) /// public IMemberForwarded Resolve(MemberRef memberRef) { - if (memberRef == null) + if (memberRef is null) return null; if (ProjectWinMDRefs) memberRef = WinMDHelpers.ToCLR(memberRef.Module, memberRef) ?? memberRef; @@ -118,7 +118,7 @@ public IMemberForwarded Resolve(MemberRef memberRef) { } TypeDef GetDeclaringType(MemberRef memberRef, IMemberRefParent parent) { - if (memberRef == null || parent == null) + if (memberRef is null || parent is null) return null; if (parent is TypeSpec ts) @@ -134,15 +134,15 @@ TypeDef GetDeclaringType(MemberRef memberRef, IMemberRefParent parent) { // assembly as the current module. if (parent is ModuleRef moduleRef) { var module = memberRef.Module; - if (module == null) + if (module is null) return null; TypeDef globalType = null; if (new SigComparer().Equals(module, moduleRef)) globalType = module.GlobalType; var modAsm = module.Assembly; - if (globalType == null && modAsm != null) { + if (globalType is null && !(modAsm is null)) { var moduleDef = modAsm.FindModule(moduleRef.Name); - if (moduleDef != null) + if (!(moduleDef is null)) globalType = moduleDef.GlobalType; } return globalType; diff --git a/src/DotNet/Resource.cs b/src/DotNet/Resource.cs index 56227890c..4f48033b9 100644 --- a/src/DotNet/Resource.cs +++ b/src/DotNet/Resource.cs @@ -210,7 +210,7 @@ public byte[] Hash { /// /// Gets/sets the file name /// - public UTF8String FileName => file == null ? UTF8String.Empty : file.Name; + public UTF8String FileName => file is null ? UTF8String.Empty : file.Name; /// /// Constructor diff --git a/src/DotNet/ResourceCollection.cs b/src/DotNet/ResourceCollection.cs index afaabd1f2..78ff42a73 100644 --- a/src/DotNet/ResourceCollection.cs +++ b/src/DotNet/ResourceCollection.cs @@ -41,7 +41,7 @@ public int IndexOf(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (resource != null && resource.Name == name) + if (!(resource is null) && resource.Name == name) return i; } return -1; @@ -56,7 +56,7 @@ public int IndexOfEmbeddedResource(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (resource != null && + if (!(resource is null) && resource.ResourceType == ResourceType.Embedded && resource.Name == name) return i; @@ -73,7 +73,7 @@ public int IndexOfAssemblyLinkedResource(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (resource != null && + if (!(resource is null) && resource.ResourceType == ResourceType.AssemblyLinked && resource.Name == name) return i; @@ -90,7 +90,7 @@ public int IndexOfLinkedResource(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (resource != null && + if (!(resource is null) && resource.ResourceType == ResourceType.Linked && resource.Name == name) return i; @@ -105,7 +105,7 @@ public int IndexOfLinkedResource(UTF8String name) { /// The or null if none was found public Resource Find(UTF8String name) { foreach (var resource in this) { - if (resource != null && resource.Name == name) + if (!(resource is null) && resource.Name == name) return resource; } return null; @@ -118,7 +118,7 @@ public Resource Find(UTF8String name) { /// The or null if none was found public EmbeddedResource FindEmbeddedResource(UTF8String name) { foreach (var resource in this) { - if (resource != null && + if (!(resource is null) && resource.ResourceType == ResourceType.Embedded && resource.Name == name) return (EmbeddedResource)resource; @@ -133,7 +133,7 @@ public EmbeddedResource FindEmbeddedResource(UTF8String name) { /// The or null if none was found public AssemblyLinkedResource FindAssemblyLinkedResource(UTF8String name) { foreach (var resource in this) { - if (resource != null && + if (!(resource is null) && resource.ResourceType == ResourceType.AssemblyLinked && resource.Name == name) return (AssemblyLinkedResource)resource; @@ -148,7 +148,7 @@ public AssemblyLinkedResource FindAssemblyLinkedResource(UTF8String name) { /// The or null if none was found public LinkedResource FindLinkedResource(UTF8String name) { foreach (var resource in this) { - if (resource != null && + if (!(resource is null) && resource.ResourceType == ResourceType.Linked && resource.Name == name) return (LinkedResource)resource; diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index 032e040dd..98c4c076e 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -146,7 +146,7 @@ public override string ToString() { case ResourceTypeCode.ByteArray: case ResourceTypeCode.Stream: var ary = data as byte[]; - if (ary != null) + if (!(ary is null)) return $"{code}: Length: {ary.Length}"; return $"{code}: '{data}'"; diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index be99f5de6..cb2162a6b 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -246,10 +246,10 @@ UserResourceType CreateUserResourceType(string fullName, bool useFullName) { string GetRealTypeFullName(string fullName) { var tr = TypeNameParser.ParseReflection(module, fullName, null); - if (tr == null) + if (tr is null) return fullName; var asmRef = tr.DefinitionAssembly; - if (asmRef == null) + if (asmRef is null) return fullName; var newFullName = fullName; @@ -273,9 +273,9 @@ string TryGetRealAssemblyName(IAssembly asm) { if (simpleName == module.CorLibTypes.AssemblyRef.Name) return module.CorLibTypes.AssemblyRef.FullName; - if (moduleMD != null) { + if (!(moduleMD is null)) { var asmRef = moduleMD.GetAssemblyRef(simpleName); - if (asmRef != null) + if (!(asmRef is null)) return asmRef.FullName; } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 148d5272a..d079b1ced 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -190,9 +190,9 @@ IResourceData ReadResourceData(List userTypes, int size) { throw new ResourceReaderException($"Invalid resource data code: {code}"); var userType = userTypes[userTypeIndex]; var serializedData = reader.ReadBytes((int)(endPos - reader.Position)); - if (createResourceDataDelegate != null) { + if (!(createResourceDataDelegate is null)) { var res = createResourceDataDelegate(resourceDataFactory, userType, serializedData); - if (res != null) + if (!(res is null)) return res; } return resourceDataFactory.CreateSerialized(serializedData, userType); diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index e10f7a608..95944f275 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -110,7 +110,7 @@ static uint Hash(string key) { void InitializeUserTypes() { foreach (var resource in resources.ResourceElements) { var data = resource.ResourceData as UserResourceData; - if (data == null) + if (data is null) continue; var newType = typeCreator.CreateUserResourceType(data.TypeName); dataToNewType[data] = newType; diff --git a/src/DotNet/SecurityAttribute.cs b/src/DotNet/SecurityAttribute.cs index 4053bf5f6..fbbfa0372 100644 --- a/src/DotNet/SecurityAttribute.cs +++ b/src/DotNet/SecurityAttribute.cs @@ -24,7 +24,7 @@ public ITypeDefOrRef AttributeType { public string TypeFullName { get { var at = attrType; - return at == null ? string.Empty : at.FullName; + return at is null ? string.Empty : at.FullName; } } diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index bbd37e680..930dac664 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -623,13 +623,13 @@ SigComparerOptions SetOptions(SigComparerOptions flags) { void RestoreOptions(SigComparerOptions oldFlags) => options = oldFlags; void InitializeGenericArguments() { - if (genericArguments == null) + if (genericArguments is null) genericArguments = new GenericArguments(); } static GenericInstSig GetGenericInstanceType(IMemberRefParent parent) { var ts = parent as TypeSpec; - if (ts == null) + if (ts is null) return null; return ts.TypeSig.RemoveModifiers() as GenericInstSig; } @@ -641,7 +641,7 @@ bool Equals(IAssembly aAsm, IAssembly bAsm, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - return td != null && Equals(aAsm, td.Module.Assembly); + return !(td is null) && Equals(aAsm, td.Module.Assembly); } bool Equals(IAssembly aAsm, IAssembly bAsm, ExportedType b) { @@ -649,7 +649,7 @@ bool Equals(IAssembly aAsm, IAssembly bAsm, ExportedType b) { return true; var td = b.Resolve(); - return td != null && Equals(aAsm, td.Module.Assembly); + return !(td is null) && Equals(aAsm, td.Module.Assembly); } bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, TypeRef b) { @@ -660,7 +660,7 @@ bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, TypeRef b) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(sourceModule); - return tda != null && tdb != null && Equals(tda.Module.Assembly, tdb.Module.Assembly); + return !(tda is null) && !(tdb is null) && Equals(tda.Module.Assembly, tdb.Module.Assembly); } bool Equals(IAssembly aAsm, ExportedType a, IAssembly bAsm, ExportedType b) { @@ -669,7 +669,7 @@ bool Equals(IAssembly aAsm, ExportedType a, IAssembly bAsm, ExportedType b) { var tda = a.Resolve(); var tdb = b.Resolve(); - return tda != null && tdb != null && Equals(tda.Module.Assembly, tdb.Module.Assembly); + return !(tda is null) && !(tdb is null) && Equals(tda.Module.Assembly, tdb.Module.Assembly); } bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, ExportedType b) { @@ -680,7 +680,7 @@ bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, ExportedType b) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(); - return tda != null && tdb != null && Equals(tda.Module.Assembly, tdb.Module.Assembly); + return !(tda is null) && !(tdb is null) && Equals(tda.Module.Assembly, tdb.Module.Assembly); } bool Equals(TypeDef a, IModule bMod, TypeRef b) { @@ -690,7 +690,7 @@ bool Equals(TypeDef a, IModule bMod, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - if (td == null) + if (td is null) return false; if (!DontCheckTypeEquivalence) { if (TIAHelper.Equivalent(a, td)) @@ -704,11 +704,11 @@ bool Equals(TypeDef a, FileDef bFile, ExportedType b) { return true; var td = b.Resolve(); - return td != null && Equals(a.Module, td.Module) && Equals(a.DefinitionAssembly, td.DefinitionAssembly); + return !(td is null) && Equals(a.Module, td.Module) && Equals(a.DefinitionAssembly, td.DefinitionAssembly); } bool TypeDefScopeEquals(TypeDef a, TypeDef b) { - if (a == null || b == null) + if (a is null || b is null) return false; if (!DontCheckTypeEquivalence) { if (TIAHelper.Equivalent(a, b)) @@ -725,7 +725,7 @@ bool Equals(TypeRef a, IModule ma, TypeRef b, IModule mb) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(sourceModule); - return tda != null && tdb != null && + return !(tda is null) && !(tdb is null) && Equals(tda.Module, tdb.Module) && Equals(tda.DefinitionAssembly, tdb.DefinitionAssembly); } @@ -737,7 +737,7 @@ bool Equals(TypeRef a, IModule ma, ExportedType b, FileDef fb) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(); - return tda != null && tdb != null && + return !(tda is null) && !(tdb is null) && Equals(tda.Module, tdb.Module) && Equals(tda.DefinitionAssembly, tdb.DefinitionAssembly); } @@ -748,7 +748,7 @@ bool Equals(Assembly aAsm, IAssembly bAsm, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - return td != null && Equals(td.Module.Assembly, aAsm); + return !(td is null) && Equals(td.Module.Assembly, aAsm); } bool Equals(Assembly aAsm, IAssembly bAsm, ExportedType b) { @@ -756,7 +756,7 @@ bool Equals(Assembly aAsm, IAssembly bAsm, ExportedType b) { return true; var td = b.Resolve(); - return td != null && Equals(td.Module.Assembly, aAsm); + return !(td is null) && Equals(td.Module.Assembly, aAsm); } bool Equals(Type a, IModule bMod, TypeRef b) { @@ -766,7 +766,7 @@ bool Equals(Type a, IModule bMod, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - return td != null && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); + return !(td is null) && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); } bool Equals(Type a, FileDef bFile, ExportedType b) { @@ -774,7 +774,7 @@ bool Equals(Type a, FileDef bFile, ExportedType b) { return true; var td = b.Resolve(); - return td != null && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); + return !(td is null) && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); } /// @@ -786,7 +786,7 @@ bool Equals(Type a, FileDef bFile, ExportedType b) { public bool Equals(IMemberRef a, IMemberRef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -798,15 +798,15 @@ public bool Equals(IMemberRef a, IMemberRef b) { PropertyDef pa, pb; EventDef ea, eb; - if ((ta = a as IType) != null && (tb = b as IType) != null) + if (!((ta = a as IType) is null) && !((tb = b as IType) is null)) result = Equals(ta, tb); - else if ((fa = a as IField) != null && (fb = b as IField) != null && fa.IsField && fb.IsField) + else if (!((fa = a as IField) is null) && !((fb = b as IField) is null) && fa.IsField && fb.IsField) result = Equals(fa, fb); - else if ((ma = a as IMethod) != null && (mb = b as IMethod) != null) + else if (!((ma = a as IMethod) is null) && !((mb = b as IMethod) is null)) result = Equals(ma, mb); - else if ((pa = a as PropertyDef) != null && (pb = b as PropertyDef) != null) + else if (!((pa = a as PropertyDef) is null) && !((pb = b as PropertyDef) is null)) result = Equals(pa, pb); - else if ((ea = a as EventDef) != null && (eb = b as EventDef) != null) + else if (!((ea = a as EventDef) is null) && !((eb = b as EventDef) is null)) result = Equals(ea, eb); else result = false; @@ -821,7 +821,7 @@ public bool Equals(IMemberRef a, IMemberRef b) { /// The member /// The hash code public int GetHashCode(IMemberRef a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -833,15 +833,15 @@ public int GetHashCode(IMemberRef a) { PropertyDef pa; EventDef ea; - if ((ta = a as IType) != null) + if (!((ta = a as IType) is null)) result = GetHashCode(ta); - else if ((fa = a as IField) != null) + else if (!((fa = a as IField) is null)) result = GetHashCode(fa); - else if ((ma = a as IMethod) != null) + else if (!((ma = a as IMethod) is null)) result = GetHashCode(ma); - else if ((pa = a as PropertyDef) != null) + else if (!((pa = a as PropertyDef) is null)) result = GetHashCode(pa); - else if ((ea = a as EventDef) != null) + else if (!((ea = a as EventDef) is null)) result = GetHashCode(ea); else result = 0; // Should never be reached @@ -874,7 +874,7 @@ public int GetHashCode(IMemberRef a) { public bool Equals(IType a, IType b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -886,55 +886,55 @@ public bool Equals(IType a, IType b) { TypeSig sa, sb; ExportedType eta, etb; - if ((tda = a as TypeDef) != null & (tdb = b as TypeDef) != null) + if (!((tda = a as TypeDef) is null) & !((tdb = b as TypeDef) is null)) result = Equals(tda, tdb); - else if ((tra = a as TypeRef) != null & (trb = b as TypeRef) != null) + else if (!((tra = a as TypeRef) is null) & !((trb = b as TypeRef) is null)) result = Equals(tra, trb); - else if ((tsa = a as TypeSpec) != null & (tsb = b as TypeSpec) != null) + else if (!((tsa = a as TypeSpec) is null) & !((tsb = b as TypeSpec) is null)) result = Equals(tsa, tsb); - else if ((sa = a as TypeSig) != null & (sb = b as TypeSig) != null) + else if (!((sa = a as TypeSig) is null) & !((sb = b as TypeSig) is null)) result = Equals(sa, sb); - else if ((eta = a as ExportedType) != null & (etb = b as ExportedType) != null) + else if (!((eta = a as ExportedType) is null) & !((etb = b as ExportedType) is null)) result = Equals(eta, etb); - else if (tda != null && trb != null) + else if (!(tda is null) && !(trb is null)) result = Equals(tda, trb); // TypeDef vs TypeRef - else if (tra != null && tdb != null) + else if (!(tra is null) && !(tdb is null)) result = Equals(tdb, tra); // TypeDef vs TypeRef - else if (tda != null && tsb != null) + else if (!(tda is null) && !(tsb is null)) result = Equals(tda, tsb); // TypeDef vs TypeSpec - else if (tsa != null && tdb != null) + else if (!(tsa is null) && !(tdb is null)) result = Equals(tdb, tsa); // TypeDef vs TypeSpec - else if (tda != null && sb != null) + else if (!(tda is null) && !(sb is null)) result = Equals(tda, sb); // TypeDef vs TypeSig - else if (sa != null && tdb != null) + else if (!(sa is null) && !(tdb is null)) result = Equals(tdb, sa); // TypeDef vs TypeSig - else if (tda != null && etb != null) + else if (!(tda is null) && !(etb is null)) result = Equals(tda, etb); // TypeDef vs ExportedType - else if (eta != null && tdb != null) + else if (!(eta is null) && !(tdb is null)) result = Equals(tdb, eta); // TypeDef vs ExportedType - else if (tra != null && tsb != null) + else if (!(tra is null) && !(tsb is null)) result = Equals(tra, tsb); // TypeRef vs TypeSpec - else if (tsa != null && trb != null) + else if (!(tsa is null) && !(trb is null)) result = Equals(trb, tsa); // TypeRef vs TypeSpec - else if (tra != null && sb != null) + else if (!(tra is null) && !(sb is null)) result = Equals(tra, sb); // TypeRef vs TypeSig - else if (sa != null && trb != null) + else if (!(sa is null) && !(trb is null)) result = Equals(trb, sa); // TypeRef vs TypeSig - else if (tra != null && etb != null) + else if (!(tra is null) && !(etb is null)) result = Equals(tra, etb); // TypeRef vs ExportedType - else if (eta != null && trb != null) + else if (!(eta is null) && !(trb is null)) result = Equals(trb, eta); // TypeRef vs ExportedType - else if (tsa != null && sb != null) + else if (!(tsa is null) && !(sb is null)) result = Equals(tsa, sb); // TypeSpec vs TypeSig - else if (sa != null && tsb != null) + else if (!(sa is null) && !(tsb is null)) result = Equals(tsb, sa); // TypeSpec vs TypeSig - else if (tsa != null && etb != null) + else if (!(tsa is null) && !(etb is null)) result = Equals(tsa, etb); // TypeSpec vs ExportedType - else if (eta != null && tsb != null) + else if (!(eta is null) && !(tsb is null)) result = Equals(tsb, eta); // TypeSpec vs ExportedType - else if (sa != null && etb != null) + else if (!(sa is null) && !(etb is null)) result = Equals(sa, etb); // TypeSig vs ExportedType - else if (eta != null && sb != null) + else if (!(eta is null) && !(sb is null)) result = Equals(sb, eta); // TypeSig vs ExportedType else result = false; // Should never be reached @@ -949,7 +949,7 @@ public bool Equals(IType a, IType b) { /// The type /// The hash code public int GetHashCode(IType a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -961,15 +961,15 @@ public int GetHashCode(IType a) { TypeSig sig; ExportedType et; - if ((td = a as TypeDef) != null) + if (!((td = a as TypeDef) is null)) hash = GetHashCode(td); - else if ((tr = a as TypeRef) != null) + else if (!((tr = a as TypeRef) is null)) hash = GetHashCode(tr); - else if ((ts = a as TypeSpec) != null) + else if (!((ts = a as TypeSpec) is null)) hash = GetHashCode(ts); - else if ((sig = a as TypeSig) != null) + else if (!((sig = a as TypeSig) is null)) hash = GetHashCode(sig); - else if ((et = a as ExportedType) != null) + else if (!((et = a as ExportedType) is null)) hash = GetHashCode(et); else hash = 0; // Should never be reached @@ -995,7 +995,7 @@ public int GetHashCode(IType a) { public bool Equals(TypeDef a, TypeRef b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1008,7 +1008,7 @@ public bool Equals(TypeDef a, TypeRef b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (tra != null) { + if (!(tra is null)) { result = Equals(tra, b); goto exit; } @@ -1018,19 +1018,19 @@ public bool Equals(TypeDef a, TypeRef b) { if (!Equals_TypeNames(a.Name, b.Name) || !Equals_TypeNamespaces(a.Namespace, b.Namespace)) result = false; - else if ((dtb = scope as TypeRef) != null) // nested type + else if (!((dtb = scope as TypeRef) is null)) // nested type result = Equals(a.DeclaringType, dtb); // Compare enclosing types - else if (a.DeclaringType != null) { + else if (!(a.DeclaringType is null)) { // a is nested, b isn't result = false; } else if (DontCompareTypeScope) result = true; - else if ((bMod = scope as IModule) != null) // 'b' is defined in the same assembly as 'a' + else if (!((bMod = scope as IModule) is null)) // 'b' is defined in the same assembly as 'a' result = Equals(a, bMod, b); - else if ((bAsm = scope as AssemblyRef) != null) { + else if (!((bAsm = scope as AssemblyRef) is null)) { var aMod = a.Module; - result = aMod != null && Equals(aMod.Assembly, bAsm, b); + result = !(aMod is null) && Equals(aMod.Assembly, bAsm, b); if (!result) { if (!DontCheckTypeEquivalence) { var tdb = b.Resolve(); @@ -1040,7 +1040,7 @@ public bool Equals(TypeDef a, TypeRef b) { } else { result = false; - //TODO: Handle the case where scope == null + //TODO: Handle the case where scope is null } if (result && !TypeRefCanReferenceGlobalType && a.IsGlobalModuleType) @@ -1067,7 +1067,7 @@ public bool Equals(TypeDef a, TypeRef b) { public bool Equals(TypeDef a, ExportedType b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1079,7 +1079,7 @@ public bool Equals(TypeDef a, ExportedType b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (tra != null) { + if (!(tra is null)) { result = Equals(tra, b); goto exit; } @@ -1089,20 +1089,20 @@ public bool Equals(TypeDef a, ExportedType b) { if (!Equals_TypeNames(a.Name, b.TypeName) || !Equals_TypeNamespaces(a.Namespace, b.TypeNamespace)) result = false; - else if ((dtb = scope as ExportedType) != null) { // nested type + else if (!((dtb = scope as ExportedType) is null)) { // nested type result = Equals(a.DeclaringType, dtb); // Compare enclosing types } - else if (a.DeclaringType != null) { + else if (!(a.DeclaringType is null)) { result = false; // a is nested, b isn't } else if (DontCompareTypeScope) result = true; else { - if ((bFile = scope as FileDef) != null) + if (!((bFile = scope as FileDef) is null)) result = Equals(a, bFile, b); - else if ((bAsm = scope as AssemblyRef) != null) { + else if (!((bAsm = scope as AssemblyRef) is null)) { var aMod = a.Module; - result = aMod != null && Equals(aMod.Assembly, bAsm, b); + result = !(aMod is null) && Equals(aMod.Assembly, bAsm, b); } else result = false; @@ -1136,7 +1136,7 @@ public bool Equals(TypeDef a, ExportedType b) { public bool Equals(TypeDef a, TypeSpec b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; return Equals(a, b.TypeSig); } @@ -1158,7 +1158,7 @@ public bool Equals(TypeDef a, TypeSpec b) { public bool Equals(TypeDef a, TypeSig b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1196,7 +1196,7 @@ public bool Equals(TypeDef a, TypeSig b) { public bool Equals(TypeRef a, TypeSpec b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; return Equals(a, b.TypeSig); } @@ -1218,7 +1218,7 @@ public bool Equals(TypeRef a, TypeSpec b) { public bool Equals(TypeRef a, ExportedType b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1252,7 +1252,7 @@ public bool Equals(TypeRef a, ExportedType b) { public bool Equals(TypeRef a, TypeSig b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1290,7 +1290,7 @@ public bool Equals(TypeRef a, TypeSig b) { public bool Equals(TypeSpec a, TypeSig b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; return Equals(a.TypeSig, b); } @@ -1312,7 +1312,7 @@ public bool Equals(TypeSpec a, TypeSig b) { public bool Equals(TypeSpec a, ExportedType b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; return Equals(a.TypeSig, b); } @@ -1334,7 +1334,7 @@ public bool Equals(TypeSpec a, ExportedType b) { public bool Equals(TypeSig a, ExportedType b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1370,7 +1370,7 @@ int GetHashCodeGlobalType() { public bool Equals(TypeRef a, TypeRef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1399,7 +1399,7 @@ public int GetHashCode(TypeRef a) { // ************************************************************************************ // See GetHashCode(Type) for the reason why null returns GetHashCodeGlobalType() - if (a == null) + if (a is null) return TypeRefCanReferenceGlobalType ? GetHashCodeGlobalType() : 0; if (!DontProjectWinMDRefs) a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; @@ -1422,7 +1422,7 @@ public int GetHashCode(TypeRef a) { public bool Equals(ExportedType a, ExportedType b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1451,7 +1451,7 @@ public int GetHashCode(ExportedType a) { // ************************************************************************************ // See GetHashCode(Type) for the reason why null returns GetHashCodeGlobalType() - if (a == null) + if (a is null) return TypeRefCanReferenceGlobalType ? GetHashCodeGlobalType() : 0; if (!DontProjectWinMDRefs) a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; @@ -1473,7 +1473,7 @@ public int GetHashCode(ExportedType a) { public bool Equals(TypeDef a, TypeDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1483,7 +1483,7 @@ public bool Equals(TypeDef a, TypeDef b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); var trb = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b); - if (tra != null || trb != null) { + if (!(tra is null) || !(trb is null)) { result = Equals((IType)tra ?? a, (IType)trb ?? b); goto exit; } @@ -1510,17 +1510,17 @@ public int GetHashCode(TypeDef a) { // ************************************************************************************ // See GetHashCode(Type) for the reason why null returns GetHashCodeGlobalType() - if (a == null || a.IsGlobalModuleType) + if (a is null || a.IsGlobalModuleType) return GetHashCodeGlobalType(); if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (tra != null) + if (!(tra is null)) return GetHashCode(tra); } int hash; hash = GetHashCode_TypeName(a.Name); - if (a.DeclaringType != null) + if (!(a.DeclaringType is null)) hash += HASHCODE_MAGIC_NESTED_TYPE; else hash += GetHashCode_TypeNamespace(a.Namespace); @@ -1536,7 +1536,7 @@ public int GetHashCode(TypeDef a) { public bool Equals(TypeSpec a, TypeSpec b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1553,7 +1553,7 @@ public bool Equals(TypeSpec a, TypeSpec b) { /// The type /// The hash code public int GetHashCode(TypeSpec a) { - if (a == null) + if (a is null) return 0; return GetHashCode(a.TypeSig); } @@ -1567,13 +1567,13 @@ public int GetHashCode(TypeSpec a) { bool EqualsResolutionScope(TypeRef a, TypeRef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; var ra = a.ResolutionScope; var rb = b.ResolutionScope; if (ra == rb) return true; - if (ra == null || rb == null) + if (ra is null || rb is null) return false; if (!recursionCounter.Increment()) return false; @@ -1586,29 +1586,29 @@ bool EqualsResolutionScope(TypeRef a, TypeRef b) { bool resolveCheck = true; // if one of them is a TypeRef, the other one must be too - if ((ea = ra as TypeRef) != null | (eb = rb as TypeRef) != null) { + if (!((ea = ra as TypeRef) is null) | !((eb = rb as TypeRef) is null)) { result = Equals(ea, eb); resolveCheck = false; } else if (DontCompareTypeScope) result = true; // only compare if both are modules - else if ((ma = ra as IModule) != null & (mb = rb as IModule) != null) + else if (!((ma = ra as IModule) is null) & !((mb = rb as IModule) is null)) result = Equals(a, ma, b, mb); // only compare if both are assemblies - else if ((aa = ra as AssemblyRef) != null & (ab = rb as AssemblyRef) != null) + else if (!((aa = ra as AssemblyRef) is null) & !((ab = rb as AssemblyRef) is null)) result = Equals(aa, a, ab, b); - else if (aa != null && rb is ModuleRef) { + else if (!(aa is null) && rb is ModuleRef) { var bMod = b.Module; - result = bMod != null && Equals(bMod.Assembly, b, aa, a); + result = !(bMod is null) && Equals(bMod.Assembly, b, aa, a); } - else if (ab != null && ra is ModuleRef) { + else if (!(ab is null) && ra is ModuleRef) { var aMod = a.Module; - result = aMod != null && Equals(aMod.Assembly, a, ab, b); + result = !(aMod is null) && Equals(aMod.Assembly, a, ab, b); } - else if (aa != null && (modDef = rb as ModuleDef) != null) + else if (!(aa is null) && !((modDef = rb as ModuleDef) is null)) result = Equals(modDef.Assembly, aa, a); - else if (ab != null && (modDef = ra as ModuleDef) != null) + else if (!(ab is null) && !((modDef = ra as ModuleDef) is null)) result = Equals(modDef.Assembly, ab, b); else { result = false; @@ -1618,7 +1618,7 @@ bool EqualsResolutionScope(TypeRef a, TypeRef b) { if (!DontCheckTypeEquivalence) { var td1 = a.Resolve(); var td2 = b.Resolve(); - if (td1 != null && td2 != null) + if (!(td1 is null) && !(td2 is null)) result = TypeDefScopeEquals(td1, td2); } } @@ -1636,13 +1636,13 @@ bool EqualsResolutionScope(TypeRef a, TypeRef b) { bool EqualsImplementation(ExportedType a, ExportedType b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; var ia = a.Implementation; var ib = b.Implementation; if (ia == ib) return true; - if (ia == null || ib == null) + if (ia is null || ib is null) return false; if (!recursionCounter.Increment()) return false; @@ -1654,21 +1654,21 @@ bool EqualsImplementation(ExportedType a, ExportedType b) { bool checkResolve = true; // if one of them is an ExportedType, the other one must be too - if ((ea = ia as ExportedType) != null | (eb = ib as ExportedType) != null) { + if (!((ea = ia as ExportedType) is null) | !((eb = ib as ExportedType) is null)) { result = Equals(ea, eb); checkResolve = false; } else if (DontCompareTypeScope) result = true; // only compare if both are files - else if ((fa = ia as FileDef) != null & (fb = ib as FileDef) != null) + else if (!((fa = ia as FileDef) is null) & !((fb = ib as FileDef) is null)) result = Equals(fa, fb); // only compare if both are assemblies - else if ((aa = ia as AssemblyRef) != null & (ab = ib as AssemblyRef) != null) + else if (!((aa = ia as AssemblyRef) is null) & !((ab = ib as AssemblyRef) is null)) result = Equals(aa, a, ab, b); - else if (fa != null && ab != null) + else if (!(fa is null) && !(ab is null)) result = Equals(a.DefinitionAssembly, ab, b); - else if (fb != null && aa != null) + else if (!(fb is null) && !(aa is null)) result = Equals(b.DefinitionAssembly, aa, a); else { result = false; @@ -1677,7 +1677,7 @@ bool EqualsImplementation(ExportedType a, ExportedType b) { if (!result && checkResolve && !DontCheckTypeEquivalence) { var td1 = a.Resolve(); var td2 = b.Resolve(); - if (td1 != null && td2 != null) + if (!(td1 is null) && !(td2 is null)) result = TypeDefScopeEquals(td1, td2); } @@ -1694,13 +1694,13 @@ bool EqualsImplementation(ExportedType a, ExportedType b) { bool EqualsScope(TypeRef a, ExportedType b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; var ra = a.ResolutionScope; var ib = b.Implementation; if (ra == ib) return true; - if (ra == null || ib == null) + if (ra is null || ib is null) return false; if (!recursionCounter.Increment()) return false; @@ -1714,19 +1714,19 @@ bool EqualsScope(TypeRef a, ExportedType b) { bool checkResolve = true; // If one is a nested type, the other one must be too - if ((ea = ra as TypeRef) != null | (eb = ib as ExportedType) != null) { + if (!((ea = ra as TypeRef) is null) | !((eb = ib as ExportedType) is null)) { result = Equals(ea, eb); checkResolve = false; } else if (DontCompareTypeScope) result = true; - else if ((ma = ra as IModule) != null & (fb = ib as FileDef) != null) + else if (!((ma = ra as IModule) is null) & !((fb = ib as FileDef) is null)) result = Equals(a, ma, b, fb); - else if ((aa = ra as AssemblyRef) != null & (ab = ib as AssemblyRef) != null) + else if (!((aa = ra as AssemblyRef) is null) & !((ab = ib as AssemblyRef) is null)) result = Equals(aa, a, ab, b); - else if (ma != null && ab != null) + else if (!(ma is null) && !(ab is null)) result = Equals(a.DefinitionAssembly, ab, b); - else if (fb != null && aa != null) + else if (!(fb is null) && !(aa is null)) result = Equals(b.DefinitionAssembly, aa, a); else { checkResolve = false; @@ -1735,7 +1735,7 @@ bool EqualsScope(TypeRef a, ExportedType b) { if (!result && checkResolve && !DontCheckTypeEquivalence) { var td1 = a.Resolve(); var td2 = b.Resolve(); - if (td1 != null && td2 != null) + if (!(td1 is null) && !(td2 is null)) result = TypeDefScopeEquals(td1, td2); } @@ -1752,7 +1752,7 @@ bool EqualsScope(TypeRef a, ExportedType b) { bool Equals(FileDef a, FileDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); @@ -1767,7 +1767,7 @@ bool Equals(FileDef a, FileDef b) { bool Equals(IModule a, FileDef b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; //TODO: You should compare against the module's file name, not the name in the metadata! @@ -1783,7 +1783,7 @@ bool Equals(IModule a, FileDef b) { internal bool Equals(IModule a, IModule b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -1791,14 +1791,14 @@ internal bool Equals(IModule a, IModule b) { return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); } - static bool IsCorLib(ModuleDef a) => a != null && a.IsManifestModule && a.Assembly.IsCorLib(); + static bool IsCorLib(ModuleDef a) => !(a is null) && a.IsManifestModule && a.Assembly.IsCorLib(); static bool IsCorLib(IModule a) { var mod = a as ModuleDef; - return mod != null && mod.IsManifestModule && mod.Assembly.IsCorLib(); + return !(mod is null) && mod.IsManifestModule && mod.Assembly.IsCorLib(); } - static bool IsCorLib(Module a) => a != null && a.Assembly.ManifestModule == a && a.Assembly == typeof(void).Assembly; + static bool IsCorLib(Module a) => !(a is null) && a.Assembly.ManifestModule == a && a.Assembly == typeof(void).Assembly; static bool IsCorLib(IAssembly a) => a.IsCorLib(); static bool IsCorLib(Assembly a) => a == typeof(void).Assembly; @@ -1811,7 +1811,7 @@ static bool IsCorLib(IModule a) { bool Equals(ModuleDef a, ModuleDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -1833,7 +1833,7 @@ bool Equals(ModuleDef a, ModuleDef b) { bool Equals(IAssembly a, IAssembly b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -1862,7 +1862,7 @@ public bool Equals(TypeSig a, TypeSig b) { } if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -1985,7 +1985,7 @@ public bool Equals(TypeSig a, TypeSig b) { static bool TokenEquals(ITypeDefOrRef a, ITypeDefOrRef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; return a.MDToken == b.MDToken; } @@ -1999,13 +1999,13 @@ public int GetHashCode(TypeSig a) { // ******************************************** // IMPORTANT: This must match GetHashCode(Type) // ******************************************** - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; int hash; - if (genericArguments != null) + if (!(genericArguments is null)) a = genericArguments.Resolve(a); switch (a.ElementType) { @@ -2120,7 +2120,7 @@ public int GetHashCode(TypeSig a) { public bool Equals(IList a, IList b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2150,7 +2150,7 @@ public int GetHashCode(IList a) { //************************************************************************ // IMPORTANT: This code must match any other GetHashCode(IList) //************************************************************************ - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2166,7 +2166,7 @@ public int GetHashCode(IList a) { bool Equals(IList a, IList b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (a.Count != b.Count) return false; @@ -2180,7 +2180,7 @@ bool Equals(IList a, IList b) { bool Equals(IList a, IList b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (a.Count != b.Count) return false; @@ -2200,7 +2200,7 @@ bool Equals(IList a, IList b) { public bool Equals(CallingConventionSig a, CallingConventionSig b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2219,22 +2219,22 @@ public bool Equals(CallingConventionSig a, CallingConventionSig b) { case CallingConvention.Property: case CallingConvention.NativeVarArg: MethodBaseSig ma = a as MethodBaseSig, mb = b as MethodBaseSig; - result = ma != null && mb != null && Equals(ma, mb); + result = !(ma is null) && !(mb is null) && Equals(ma, mb); break; case CallingConvention.Field: FieldSig fa = a as FieldSig, fb = b as FieldSig; - result = fa != null && fb != null && Equals(fa, fb); + result = !(fa is null) && !(fb is null) && Equals(fa, fb); break; case CallingConvention.LocalSig: LocalSig la = a as LocalSig, lb = b as LocalSig; - result = la != null && lb != null && Equals(la, lb); + result = !(la is null) && !(lb is null) && Equals(la, lb); break; case CallingConvention.GenericInst: GenericInstMethodSig ga = a as GenericInstMethodSig, gb = b as GenericInstMethodSig; - result = ga != null && gb != null && Equals(ga, gb); + result = !(ga is null) && !(gb is null) && Equals(ga, gb); break; case CallingConvention.Unmanaged: @@ -2254,7 +2254,7 @@ public bool Equals(CallingConventionSig a, CallingConventionSig b) { /// The sig /// The hash code public int GetHashCode(CallingConventionSig a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2270,22 +2270,22 @@ public int GetHashCode(CallingConventionSig a) { case CallingConvention.Property: case CallingConvention.NativeVarArg: var ma = a as MethodBaseSig; - hash = ma == null ? 0 : GetHashCode(ma); + hash = ma is null ? 0 : GetHashCode(ma); break; case CallingConvention.Field: var fa = a as FieldSig; - hash = fa == null ? 0 : GetHashCode(fa); + hash = fa is null ? 0 : GetHashCode(fa); break; case CallingConvention.LocalSig: var la = a as LocalSig; - hash = la == null ? 0 : GetHashCode(la); + hash = la is null ? 0 : GetHashCode(la); break; case CallingConvention.GenericInst: var ga = a as GenericInstMethodSig; - hash = ga == null ? 0 : GetHashCode(ga); + hash = ga is null ? 0 : GetHashCode(ga); break; case CallingConvention.Unmanaged: @@ -2307,7 +2307,7 @@ public int GetHashCode(CallingConventionSig a) { public bool Equals(MethodBaseSig a, MethodBaseSig b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2328,7 +2328,7 @@ public bool Equals(MethodBaseSig a, MethodBaseSig b) { /// The method/property sig /// The hash code public int GetHashCode(MethodBaseSig a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2383,7 +2383,7 @@ int GetHashCode(CallingConvention a) { public bool Equals(FieldSig a, FieldSig b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2400,7 +2400,7 @@ public bool Equals(FieldSig a, FieldSig b) { /// The field sig /// The hash code public int GetHashCode(FieldSig a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2421,7 +2421,7 @@ public int GetHashCode(FieldSig a) { public bool Equals(LocalSig a, LocalSig b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2438,7 +2438,7 @@ public bool Equals(LocalSig a, LocalSig b) { /// The local sig /// The hash code public int GetHashCode(LocalSig a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2459,7 +2459,7 @@ public int GetHashCode(LocalSig a) { public bool Equals(GenericInstMethodSig a, GenericInstMethodSig b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2476,7 +2476,7 @@ public bool Equals(GenericInstMethodSig a, GenericInstMethodSig b) { /// The generic inst method sig /// The hash code public int GetHashCode(GenericInstMethodSig a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2497,7 +2497,7 @@ public int GetHashCode(GenericInstMethodSig a) { public bool Equals(IMethod a, IMethod b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2507,15 +2507,15 @@ public bool Equals(IMethod a, IMethod b) { MemberRef mra, mrb; MethodSpec msa, msb; - if ((mda = a as MethodDef) != null & (mdb = b as MethodDef) != null) + if (!((mda = a as MethodDef) is null) & !((mdb = b as MethodDef) is null)) result = Equals(mda, mdb); - else if ((mra = a as MemberRef) != null & (mrb = b as MemberRef) != null) + else if (!((mra = a as MemberRef) is null) & !((mrb = b as MemberRef) is null)) result = Equals(mra, mrb); - else if ((msa = a as MethodSpec) != null && (msb = b as MethodSpec) != null) + else if (!((msa = a as MethodSpec) is null) && !((msb = b as MethodSpec) is null)) result = Equals(msa, msb); - else if (mda != null && mrb != null) + else if (!(mda is null) && !(mrb is null)) result = Equals(mda, mrb); - else if (mra != null && mdb != null) + else if (!(mra is null) && !(mdb is null)) result = Equals(mdb, mra); else result = false; @@ -2530,7 +2530,7 @@ public bool Equals(IMethod a, IMethod b) { /// The method /// The hash code public int GetHashCode(IMethod a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2540,11 +2540,11 @@ public int GetHashCode(IMethod a) { MemberRef mra; MethodSpec msa; - if ((mda = a as MethodDef) != null) + if (!((mda = a as MethodDef) is null)) hash = GetHashCode(mda); - else if ((mra = a as MemberRef) != null) + else if (!((mra = a as MemberRef) is null)) hash = GetHashCode(mra); - else if ((msa = a as MethodSpec) != null) + else if (!((msa = a as MethodSpec) is null)) hash = GetHashCode(msa); else hash = 0; @@ -2570,7 +2570,7 @@ public int GetHashCode(IMethod a) { public bool Equals(MethodDef a, MemberRef b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2579,7 +2579,7 @@ public bool Equals(MethodDef a, MemberRef b) { if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (mra != null) { + if (!(mra is null)) { result = Equals(mra, b); goto exit; } @@ -2603,7 +2603,7 @@ public bool Equals(MethodDef a, MemberRef b) { public bool Equals(MethodDef a, MethodDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2612,7 +2612,7 @@ public bool Equals(MethodDef a, MethodDef b) { if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); var mrb = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b); - if (mra != null || mrb != null) { + if (!(mra is null) || !(mrb is null)) { result = Equals((IMethod)mra ?? a, (IMethod)mrb ?? b); goto exit; } @@ -2635,11 +2635,11 @@ public int GetHashCode(MethodDef a) { // *********************************************************************** // IMPORTANT: This hash code must match the MemberRef/MethodBase hash code // *********************************************************************** - if (a == null) + if (a is null) return 0; if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (mra != null) + if (!(mra is null)) return GetHashCode(mra); } @@ -2664,7 +2664,7 @@ public int GetHashCode(MethodDef a) { public bool Equals(MemberRef a, MemberRef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2690,7 +2690,7 @@ public int GetHashCode(MemberRef a) { // ******************************************************************************** // IMPORTANT: This hash code must match the MethodDef/FieldDef/MethodBase hash code // ******************************************************************************** - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2700,7 +2700,7 @@ public int GetHashCode(MemberRef a) { int hash = GetHashCode_MethodFieldName(a.Name); GenericInstSig git; - if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) != null) { + if (SubstituteGenericParameters && !((git = GetGenericInstanceType(a.Class)) is null)) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); hash += GetHashCode(a.Signature); @@ -2724,7 +2724,7 @@ public int GetHashCode(MemberRef a) { public bool Equals(MethodSpec a, MethodSpec b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2744,7 +2744,7 @@ public int GetHashCode(MethodSpec a) { // ************************************************************* // IMPORTANT: This hash code must match the MethodBase hash code // ************************************************************* - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2752,12 +2752,12 @@ public int GetHashCode(MethodSpec a) { // We must do this or it won't get the same hash code as some MethodInfos var oldOptions = SetOptions(SigComparerOptions_SubstituteGenericParameters); var gim = a.GenericInstMethodSig; - if (gim != null) { + if (!(gim is null)) { InitializeGenericArguments(); genericArguments.PushMethodArgs(gim.GenericArguments); } int hash = GetHashCode(a.Method); - if (gim != null) + if (!(gim is null)) genericArguments.PopMethodArgs(); RestoreOptions(oldOptions); @@ -2774,7 +2774,7 @@ public int GetHashCode(MethodSpec a) { bool Equals(IMemberRefParent a, IMemberRefParent b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2785,18 +2785,18 @@ bool Equals(IMemberRefParent a, IMemberRefParent b) { MethodDef ma, mb; TypeDef td; - if ((ita = a as ITypeDefOrRef) != null && (itb = b as ITypeDefOrRef) != null) + if (!((ita = a as ITypeDefOrRef) is null) && !((itb = b as ITypeDefOrRef) is null)) result = Equals((IType)ita, (IType)itb); - else if ((moda = a as ModuleRef) != null & (modb = b as ModuleRef) != null) { + else if (!((moda = a as ModuleRef) is null) & !((modb = b as ModuleRef) is null)) { ModuleDef omoda = moda.Module, omodb = modb.Module; result = Equals((IModule)moda, (IModule)modb) && Equals(omoda?.Assembly, omodb?.Assembly); } - else if ((ma = a as MethodDef) != null && (mb = b as MethodDef) != null) + else if (!((ma = a as MethodDef) is null) && !((mb = b as MethodDef) is null)) result = Equals(ma, mb); - else if (modb != null && (td = a as TypeDef) != null) + else if (!(modb is null) && !((td = a as TypeDef) is null)) result = EqualsGlobal(td, modb); - else if (moda != null && (td = b as TypeDef) != null) + else if (!(moda is null) && !((td = b as TypeDef) is null)) result = EqualsGlobal(td, moda); else result = false; @@ -2811,7 +2811,7 @@ bool Equals(IMemberRefParent a, IMemberRefParent b) { /// The MemberRefParent /// The hash code int GetHashCode(IMemberRefParent a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2820,11 +2820,11 @@ int GetHashCode(IMemberRefParent a) { ITypeDefOrRef ita; MethodDef ma; - if ((ita = a as ITypeDefOrRef) != null) + if (!((ita = a as ITypeDefOrRef) is null)) hash = GetHashCode((IType)ita); else if (a is ModuleRef) hash = GetHashCodeGlobalType(); - else if ((ma = a as MethodDef) != null) { + else if (!((ma = a as MethodDef) is null)) { // Only use the declaring type so we get the same hash code when hashing a MethodBase. hash = GetHashCode(ma.DeclaringType); } @@ -2844,7 +2844,7 @@ int GetHashCode(IMemberRefParent a) { public bool Equals(IField a, IField b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2853,13 +2853,13 @@ public bool Equals(IField a, IField b) { FieldDef fa, fb; MemberRef ma, mb; - if ((fa = a as FieldDef) != null & (fb = b as FieldDef) != null) + if (!((fa = a as FieldDef) is null) & !((fb = b as FieldDef) is null)) result = Equals(fa, fb); - else if ((ma = a as MemberRef) != null & (mb = b as MemberRef) != null) + else if (!((ma = a as MemberRef) is null) & !((mb = b as MemberRef) is null)) result = Equals(ma, mb); - else if (fa != null && mb != null) + else if (!(fa is null) && !(mb is null)) result = Equals(fa, mb); - else if (fb != null && ma != null) + else if (!(fb is null) && !(ma is null)) result = Equals(fb, ma); else result = false; @@ -2874,7 +2874,7 @@ public bool Equals(IField a, IField b) { /// The field /// The hash code public int GetHashCode(IField a) { - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2883,9 +2883,9 @@ public int GetHashCode(IField a) { FieldDef fa; MemberRef ma; - if ((fa = a as FieldDef) != null) + if (!((fa = a as FieldDef) is null)) hash = GetHashCode(fa); - else if ((ma = a as MemberRef) != null) + else if (!((ma = a as MemberRef) is null)) hash = GetHashCode(ma); else hash = 0; @@ -2911,7 +2911,7 @@ public int GetHashCode(IField a) { public bool Equals(FieldDef a, MemberRef b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2934,7 +2934,7 @@ public bool Equals(FieldDef a, MemberRef b) { public bool Equals(FieldDef a, FieldDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -2956,7 +2956,7 @@ public int GetHashCode(FieldDef a) { // ********************************************************************** // IMPORTANT: This hash code must match the MemberRef/FieldInfo hash code // ********************************************************************** - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -2979,7 +2979,7 @@ public int GetHashCode(FieldDef a) { public bool Equals(PropertyDef a, PropertyDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3001,7 +3001,7 @@ public int GetHashCode(PropertyDef a) { // *************************************************************** // IMPORTANT: This hash code must match the PropertyInfo hash code // *************************************************************** - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -3025,7 +3025,7 @@ public int GetHashCode(PropertyDef a) { public bool Equals(EventDef a, EventDef b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3047,7 +3047,7 @@ public int GetHashCode(EventDef a) { // ************************************************************ // IMPORTANT: This hash code must match the EventInfo hash code // ************************************************************ - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -3065,7 +3065,7 @@ public int GetHashCode(EventDef a) { bool EqualsGlobal(TypeDef a, ModuleRef b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3097,7 +3097,7 @@ bool EqualsGlobal(TypeDef a, ModuleRef b) { public bool Equals(IType a, Type b) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; if (!recursionCounter.Increment()) return false; @@ -3109,15 +3109,15 @@ public bool Equals(IType a, Type b) { TypeSig sig; ExportedType et; - if ((td = a as TypeDef) != null) + if (!((td = a as TypeDef) is null)) result = Equals(td, b); - else if ((tr = a as TypeRef) != null) + else if (!((tr = a as TypeRef) is null)) result = Equals(tr, b); - else if ((ts = a as TypeSpec) != null) + else if (!((ts = a as TypeSpec) is null)) result = Equals(ts, b); - else if ((sig = a as TypeSig) != null) + else if (!((sig = a as TypeSig) is null)) result = Equals(sig, b); - else if ((et = a as ExportedType) != null) + else if (!((et = a as ExportedType) is null)) result = Equals(et, b); else result = false; @@ -3143,9 +3143,9 @@ public bool Equals(IType a, Type b) { public bool Equals(TypeDef a, Type b) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; - if ((object)b == null) + if (b is null) return a.IsGlobalModuleType; if (!recursionCounter.Increment()) return false; @@ -3154,7 +3154,7 @@ public bool Equals(TypeDef a, Type b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (tra != null) { + if (!(tra is null)) { result = Equals(tra, b); goto exit; } @@ -3171,10 +3171,10 @@ public bool Equals(TypeDef a, Type b) { } bool EnclosingTypeEquals(TypeDef a, Type b) { - // b == null doesn't mean that b is the global type + // b is null doesn't mean that b is the global type if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; return Equals(a, b); } @@ -3196,9 +3196,9 @@ bool EnclosingTypeEquals(TypeDef a, Type b) { public bool Equals(TypeRef a, Type b) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; - if ((object)b == null) + if (b is null) return false; // Must use a ModuleRef to reference the global type, so always fail if (!recursionCounter.Increment()) return false; @@ -3216,19 +3216,19 @@ public bool Equals(TypeRef a, Type b) { result = false; else if (!Equals_TypeNames(a.Name, b.Name) || !Equals_TypeNamespaces(a.Namespace, b)) result = false; - else if ((dta = scope as TypeRef) != null) // nested type + else if (!((dta = scope as TypeRef) is null)) // nested type result = Equals(dta, b.DeclaringType); // Compare enclosing types else if (b.IsNested) result = false; // b is nested, a isn't else if (DontCompareTypeScope) result = true; - else if ((aMod = scope as IModule) != null) // 'a' is defined in the same assembly as 'b' + else if (!((aMod = scope as IModule) is null)) // 'a' is defined in the same assembly as 'b' result = Equals(b, aMod, a); - else if ((aAsm = scope as AssemblyRef) != null) + else if (!((aAsm = scope as AssemblyRef) is null)) result = Equals(b.Assembly, aAsm, a); else { result = false; - //TODO: Handle the case where scope == null + //TODO: Handle the case where scope is null } recursionCounter.Decrement(); @@ -3258,9 +3258,9 @@ bool Equals_TypeNamespaces(UTF8String a, Type b) { public bool Equals(TypeSpec a, Type b) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; - if ((object)b == null) + if (b is null) return false; // Must use a ModuleRef to reference the global type, so always fail return Equals(a.TypeSig, b); } @@ -3292,10 +3292,10 @@ bool Equals(ITypeDefOrRef a, Type b, bool treatAsGenericInst) { /// /// The type static bool IsFnPtrElementType(Type a) { - if ((object)a == null || !a.HasElementType) + if (a is null || !a.HasElementType) return false; var et = a.GetElementType(); - if (et == null || et.HasElementType) + if (et is null || et.HasElementType) return false; if (et != typeof(IntPtr)) // FnPtr is mapped to System.IntPtr return false; @@ -3316,15 +3316,15 @@ static bool IsFnPtrElementType(Type a) { bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; - if ((object)b == null) + if (b is null) return false; // Must use a ModuleRef to reference the global type, so always fail if (!recursionCounter.Increment()) return false; bool result; - if (genericArguments != null) + if (!(genericArguments is null)) a = genericArguments.Resolve(a); switch (a.ElementType) { @@ -3354,7 +3354,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = false; else if (IsFnPtrElementType(b)) { a = a.Next.RemoveModifiers(); - result = a != null && a.ElementType == ElementType.FnPtr; + result = !(a is null) && a.ElementType == ElementType.FnPtr; } else result = Equals(a.Next, b.GetElementType()); @@ -3365,7 +3365,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = false; else if (IsFnPtrElementType(b)) { a = a.Next.RemoveModifiers(); - result = a != null && a.ElementType == ElementType.FnPtr; + result = !(a is null) && a.ElementType == ElementType.FnPtr; } else result = Equals(a.Next, b.GetElementType()); @@ -3376,7 +3376,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = false; else if (IsFnPtrElementType(b)) { a = a.Next.RemoveModifiers(); - result = a != null && a.ElementType == ElementType.FnPtr; + result = !(a is null) && a.ElementType == ElementType.FnPtr; } else result = Equals(a.Next, b.GetElementType()); @@ -3393,7 +3393,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { var ara = a as ArraySig; result = ara.Rank == b.GetArrayRank() && (IsFnPtrElementType(b) ? - (a = a.Next.RemoveModifiers()) != null && a.ElementType == ElementType.FnPtr : + !((a = a.Next.RemoveModifiers()) is null) && a.ElementType == ElementType.FnPtr : Equals(a.Next, b.GetElementType())); } break; @@ -3406,13 +3406,13 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { case ElementType.Var: result = b.IsGenericParameter && b.GenericParameterPosition == (a as GenericSig).Number && - (object)b.DeclaringMethod == null; + b.DeclaringMethod is null; break; case ElementType.MVar: result = b.IsGenericParameter && b.GenericParameterPosition == (a as GenericSig).Number && - (object)b.DeclaringMethod != null; + !(b.DeclaringMethod is null); break; case ElementType.GenericInst: @@ -3474,9 +3474,9 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { public bool Equals(ExportedType a, Type b) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; - if ((object)b == null) + if (b is null) return false; // Must use a ModuleRef to reference the global type, so always fail if (!recursionCounter.Increment()) return false; @@ -3494,15 +3494,15 @@ public bool Equals(ExportedType a, Type b) { result = false; else if (!Equals_TypeNames(a.TypeName, b.Name) || !Equals_TypeNamespaces(a.TypeNamespace, b)) result = false; - else if ((dta = scope as ExportedType) != null) // nested type + else if (!((dta = scope as ExportedType) is null)) // nested type result = Equals(dta, b.DeclaringType); // Compare enclosing types else if (b.IsNested) result = false; // b is nested, a isn't else if (DontCompareTypeScope) result = true; - else if ((aFile = scope as FileDef) != null) + else if (!((aFile = scope as FileDef) is null)) result = Equals(b, aFile, a); - else if ((aAsm = scope as AssemblyRef) != null) + else if (!((aAsm = scope as AssemblyRef) is null)) result = Equals(b.Assembly, aAsm, a); else result = false; @@ -3529,7 +3529,7 @@ public int GetHashCode(Type a, bool treatAsGenericInst) { // ************************************************************************** // IMPORTANT: This hash code must match the TypeSig/TypeDef/TypeRef hash code // ************************************************************************** - if ((object)a == null) // Could be global type + if (a is null) // Could be global type return GetHashCode_TypeDef(a); if (!recursionCounter.Increment()) return 0; @@ -3630,7 +3630,7 @@ int GetHashCode(IList a) { //************************************************************************ // IMPORTANT: This code must match any other GetHashCode(IList) //************************************************************************ - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -3675,7 +3675,7 @@ public int GetHashCode_TypeDef(Type a) { // A global method/field's declaring type is null. This is the reason we must // return GetHashCodeGlobalType() here. - if ((object)a == null) + if (a is null) return GetHashCodeGlobalType(); int hash; hash = GetHashCode_TypeName(a.Name); @@ -3695,7 +3695,7 @@ public int GetHashCode_TypeDef(Type a) { bool Equals(IList a, IList b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3725,7 +3725,7 @@ bool Equals(IList a, IList b) { bool Equals(ModuleDef a, Module b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -3747,7 +3747,7 @@ bool Equals(ModuleDef a, Module b) { bool Equals(FileDef a, Module b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; // Use b.Name since it's the filename we want to compare, not b.ScopeName @@ -3763,7 +3763,7 @@ bool Equals(FileDef a, Module b) { bool Equals(IModule a, Module b) { if ((object)a == b) return true; - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -3781,7 +3781,7 @@ bool Equals(IModule a, Module b) { bool Equals(IAssembly a, Assembly b) { if ((object)a == b) return true; - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) return true; @@ -3811,7 +3811,7 @@ bool DeclaringTypeEquals(IMethod a, MethodBase b) { if ((object)a == b) return true; - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3821,11 +3821,11 @@ bool DeclaringTypeEquals(IMethod a, MethodBase b) { MemberRef mr; MethodSpec ms; - if ((md = a as MethodDef) != null) + if (!((md = a as MethodDef) is null)) result = DeclaringTypeEquals(md, b); - else if ((mr = a as MemberRef) != null) + else if (!((mr = a as MemberRef) is null)) result = DeclaringTypeEquals(mr, b); - else if ((ms = a as MethodSpec) != null) + else if (!((ms = a as MethodSpec) is null)) result = DeclaringTypeEquals(ms, b); else result = false; @@ -3840,7 +3840,7 @@ bool DeclaringTypeEquals(MethodDef a, MethodBase b) { return true; if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; return Equals(a.DeclaringType, b.DeclaringType); } @@ -3851,7 +3851,7 @@ bool DeclaringTypeEquals(MemberRef a, MethodBase b) { return true; if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; return Equals(a.Class, b.DeclaringType, b.Module); } @@ -3862,7 +3862,7 @@ bool DeclaringTypeEquals(MethodSpec a, MethodBase b) { return true; if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; return DeclaringTypeEquals(a.Method, b); } @@ -3884,7 +3884,7 @@ bool DeclaringTypeEquals(MethodSpec a, MethodBase b) { public bool Equals(IMethod a, MethodBase b) { if ((object)a == b) return true; - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3894,11 +3894,11 @@ public bool Equals(IMethod a, MethodBase b) { MemberRef mr; MethodSpec ms; - if ((md = a as MethodDef) != null) + if (!((md = a as MethodDef) is null)) result = Equals(md, b); - else if ((mr = a as MemberRef) != null) + else if (!((mr = a as MemberRef) is null)) result = Equals(mr, b); - else if ((ms = a as MethodSpec) != null) + else if (!((ms = a as MethodSpec) is null)) result = Equals(ms, b); else result = false; @@ -3924,7 +3924,7 @@ public bool Equals(IMethod a, MethodBase b) { public bool Equals(MethodDef a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3932,7 +3932,7 @@ public bool Equals(MethodDef a, MethodBase b) { bool result; if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (mra != null) { + if (!(mra is null)) { result = Equals(mra, b); goto exit; } @@ -3940,7 +3940,7 @@ public bool Equals(MethodDef a, MethodBase b) { var amSig = a.MethodSig; result = Equals_MethodFieldNames(a.Name, b.Name) && - amSig != null && + !(amSig is null) && ((amSig.Generic && b.IsGenericMethodDefinition && b.IsGenericMethod) || (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)) && Equals(amSig, b) && @@ -3968,7 +3968,7 @@ public bool Equals(MethodDef a, MethodBase b) { public bool Equals(MethodSig a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -3999,7 +3999,7 @@ public bool Equals(MethodSig a, MethodBase b) { public bool Equals(MemberRef a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4022,12 +4022,12 @@ public bool Equals(MemberRef a, MethodBase b) { else { var amSig = a.MethodSig; result = Equals_MethodFieldNames(a.Name, b.Name) && - amSig != null && + !(amSig is null) && ((amSig.Generic && b.IsGenericMethodDefinition && b.IsGenericMethod) || (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)); GenericInstSig git; - if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) != null) { + if (SubstituteGenericParameters && !((git = GetGenericInstanceType(a.Class)) is null)) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(amSig, b); @@ -4063,7 +4063,7 @@ static bool GenericMethodArgsEquals(int numMethodArgs, IList methodGenArgs bool Equals(IMemberRefParent a, Type b, Module bModule) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. - if (a == null) + if (a is null) return false; if (!recursionCounter.Increment()) return false; @@ -4074,17 +4074,17 @@ bool Equals(IMemberRefParent a, Type b, Module bModule) { MethodDef ma; TypeDef td; - if ((ita = a as ITypeDefOrRef) != null) + if (!((ita = a as ITypeDefOrRef) is null)) result = Equals((IType)ita, b); - else if ((moda = a as ModuleRef) != null) { + else if (!((moda = a as ModuleRef) is null)) { var omoda = moda.Module; - result = (object)b == null && // b == null => it's the global type + result = b is null && // b is null => it's the global type Equals(moda, bModule) && Equals(omoda?.Assembly, bModule.Assembly); } - else if ((ma = a as MethodDef) != null) + else if (!((ma = a as MethodDef) is null)) result = Equals(ma.DeclaringType, b); - else if ((object)b == null && (td = a as TypeDef) != null) + else if (b is null && !((td = a as TypeDef) is null)) result = td.IsGlobalModuleType; else result = false; @@ -4110,7 +4110,7 @@ bool Equals(IMemberRefParent a, Type b, Module bModule) { public bool Equals(MethodSpec a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4127,7 +4127,7 @@ public bool Equals(MethodSpec a, MethodBase b) { result = result && DeclaringTypeEquals(a.Method, b); var gim = a.GenericInstMethodSig; - result = result && gim != null && Equals(gim.GenericArguments, b.GetGenericArguments()); + result = result && !(gim is null) && Equals(gim.GenericArguments, b.GetGenericArguments()); recursionCounter.Decrement(); return result; @@ -4139,7 +4139,7 @@ public bool Equals(MethodSpec a, MethodBase b) { /// The MethodBase /// The hash code public int GetHashCode(MethodBase a) { - if ((object)a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4157,7 +4157,7 @@ public int GetHashCode(MethodBase a) { } int GetHashCode_MethodSig(MethodBase a) { - if ((object)a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4184,7 +4184,7 @@ int GetHashCode(IList a, Type declaringType) { //************************************************************************ // IMPORTANT: This code must match any other GetHashCode(IList) //************************************************************************ - if (a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4199,7 +4199,7 @@ int GetHashCode(IList a, Type declaringType) { int GetHashCode_ReturnType(MethodBase a) { var mi = a as MethodInfo; - if ((object)mi != null) + if (!(mi is null)) return GetHashCode(mi.ReturnParameter, a.DeclaringType); return GetHashCode(typeof(void)); } @@ -4269,14 +4269,14 @@ static int GetHashCode_CallingConvention(CallingConventions a, bool isGeneric) { bool ReturnTypeEquals(TypeSig a, MethodBase b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; bool result; var mi = b as MethodInfo; - if ((object)mi != null) + if (!(mi is null)) result = Equals(a, mi.ReturnParameter, b.DeclaringType); else if (b is ConstructorInfo) result = IsSystemVoid(a); @@ -4299,7 +4299,7 @@ bool ReturnTypeEquals(TypeSig a, MethodBase b) { bool Equals(IList a, IList b, Type declaringType) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4330,7 +4330,7 @@ bool Equals(IList a, IList b, Type declaringType) { bool Equals(TypeSig a, ParameterInfo b, Type declaringType) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4354,7 +4354,7 @@ bool ModifiersEquals(TypeSig a, IList reqMods2, IList optMods2, out var optMods1 = new List(optMods2.Count); while (true) { var modifierSig = aAfterModifiers as ModifierSig; - if (modifierSig == null) + if (modifierSig is null) break; if (modifierSig is CModOptSig) optMods1.Add(modifierSig.Modifier); @@ -4380,7 +4380,7 @@ bool ModifiersEquals(TypeSig a, IList reqMods2, IList optMods2, out bool ModifiersEquals(IList a, IList b) { if ((object)a == (object)b) return true; // both are null - if (a == null || b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4418,7 +4418,7 @@ bool ModifiersEquals(IList a, IList b) { public bool Equals(IField a, FieldInfo b) { if ((object)a == b) return true; - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4427,9 +4427,9 @@ public bool Equals(IField a, FieldInfo b) { FieldDef fa; MemberRef ma; - if ((fa = a as FieldDef) != null) + if (!((fa = a as FieldDef) is null)) result = Equals(fa, b); - else if ((ma = a as MemberRef) != null) + else if (!((ma = a as MemberRef) is null)) result = Equals(ma, b); else result = false; @@ -4455,7 +4455,7 @@ public bool Equals(IField a, FieldInfo b) { public bool Equals(FieldDef a, FieldInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4471,7 +4471,7 @@ public bool Equals(FieldDef a, FieldInfo b) { bool Equals(FieldSig a, FieldInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4500,7 +4500,7 @@ bool Equals(FieldSig a, FieldInfo b) { public bool Equals(MemberRef a, FieldInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4508,7 +4508,7 @@ public bool Equals(MemberRef a, FieldInfo b) { bool result = Equals_MethodFieldNames(a.Name, b.Name); GenericInstSig git; - if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) != null) { + if (SubstituteGenericParameters && !((git = GetGenericInstanceType(a.Class)) is null)) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(a.FieldSig, b); @@ -4532,7 +4532,7 @@ public int GetHashCode(FieldInfo a) { // ************************************************************ // IMPORTANT: This hash code must match the MemberRef hash code // ************************************************************ - if ((object)a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4547,7 +4547,7 @@ public int GetHashCode(FieldInfo a) { } int GetHashCode_FieldSig(FieldInfo a) { - if ((object)a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4568,7 +4568,7 @@ int GetHashCode_FieldSig(FieldInfo a) { public bool Equals(PropertyDef a, PropertyInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4584,7 +4584,7 @@ public bool Equals(PropertyDef a, PropertyInfo b) { bool Equals(PropertySig a, PropertyInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4605,7 +4605,7 @@ public int GetHashCode(PropertyInfo a) { // ************************************************************** // IMPORTANT: This hash code must match the PropertyDef hash code // ************************************************************** - if ((object)a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; @@ -4628,7 +4628,7 @@ public int GetHashCode(PropertyInfo a) { public bool Equals(EventDef a, EventInfo b) { if ((object)a == (object)b) return true; // both are null - if (a == null || (object)b == null) + if (a is null || b is null) return false; if (!recursionCounter.Increment()) return false; @@ -4650,7 +4650,7 @@ public int GetHashCode(EventInfo a) { // *********************************************************** // IMPORTANT: This hash code must match the EventDef hash code // *********************************************************** - if ((object)a == null) + if (a is null) return 0; if (!recursionCounter.Increment()) return 0; diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 4bdeba9a3..358123908 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -67,7 +67,7 @@ public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig, G if (reader.reader.Length == 0) return null; var csig = reader.ReadSig(); - if (csig != null) + if (!(csig is null)) csig.ExtraData = reader.GetExtraData(); return csig; } @@ -495,7 +495,7 @@ T ReadSig(T methodSig) where T : MethodBaseSig { for (uint i = 0; i < numParams; i++) { var type = ReadType(); if (type is SentinelSig) { - if (methodSig.ParamsAfterSentinel == null) + if (methodSig.ParamsAfterSentinel is null) methodSig.ParamsAfterSentinel = parameters = new List((int)(numParams - i)); i--; } diff --git a/src/DotNet/StandAloneSig.cs b/src/DotNet/StandAloneSig.cs index c645789f4..f733cffc3 100644 --- a/src/DotNet/StandAloneSig.cs +++ b/src/DotNet/StandAloneSig.cs @@ -44,7 +44,7 @@ public CallingConventionSig Signature { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -69,7 +69,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -160,7 +160,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public StandAloneSigMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.StandAloneSigTable.IsInvalidRID(rid)) throw new BadImageFormatException($"StandAloneSig rid {rid} does not exist"); diff --git a/src/DotNet/StrongNameKey.cs b/src/DotNet/StrongNameKey.cs index 025ca6336..25016a757 100644 --- a/src/DotNet/StrongNameKey.cs +++ b/src/DotNet/StrongNameKey.cs @@ -252,7 +252,7 @@ public sealed class StrongNameKey { /// public byte[] PublicKey { get { - if (publicKey == null) + if (publicKey is null) Interlocked.CompareExchange(ref publicKey, CreatePublicKey(), null); return publicKey; } diff --git a/src/DotNet/TIAHelper.cs b/src/DotNet/TIAHelper.cs index 223d208e6..df55adcb1 100644 --- a/src/DotNet/TIAHelper.cs +++ b/src/DotNet/TIAHelper.cs @@ -26,7 +26,7 @@ static bool stricmp(UTF8String a, UTF8String b) { var db = b?.Data; if (da == db) return true; - if (da == null || db == null) + if (da is null || db is null) return false; if (da.Length != db.Length) return false; @@ -44,14 +44,14 @@ static bool stricmp(UTF8String a, UTF8String b) { } static Info? GetInfo(TypeDef td) { - if (td == null) + if (td is null) return null; if (td.IsWindowsRuntime) return null; UTF8String scope = null, identifier = null; var tia = td.CustomAttributes.Find("System.Runtime.InteropServices.TypeIdentifierAttribute"); - if (tia != null) { + if (!(tia is null)) { if (tia.ConstructorArguments.Count >= 2) { if (tia.ConstructorArguments[0].Type.GetElementType() != ElementType.String) return null; @@ -63,7 +63,7 @@ static bool stricmp(UTF8String a, UTF8String b) { } else { var asm = td.Module?.Assembly; - if (asm == null) + if (asm is null) return null; bool isTypeLib = asm.CustomAttributes.IsDefined("System.Runtime.InteropServices.ImportedFromTypeLibAttribute") || asm.CustomAttributes.IsDefined("System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute"); @@ -77,11 +77,11 @@ static bool stricmp(UTF8String a, UTF8String b) { gca = td.CustomAttributes.Find("System.Runtime.InteropServices.GuidAttribute"); else { var asm = td.Module?.Assembly; - if (asm == null) + if (asm is null) return null; gca = asm.CustomAttributes.Find("System.Runtime.InteropServices.GuidAttribute"); } - if (gca == null) + if (gca is null) return null; if (gca.ConstructorArguments.Count < 1) return null; @@ -110,15 +110,15 @@ static byte[] Concat(byte[] a, byte b, byte[] c) { return data; } - internal static bool IsTypeDefEquivalent(TypeDef td) => GetInfo(td) != null && CheckEquivalent(td); + internal static bool IsTypeDefEquivalent(TypeDef td) => !(GetInfo(td) is null) && CheckEquivalent(td); static bool CheckEquivalent(TypeDef td) { - Debug.Assert(td != null); + Debug.Assert(!(td is null)); - for (int i = 0; td != null && i < 1000; i++) { + for (int i = 0; !(td is null) && i < 1000; i++) { if (i != 0) { var info = GetInfo(td); - if (info == null) + if (info is null) return false; } @@ -133,7 +133,7 @@ static bool CheckEquivalent(TypeDef td) { return false; var declType = td.DeclaringType; - if (declType == null) + if (declType is null) return td.IsPublic; if (!td.IsNestedPublic) @@ -146,10 +146,10 @@ static bool CheckEquivalent(TypeDef td) { public static bool Equivalent(TypeDef td1, TypeDef td2) { var info1 = GetInfo(td1); - if (info1 == null) + if (info1 is null) return false; var info2 = GetInfo(td2); - if (info2 == null) + if (info2 is null) return false; if (!CheckEquivalent(td1) || !CheckEquivalent(td2)) return false; @@ -166,7 +166,7 @@ public static bool Equivalent(TypeDef td1, TypeDef td2) { else { var bt1 = td1.BaseType; var bt2 = td2.BaseType; - if (bt1 == null || bt2 == null) + if (bt1 is null || bt2 is null) return false; if (td1.IsDelegate) { if (!td2.IsDelegate) @@ -188,9 +188,9 @@ public static bool Equivalent(TypeDef td1, TypeDef td2) { td1 = td1.DeclaringType; td2 = td2.DeclaringType; - if (td1 == null && td2 == null) + if (td1 is null && td2 is null) break; - if (td1 == null || td2 == null) + if (td1 is null || td2 is null) return false; } @@ -200,7 +200,7 @@ public static bool Equivalent(TypeDef td1, TypeDef td2) { static bool DelegateEquals(TypeDef td1, TypeDef td2) { var invoke1 = td1.FindMethod(InvokeString); var invoke2 = td2.FindMethod(InvokeString); - if (invoke1 == null || invoke2 == null) + if (invoke1 is null || invoke2 is null) return false; //TODO: Compare method signatures. Prevent infinite recursion... diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index db4093d90..2b39d9d82 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -224,7 +224,7 @@ void InitializeBaseType() { /// public IList Fields { get { - if (fields == null) + if (fields is null) InitializeFields(); return fields; } @@ -240,7 +240,7 @@ protected virtual void InitializeFields() => /// public IList Methods { get { - if (methods == null) + if (methods is null) InitializeMethods(); return methods; } @@ -254,7 +254,7 @@ protected virtual void InitializeMethods() => /// public IList GenericParameters { get { - if (genericParameters == null) + if (genericParameters is null) InitializeGenericParameters(); return genericParameters; } @@ -270,7 +270,7 @@ protected virtual void InitializeGenericParameters() => /// public IList Interfaces { get { - if (interfaces == null) + if (interfaces is null) InitializeInterfaces(); return interfaces; } @@ -284,7 +284,7 @@ protected virtual void InitializeInterfaces() => /// public IList DeclSecurities { get { - if (declSecurities == null) + if (declSecurities is null) InitializeDeclSecurities(); return declSecurities; } @@ -334,7 +334,7 @@ void InitializeClassLayout() { } ClassLayout GetOrCreateClassLayout() { var cl = ClassLayout; - if (cl != null) + if (!(cl is null)) return cl; Interlocked.CompareExchange(ref classLayout, new ClassLayoutUser(0, 0), null); return classLayout; @@ -359,9 +359,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (currentDeclaringType != null) + if (!(currentDeclaringType is null)) currentDeclaringType.NestedTypes.Remove(this); // Will set DeclaringType2 = null - if (value != null) + if (!(value is null)) value.NestedTypes.Add(this); // Will set DeclaringType2 = value // Make sure this is clear. Will be set whenever it's inserted into ModulDef.Types @@ -420,7 +420,7 @@ void InitializeDeclaringType2() { /// public IList NestedTypes { get { - if (nestedTypes == null) + if (nestedTypes is null) InitializeNestedTypes(); return nestedTypes; } @@ -436,7 +436,7 @@ protected virtual void InitializeNestedTypes() => /// public IList Events { get { - if (events == null) + if (events is null) InitializeEvents(); return events; } @@ -452,7 +452,7 @@ protected virtual void InitializeEvents() => /// public IList Properties { get { - if (properties == null) + if (properties is null) InitializeProperties(); return properties; } @@ -468,7 +468,7 @@ protected virtual void InitializeProperties() => /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -493,7 +493,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -542,7 +542,7 @@ protected virtual void InitializeCustomDebugInfos() => /// /// true if is not null /// - public bool HasClassLayout => ClassLayout != null; + public bool HasClassLayout => !(ClassLayout is null); /// /// Gets/sets the packing size. If you write to this property but @@ -552,7 +552,7 @@ protected virtual void InitializeCustomDebugInfos() => public ushort PackingSize { get { var cl = ClassLayout; - return cl == null ? ushort.MaxValue : cl.PackingSize; + return cl is null ? ushort.MaxValue : cl.PackingSize; } set { var cl = GetOrCreateClassLayout(); @@ -568,7 +568,7 @@ public ushort PackingSize { public uint ClassSize { get { var cl = ClassLayout; - return cl == null ? uint.MaxValue : cl.ClassSize; + return cl is null ? uint.MaxValue : cl.ClassSize; } set { var cl = GetOrCreateClassLayout(); @@ -584,7 +584,7 @@ public bool IsValueType { if ((Attributes & TypeAttributes.ClassSemanticsMask) != TypeAttributes.Class) return false; var baseType = BaseType; - if (baseType == null) + if (baseType is null) return false; if (!baseType.DefinitionAssembly.IsCorLib()) return false; @@ -597,7 +597,7 @@ public bool IsValueType { } else { var baseTd = baseType as TypeDef; - if (baseTd == null) + if (baseTd is null) return false; baseName = baseTd.Name; baseNamespace = baseTd.Namespace; @@ -628,7 +628,7 @@ public bool IsEnum { if ((Attributes & TypeAttributes.ClassSemanticsMask) != TypeAttributes.Class) return false; var baseType = BaseType; - if (baseType == null) + if (baseType is null) return false; if (!baseType.DefinitionAssembly.IsCorLib()) return false; @@ -650,7 +650,7 @@ public bool IsDelegate { if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.ClassSemanticsMask)) != TypeAttributes.Class) return false; var baseType = BaseType; - if (baseType == null) + if (baseType is null) return false; if (!baseType.DefinitionAssembly.IsCorLib()) return false; @@ -667,7 +667,7 @@ public bool IsDelegate { /// /// true if this is a nested type (it has a declaring type) /// - public bool IsNested => DeclaringType != null; + public bool IsNested => !(DeclaringType is null); /// public bool IsPrimitive => this.IsPrimitive(); @@ -900,7 +900,7 @@ public bool HasSecurity { public bool IsGlobalModuleType { get { var mod = Module; - return mod != null && mod.GlobalType == this; + return !(mod is null) && mod.GlobalType == this; } } @@ -920,7 +920,7 @@ public TypeSig GetEnumUnderlyingType() { var field = fields[i]; if (!field.IsLiteral && !field.IsStatic) { var fieldSig = field.FieldSig; - if (fieldSig != null) + if (!(fieldSig is null)) return fieldSig.Type; } } @@ -945,15 +945,15 @@ public TypeSig GetEnumUnderlyingType() { /// A or a instance or null /// if it couldn't be resolved. public IMemberForwarded Resolve(MemberRef memberRef, SigComparerOptions options) { - if (memberRef == null) + if (memberRef is null) return null; var methodSig = memberRef.MethodSig; - if (methodSig != null) + if (!(methodSig is null)) return FindMethodCheckBaseType(memberRef.Name, methodSig, options, memberRef.Module); var fieldSig = memberRef.FieldSig; - if (fieldSig != null) + if (!(fieldSig is null)) return FindFieldCheckBaseType(memberRef.Name, fieldSig, options, memberRef.Module); return null; @@ -985,7 +985,7 @@ public IMemberForwarded Resolve(MemberRef memberRef, SigComparerOptions options) /// The module that needs to find the method or null /// The first method that matches or null if none found public MethodDef FindMethod(UTF8String name, MethodSig sig, SigComparerOptions options, ModuleDef sourceModule) { - if (UTF8String.IsNull(name) || sig == null) + if (UTF8String.IsNull(name) || sig is null) return null; var comparer = new SigComparer(options, sourceModule); bool allowPrivateScope = (options & SigComparerOptions.PrivateScopeMethodIsComparable) != 0; @@ -1057,7 +1057,7 @@ public MethodDef FindStaticConstructor() { /// The class constructor public MethodDef FindOrCreateStaticConstructor() { var cctor = FindStaticConstructor(); - if (cctor != null) + if (!(cctor is null)) return cctor; var implFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; @@ -1116,7 +1116,7 @@ public MethodDef FindDefaultConstructor() { if (!method.IsInstanceConstructor) continue; var sig = method.MethodSig; - if (sig != null && sig.Params.Count == 0) + if (!(sig is null) && sig.Params.Count == 0) return method; } return null; @@ -1148,7 +1148,7 @@ public MethodDef FindDefaultConstructor() { /// The module that needs to find the field or null /// The first field that matches or null if none found public FieldDef FindField(UTF8String name, FieldSig sig, SigComparerOptions options, ModuleDef sourceModule) { - if (UTF8String.IsNull(name) || sig == null) + if (UTF8String.IsNull(name) || sig is null) return null; var comparer = new SigComparer(options, sourceModule); bool allowPrivateScope = (options & SigComparerOptions.PrivateScopeFieldIsComparable) != 0; @@ -1223,7 +1223,7 @@ public IEnumerable FindFields(UTF8String name) { /// The module that needs to find the event or null /// A or null if not found public EventDef FindEvent(UTF8String name, IType type, SigComparerOptions options, ModuleDef sourceModule) { - if (UTF8String.IsNull(name) || type == null) + if (UTF8String.IsNull(name) || type is null) return null; var comparer = new SigComparer(options, sourceModule); var events = Events; @@ -1295,7 +1295,7 @@ public IEnumerable FindEvents(UTF8String name) { /// The module that needs to find the property or null /// A or null if not found public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig, SigComparerOptions options, ModuleDef sourceModule) { - if (UTF8String.IsNull(name) || propSig == null) + if (UTF8String.IsNull(name) || propSig is null) return null; var comparer = new SigComparer(options, sourceModule); var properties = Properties; @@ -1368,9 +1368,9 @@ public IEnumerable FindProperties(UTF8String name) { /// The method or null if it wasn't found public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; - while (td != null) { + while (!(td is null)) { var md = td.FindMethod(name, sig, options, sourceModule); - if (md != null) + if (!(md is null)) return md; td = td.BaseType.ResolveTypeDef(); } @@ -1384,9 +1384,9 @@ public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig, SigComp /// The method or null if it wasn't found public MethodDef FindMethodCheckBaseType(UTF8String name) { var td = this; - while (td != null) { + while (!(td is null)) { var md = td.FindMethod(name); - if (md != null) + if (!(md is null)) return md; td = td.BaseType.ResolveTypeDef(); } @@ -1420,9 +1420,9 @@ public MethodDef FindMethodCheckBaseType(UTF8String name) { /// The field or null if it wasn't found public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; - while (td != null) { + while (!(td is null)) { var fd = td.FindField(name, sig, options, sourceModule); - if (fd != null) + if (!(fd is null)) return fd; td = td.BaseType.ResolveTypeDef(); } @@ -1436,9 +1436,9 @@ public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig, SigCompare /// The field or null if it wasn't found public FieldDef FindFieldCheckBaseType(UTF8String name) { var td = this; - while (td != null) { + while (!(td is null)) { var fd = td.FindField(name); - if (fd != null) + if (!(fd is null)) return fd; td = td.BaseType.ResolveTypeDef(); } @@ -1453,9 +1453,9 @@ public FieldDef FindFieldCheckBaseType(UTF8String name) { /// The event or null if it wasn't found public EventDef FindEventCheckBaseType(UTF8String name, ITypeDefOrRef eventType) { var td = this; - while (td != null) { + while (!(td is null)) { var ed = td.FindEvent(name, eventType); - if (ed != null) + if (!(ed is null)) return ed; td = td.BaseType.ResolveTypeDef(); } @@ -1469,9 +1469,9 @@ public EventDef FindEventCheckBaseType(UTF8String name, ITypeDefOrRef eventType) /// The event or null if it wasn't found public EventDef FindEventCheckBaseType(UTF8String name) { var td = this; - while (td != null) { + while (!(td is null)) { var ed = td.FindEvent(name); - if (ed != null) + if (!(ed is null)) return ed; td = td.BaseType.ResolveTypeDef(); } @@ -1505,9 +1505,9 @@ public EventDef FindEventCheckBaseType(UTF8String name) { /// The property or null if it wasn't found public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; - while (td != null) { + while (!(td is null)) { var pd = td.FindProperty(name, sig, options, sourceModule); - if (pd != null) + if (!(pd is null)) return pd; td = td.BaseType.ResolveTypeDef(); } @@ -1521,9 +1521,9 @@ public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, S /// The property or null if it wasn't found public PropertyDef FindPropertyCheckBaseType(UTF8String name) { var td = this; - while (td != null) { + while (!(td is null)) { var pd = td.FindProperty(name); - if (pd != null) + if (!(pd is null)) return pd; td = td.BaseType.ResolveTypeDef(); } @@ -1543,7 +1543,7 @@ public PropertyDef FindPropertyCheckBaseType(UTF8String name) { /// true if we should remove all /// empty properties and events. public void Remove(MethodDef method, bool removeEmptyPropertiesEvents) { - if (method == null) + if (method is null) return; var properties = Properties; @@ -1604,7 +1604,7 @@ internal virtual void OnLazyAdd2(int index, ref FieldDef value) { /// void IListListener.OnAdd(int index, FieldDef value) { - if (value.DeclaringType != null) + if (!(value.DeclaringType is null)) throw new InvalidOperationException("Field is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; } @@ -1634,7 +1634,7 @@ internal virtual void OnLazyAdd2(int index, ref MethodDef value) { /// void IListListener.OnAdd(int index, MethodDef value) { - if (value.DeclaringType != null) + if (!(value.DeclaringType is null)) throw new InvalidOperationException("Method is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; value.Parameters.UpdateThisParameterType(this); @@ -1661,8 +1661,8 @@ void IListListener.OnClear() { /// void IListListener.OnLazyAdd(int index, ref TypeDef value) { #if DEBUG - if (value.Module2 != null) - throw new InvalidOperationException("Added nested type's Module != null"); + if (!(value.Module2 is null)) + throw new InvalidOperationException("Added nested type's !(Module is null)"); if (value.DeclaringType != this) throw new InvalidOperationException("Added nested type's DeclaringType != this"); #endif @@ -1670,9 +1670,9 @@ void IListListener.OnLazyAdd(int index, ref TypeDef value) { /// void IListListener.OnAdd(int index, TypeDef value) { - if (value.DeclaringType != null) + if (!(value.DeclaringType is null)) throw new InvalidOperationException("Nested type is already owned by another type. Set DeclaringType to null first."); - if (value.Module != null) + if (!(value.Module is null)) throw new InvalidOperationException("Type is already owned by another module. Remove it from that module's type list."); value.DeclaringType2 = this; } @@ -1705,7 +1705,7 @@ internal virtual void OnLazyAdd2(int index, ref EventDef value) { /// void IListListener.OnAdd(int index, EventDef value) { - if (value.DeclaringType != null) + if (!(value.DeclaringType is null)) throw new InvalidOperationException("Event is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; } @@ -1735,7 +1735,7 @@ internal virtual void OnLazyAdd2(int index, ref PropertyDef value) { /// void IListListener.OnAdd(int index, PropertyDef value) { - if (value.DeclaringType != null) + if (!(value.DeclaringType is null)) throw new InvalidOperationException("Property is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; } @@ -1765,7 +1765,7 @@ internal virtual void OnLazyAdd2(int index, ref GenericParam value) { /// void IListListener.OnAdd(int index, GenericParam value) { - if (value.Owner != null) + if (!(value.Owner is null)) throw new InvalidOperationException("Generic param is already owned by another type/method. Set Owner to null first."); value.Owner = this; } @@ -1818,7 +1818,7 @@ public FieldDef GetField(UTF8String name) { internal static bool GetClassSize(TypeDef td, out uint size) { size = 0; - if (td == null) + if (td is null) return false; if (!td.IsValueType) return false; // Not supported by us @@ -1826,13 +1826,13 @@ internal static bool GetClassSize(TypeDef td, out uint size) { if (td.Fields.Count != 1) return false; var fd = td.Fields[0]; - if (fd == null) + if (fd is null) return false; return fd.GetFieldSize(out size); } var classLayout = td.ClassLayout; - if (classLayout == null) + if (classLayout is null) return false; uint classSize = classLayout.ClassSize; if (classSize != 0) { @@ -1856,36 +1856,36 @@ protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { // Must be a member ref var mr = mdr as MemberRef; - if (mr == null) + if (mr is null) return null; // If Class is MethodDef, then it should be a vararg method var parent = mr.Class; md = parent as MethodDef; - if (md != null) + if (!(md is null)) return md; // If it's a TypeSpec, it must be a generic instance type for (int i = 0; i < 10; i++) { var ts = parent as TypeSpec; - if (ts == null) + if (ts is null) break; var gis = ts.TypeSig as GenericInstSig; - if (gis == null || gis.GenericType == null) + if (gis is null || gis.GenericType is null) return null; parent = gis.GenericType.TypeDefOrRef; } var td = parent as TypeDef; - if (td == null) { + if (td is null) { // If it's a TypeRef, resolve it as if it is a reference to a type in the // current module, even if its ResolutionScope happens to be some other // assembly/module (that's what the CLR does) - if (parent is TypeRef tr && Module != null) + if (parent is TypeRef tr && !(Module is null)) td = Module.Find(tr); } - if (td == null) + if (td is null) return null; return td.FindMethod(mr.Name, mr.MethodSig); } @@ -2054,7 +2054,7 @@ protected override void InitializeCustomDebugInfos() { } /// - protected override ModuleDef GetModule2_NoLock() => DeclaringType2_NoLock != null ? null : readerModule; + protected override ModuleDef GetModule2_NoLock() => !(DeclaringType2_NoLock is null) ? null : readerModule; /// /// Constructor @@ -2065,7 +2065,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public TypeDefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.TypeDefTable.IsInvalidRID(rid)) throw new BadImageFormatException($"TypeDef rid {rid} does not exist"); @@ -2088,10 +2088,10 @@ public TypeDefMD(ModuleDefMD readerModule, uint rid) { /// Generic parameter context /// A list (possibly empty) of all methods overrides internal IList GetMethodOverrides(MethodDefMD method, GenericParamContext gpContext) { - if (method == null) + if (method is null) return new List(); - if (methodRidToOverrides == null) + if (methodRidToOverrides is null) InitializeMethodOverrides(); if (methodRidToOverrides.TryGetValue(method.OrigRid, out var overrides)) { @@ -2128,14 +2128,14 @@ void InitializeMethodOverrides() { var methodBody = readerModule.ResolveMethodDefOrRef(row.MethodBody); var methodDecl = readerModule.ResolveMethodDefOrRef(row.MethodDeclaration); - if (methodBody == null || methodDecl == null) + if (methodBody is null || methodDecl is null) continue; // Should only happen if some obfuscator added invalid metadata // Find the real method. This is usually methodBody since it's usually a // MethodDef. The CLR only allows method bodies in the current type, and // so shall we. var method = FindMethodImplMethod(methodBody); - if (method == null || method.DeclaringType != this) + if (method is null || method.DeclaringType != this) continue; uint rid = method.Rid; @@ -2159,7 +2159,7 @@ internal void InitializeMethodSemanticsAttributes() { if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[j], out var row)) continue; var method = readerModule.ResolveMethod(row.Method); - if (method == null) + if (method is null) continue; Interlocked.CompareExchange(ref method.semAttrs, row.Semantic | MethodDef.SEMATTRS_INITD, 0); @@ -2174,7 +2174,7 @@ internal void InitializeMethodSemanticsAttributes() { if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[j], out var row)) continue; var method = readerModule.ResolveMethod(row.Method); - if (method == null) + if (method is null) continue; Interlocked.CompareExchange(ref method.semAttrs, row.Semantic | MethodDef.SEMATTRS_INITD, 0); @@ -2193,7 +2193,7 @@ internal void InitializeProperty(PropertyDefMD prop, out IList getMet getMethods = new List(); setMethods = new List(); otherMethods = new List(); - if (prop == null) + if (prop is null) return; var ridList = readerModule.Metadata.GetMethodSemanticsRidList(Table.Property, prop.OrigRid); @@ -2201,7 +2201,7 @@ internal void InitializeProperty(PropertyDefMD prop, out IList getMet if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[i], out var row)) continue; var method = readerModule.ResolveMethod(row.Method); - if (method == null || method.DeclaringType != prop.DeclaringType) + if (method is null || method.DeclaringType != prop.DeclaringType) continue; // It's documented to be flags, but ignore those with more than one bit set @@ -2241,7 +2241,7 @@ internal void InitializeEvent(EventDefMD evt, out MethodDef addMethod, out Metho invokeMethod = null; removeMethod = null; otherMethods = new List(); - if (evt == null) + if (evt is null) return; var ridList = readerModule.Metadata.GetMethodSemanticsRidList(Table.Event, evt.OrigRid); @@ -2249,23 +2249,23 @@ internal void InitializeEvent(EventDefMD evt, out MethodDef addMethod, out Metho if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[i], out var row)) continue; var method = readerModule.ResolveMethod(row.Method); - if (method == null || method.DeclaringType != evt.DeclaringType) + if (method is null || method.DeclaringType != evt.DeclaringType) continue; // It's documented to be flags, but ignore those with more than one bit set switch ((MethodSemanticsAttributes)row.Semantic) { case MethodSemanticsAttributes.AddOn: - if (addMethod == null) + if (addMethod is null) addMethod = method; break; case MethodSemanticsAttributes.RemoveOn: - if (removeMethod == null) + if (removeMethod is null) removeMethod = method; break; case MethodSemanticsAttributes.Fire: - if (invokeMethod == null) + if (invokeMethod is null) invokeMethod = method; break; diff --git a/src/DotNet/TypeDefFinder.cs b/src/DotNet/TypeDefFinder.cs index 480914b5d..1e953aa3e 100644 --- a/src/DotNet/TypeDefFinder.cs +++ b/src/DotNet/TypeDefFinder.cs @@ -54,7 +54,7 @@ bool IsCacheEnabled_NoLock { if (isCacheEnabled == value) return; - if (typeEnumerator != null) { + if (!(typeEnumerator is null)) { typeEnumerator.Dispose(); typeEnumerator = null; } @@ -92,7 +92,7 @@ public TypeDefFinder(IEnumerable rootTypes, bool includeNestedTypes) { } void InitializeTypeEnumerator() { - if (typeEnumerator != null) { + if (!(typeEnumerator is null)) { typeEnumerator.Dispose(); typeEnumerator = null; } @@ -117,7 +117,7 @@ public void ResetCache() { /// public TypeDef Find(string fullName, bool isReflectionName) { - if (fullName == null) + if (fullName is null) return null; #if THREAD_SAFE theLock.EnterWriteLock(); try { @@ -132,7 +132,7 @@ public TypeDef Find(string fullName, bool isReflectionName) { /// public TypeDef Find(TypeRef typeRef) { - if (typeRef == null) + if (typeRef is null) return null; #if THREAD_SAFE theLock.EnterWriteLock(); try { @@ -151,7 +151,7 @@ TypeDef FindCache(TypeRef typeRef) { var comparer = new SigComparer(TypeComparerOptions); while (true) { cachedType = GetNextTypeDefCache(); - if (cachedType == null || comparer.Equals(cachedType, typeRef)) + if (cachedType is null || comparer.Equals(cachedType, typeRef)) return cachedType; } } @@ -163,7 +163,7 @@ TypeDef FindCacheReflection(string fullName) { // Build the cache lazily while (true) { cachedType = GetNextTypeDefCache(); - if (cachedType == null) + if (cachedType is null) return cachedType; sb.Length = 0; if (FullNameFactory.FullName(cachedType, true, null, sb) == fullName) @@ -178,7 +178,7 @@ TypeDef FindCacheNormal(string fullName) { // Build the cache lazily while (true) { cachedType = GetNextTypeDefCache(); - if (cachedType == null) + if (cachedType is null) return cachedType; sb.Length = 0; if (FullNameFactory.FullName(cachedType, false, null, sb) == fullName) @@ -191,7 +191,7 @@ TypeDef FindSlow(TypeRef typeRef) { var comparer = new SigComparer(TypeComparerOptions); while (true) { var type = GetNextTypeDef(); - if (type == null || comparer.Equals(type, typeRef)) + if (type is null || comparer.Equals(type, typeRef)) return type; } } @@ -200,7 +200,7 @@ TypeDef FindSlowReflection(string fullName) { InitializeTypeEnumerator(); while (true) { var type = GetNextTypeDef(); - if (type == null) + if (type is null) return type; sb.Length = 0; if (FullNameFactory.FullName(type, true, null, sb) == fullName) @@ -212,7 +212,7 @@ TypeDef FindSlowNormal(string fullName) { InitializeTypeEnumerator(); while (true) { var type = GetNextTypeDef(); - if (type == null) + if (type is null) return type; sb.Length = 0; if (FullNameFactory.FullName(type, false, null, sb) == fullName) @@ -227,7 +227,7 @@ TypeDef FindSlowNormal(string fullName) { TypeDef GetNextTypeDef() { while (typeEnumerator.MoveNext()) { var type = typeEnumerator.Current; - if (type != null) + if (!(type is null)) return type; } return null; @@ -241,7 +241,7 @@ TypeDef GetNextTypeDef() { /// The next or null if none TypeDef GetNextTypeDefCache() { var type = GetNextTypeDef(); - if (type == null) + if (type is null) return null; // Only insert it if another type with the exact same sig/name isn't already @@ -265,7 +265,7 @@ public void Dispose() { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (typeEnumerator != null) + if (!(typeEnumerator is null)) typeEnumerator.Dispose(); typeEnumerator = null; typeRefCache = null; diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index 01f750f88..04de27173 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -9,12 +9,12 @@ namespace dnlib.DotNet { struct TypeHelper { RecursionCounter recursionCounter; - internal static bool ContainsGenericParameter(StandAloneSig ss) => ss != null && TypeHelper.ContainsGenericParameter(ss.Signature); - internal static bool ContainsGenericParameter(InterfaceImpl ii) => ii != null && TypeHelper.ContainsGenericParameter(ii.Interface); - internal static bool ContainsGenericParameter(GenericParamConstraint gpc) => gpc != null && ContainsGenericParameter(gpc.Constraint); + internal static bool ContainsGenericParameter(StandAloneSig ss) => !(ss is null) && TypeHelper.ContainsGenericParameter(ss.Signature); + internal static bool ContainsGenericParameter(InterfaceImpl ii) => !(ii is null) && TypeHelper.ContainsGenericParameter(ii.Interface); + internal static bool ContainsGenericParameter(GenericParamConstraint gpc) => !(gpc is null) && ContainsGenericParameter(gpc.Constraint); internal static bool ContainsGenericParameter(MethodSpec ms) { - if (ms == null) + if (ms is null) return false; // A normal MethodSpec should always contain generic arguments and thus @@ -23,7 +23,7 @@ internal static bool ContainsGenericParameter(MethodSpec ms) { } internal static bool ContainsGenericParameter(MemberRef mr) { - if (mr == null) + if (mr is null) return false; if (ContainsGenericParameter(mr.Signature)) @@ -175,7 +175,7 @@ public static bool ContainsGenericParameter(IType type) { bool ContainsGenericParameterInternal(TypeRef type) => false; bool ContainsGenericParameterInternal(TypeSpec type) { - if (type == null) + if (type is null) return false; if (!recursionCounter.Increment()) return false; @@ -187,14 +187,14 @@ bool ContainsGenericParameterInternal(TypeSpec type) { } bool ContainsGenericParameterInternal(ITypeDefOrRef tdr) { - if (tdr == null) + if (tdr is null) return false; // TypeDef and TypeRef contain no generic parameters return ContainsGenericParameterInternal(tdr as TypeSpec); } bool ContainsGenericParameterInternal(TypeSig type) { - if (type == null) + if (type is null) return false; if (!recursionCounter.Increment()) return false; @@ -288,7 +288,7 @@ bool ContainsGenericParameterInternal(CallingConventionSig callConv) { } bool ContainsGenericParameterInternal(FieldSig fs) { - if (fs == null) + if (fs is null) return false; if (!recursionCounter.Increment()) return false; @@ -300,7 +300,7 @@ bool ContainsGenericParameterInternal(FieldSig fs) { } bool ContainsGenericParameterInternal(MethodBaseSig mbs) { - if (mbs == null) + if (mbs is null) return false; if (!recursionCounter.Increment()) return false; @@ -314,7 +314,7 @@ bool ContainsGenericParameterInternal(MethodBaseSig mbs) { } bool ContainsGenericParameterInternal(LocalSig ls) { - if (ls == null) + if (ls is null) return false; if (!recursionCounter.Increment()) return false; @@ -326,7 +326,7 @@ bool ContainsGenericParameterInternal(LocalSig ls) { } bool ContainsGenericParameterInternal(GenericInstMethodSig gim) { - if (gim == null) + if (gim is null) return false; if (!recursionCounter.Increment()) return false; @@ -338,7 +338,7 @@ bool ContainsGenericParameterInternal(GenericInstMethodSig gim) { } bool ContainsGenericParameter(IList types) { - if (types == null) + if (types is null) return false; if (!recursionCounter.Increment()) return false; diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index 12728ee92..9c74f47ca 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -238,7 +238,7 @@ public void Dispose() { protected virtual void Dispose(bool disposing) { if (!disposing) return; - if (reader != null) + if (!(reader is null)) reader.Dispose(); reader = null; } @@ -389,17 +389,17 @@ internal TypeSig ToTypeSig(ITypeDefOrRef type) { internal AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { AssemblyRef asmRef = null; - if (nonNestedTypeRef != null && typeNameParserHelper != null) + if (!(nonNestedTypeRef is null) && !(typeNameParserHelper is null)) asmRef = typeNameParserHelper.FindAssemblyRef(nonNestedTypeRef); - if (asmRef != null) + if (!(asmRef is null)) return asmRef; var ownerAsm = ownerModule.Assembly; - if (ownerAsm != null) + if (!(ownerAsm is null)) return ownerModule.UpdateRowId(ownerAsm.ToAssemblyRef()); return AssemblyRef.CurrentAssembly; } - internal bool IsValueType(TypeRef typeRef) => typeRef != null && typeRef.IsValueType; + internal bool IsValueType(TypeRef typeRef) => !(typeRef is null) && typeRef.IsValueType; internal static void Verify(bool b, string msg) { if (!b) @@ -574,12 +574,12 @@ TypeSig ReadType(bool readAssemblyReference) { result = null; if (typeRef == nonNestedTypeRef) { var corLibSig = ownerModule.CorLibTypes.GetCorLibTypeSig(typeRef.Namespace, typeRef.Name, typeRef.DefinitionAssembly); - if (corLibSig != null) + if (!(corLibSig is null)) result = corLibSig; } - if (result == null) { + if (result is null) { var typeDef = Resolve(asmRef, typeRef); - result = ToTypeSig(typeDef != null ? (ITypeDefOrRef)typeDef : typeRef); + result = ToTypeSig(!(typeDef is null) ? (ITypeDefOrRef)typeDef : typeRef); } if (tspecs.Count != 0) @@ -592,12 +592,12 @@ TypeSig ReadType(bool readAssemblyReference) { TypeDef Resolve(AssemblyRef asmRef, TypeRef typeRef) { var asm = ownerModule.Assembly; - if (asm == null) + if (asm is null) return null; if (!(AssemblyNameComparer.CompareAll.Equals(asmRef, asm) && asmRef.IsRetargetable == asm.IsRetargetable)) return null; var td = asm.Find(typeRef); - return td != null && td.Module == ownerModule ? td : null; + return !(td is null) && td.Module == ownerModule ? td : null; } AssemblyRef ReadOptionalAssemblyRef() { @@ -721,7 +721,7 @@ IList ReadTSpecs() { AssemblyRef ReadAssemblyRef() { var asmRef = new AssemblyRefUser(); - if (ownerModule != null) + if (!(ownerModule is null)) ownerModule.UpdateRowId(asmRef); asmRef.Name = ReadAssemblyNameId(); diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index 1390df475..82277e9fa 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -156,7 +156,7 @@ public UTF8String Namespace { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -181,7 +181,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -195,13 +195,13 @@ protected virtual void InitializeCustomDebugInfos() => /// /// true if it's nested within another /// - public bool IsNested => DeclaringType != null; + public bool IsNested => !(DeclaringType is null); /// public bool IsValueType { get { var td = Resolve(); - return td != null && td.IsValueType; + return !(td is null) && td.IsValueType; } } @@ -242,7 +242,7 @@ public bool IsValueType { /// The module that needs to resolve the type or null /// A instance or null if it couldn't be resolved public TypeDef Resolve(ModuleDef sourceModule) { - if (module == null) + if (module is null) return null; return module.Context.Resolver.Resolve(this, sourceModule ?? module); } @@ -262,7 +262,7 @@ public TypeDef Resolve(ModuleDef sourceModule) { /// If the type couldn't be resolved public TypeDef ResolveThrow(ModuleDef sourceModule) { var type = Resolve(sourceModule); - if (type != null) + if (!(type is null)) return type; throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); } @@ -273,11 +273,11 @@ public TypeDef ResolveThrow(ModuleDef sourceModule) { /// Input /// The non-nested or null internal static TypeRef GetNonNestedTypeRef(TypeRef typeRef) { - if (typeRef == null) + if (typeRef is null) return null; for (int i = 0; i < 1000; i++) { var next = typeRef.ResolutionScope as TypeRef; - if (next == null) + if (next is null) return typeRef; typeRef = next; } @@ -367,7 +367,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public TypeRefMD(ModuleDefMD readerModule, uint rid) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.TypeRefTable.IsInvalidRID(rid)) throw new BadImageFormatException($"TypeRef rid {rid} does not exist"); diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index 2afb84feb..e91da4587 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -71,7 +71,7 @@ public uint Rid { int IGenericParameterProvider.NumberOfGenericParameters { get { var type = this.RemovePinnedAndModifiers() as GenericInstSig; - return type == null ? 0 : type.GenericArguments.Count; + return type is null ? 0 : type.GenericArguments.Count; } } @@ -79,12 +79,12 @@ int IGenericParameterProvider.NumberOfGenericParameters { public bool IsValueType { get { var t = this.RemovePinnedAndModifiers(); - if (t == null) + if (t is null) return false; if (t.ElementType == ElementType.GenericInst) { var gis = (GenericInstSig)t; t = gis.GenericType; - if (t == null) + if (t is null) return false; } return t.ElementType.IsValueType(); @@ -255,11 +255,11 @@ public static partial class Extensions { /// A instance /// Input after all modifiers public static TypeSig RemoveModifiers(this TypeSig a) { - if (a == null) + if (a is null) return null; while (true) { var modifier = a as ModifierSig; - if (modifier == null) + if (modifier is null) return a; a = a.Next; } @@ -272,7 +272,7 @@ public static TypeSig RemoveModifiers(this TypeSig a) { /// Input after pinned signature public static TypeSig RemovePinned(this TypeSig a) { var pinned = a as PinnedSig; - if (pinned == null) + if (pinned is null) return a; return pinned.Next; } @@ -398,7 +398,7 @@ public static TypeSig RemovePinnedAndModifiers(this TypeSig a) { /// /// this /// - public static bool GetIsValueType(this TypeSig self) => self == null ? false : self.IsValueType; + public static bool GetIsValueType(this TypeSig self) => self is null ? false : self.IsValueType; /// /// Gets the value or false if @@ -406,35 +406,35 @@ public static TypeSig RemovePinnedAndModifiers(this TypeSig a) { /// /// this /// - public static bool GetIsPrimitive(this TypeSig self) => self == null ? false : self.IsPrimitive; + public static bool GetIsPrimitive(this TypeSig self) => self is null ? false : self.IsPrimitive; /// /// Gets the element type /// /// this /// The element type - public static ElementType GetElementType(this TypeSig a) => a == null ? ElementType.End : a.ElementType; + public static ElementType GetElementType(this TypeSig a) => a is null ? ElementType.End : a.ElementType; /// /// Gets the full name of the type /// /// this /// Full name of the type - public static string GetFullName(this TypeSig a) => a == null ? string.Empty : a.FullName; + public static string GetFullName(this TypeSig a) => a is null ? string.Empty : a.FullName; /// /// Gets the name of the type /// /// this /// Name of the type - public static string GetName(this TypeSig a) => a == null ? string.Empty : a.TypeName; + public static string GetName(this TypeSig a) => a is null ? string.Empty : a.TypeName; /// /// Gets the namespace of the type /// /// this /// Namespace of the type - public static string GetNamespace(this TypeSig a) => a == null ? string.Empty : a.Namespace; + public static string GetNamespace(this TypeSig a) => a is null ? string.Empty : a.Namespace; /// /// Returns the if it is a . @@ -483,17 +483,17 @@ public abstract class TypeDefOrRefSig : LeafSig { /// /// Returns true if != null /// - public bool IsTypeRef => TypeRef != null; + public bool IsTypeRef => !(TypeRef is null); /// /// Returns true if != null /// - public bool IsTypeDef => TypeDef != null; + public bool IsTypeDef => !(TypeDef is null); /// /// Returns true if != null /// - public bool IsTypeSpec => TypeSpec != null; + public bool IsTypeSpec => !(TypeSpec is null); /// /// Gets the or null if it's not a @@ -599,19 +599,19 @@ public abstract class GenericSig : LeafSig { /// /// true if it has an owner or /// - public bool HasOwner => genericParamProvider != null; + public bool HasOwner => !(genericParamProvider is null); /// /// true if it has an owner ( is /// not null) /// - public bool HasOwnerType => OwnerType != null; + public bool HasOwnerType => !(OwnerType is null); /// /// true if it has an owner ( is /// not null) /// - public bool HasOwnerMethod => OwnerMethod != null; + public bool HasOwnerMethod => !(OwnerMethod is null); /// /// Gets the owner type or null if the owner is a or if it @@ -636,7 +636,7 @@ public abstract class GenericSig : LeafSig { public GenericParam GenericParam { get { var gpp = genericParamProvider; - if (gpp == null) + if (gpp is null) return null; var gps = gpp.GenericParameters; int count = gps.Count; diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index 57d906ed5..8465edd03 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -44,7 +44,7 @@ public uint Rid { int IGenericParameterProvider.NumberOfGenericParameters { get { var ts = TypeSig; - return ts == null ? 0 : ((IGenericParameterProvider)ts).NumberOfGenericParameters; + return ts is null ? 0 : ((IGenericParameterProvider)ts).NumberOfGenericParameters; } } @@ -52,11 +52,11 @@ int IGenericParameterProvider.NumberOfGenericParameters { UTF8String IFullName.Name { get { var mr = ScopeType; - return mr == null ? UTF8String.Empty : mr.Name; + return mr is null ? UTF8String.Empty : mr.Name; } set { var mr = ScopeType; - if (mr != null) + if (!(mr is null)) mr.Name = value; } } @@ -97,7 +97,7 @@ ITypeDefOrRef IMemberRef.DeclaringType { public bool IsValueType { get { var sig = TypeSig; - return sig != null && sig.IsValueType; + return !(sig is null) && sig.IsValueType; } } @@ -105,7 +105,7 @@ public bool IsValueType { public bool IsPrimitive { get { var sig = TypeSig; - return sig != null && sig.IsPrimitive; + return !(sig is null) && sig.IsPrimitive; } } @@ -213,7 +213,7 @@ protected virtual TypeSig GetTypeSigAndExtraData_NoLock(out byte[] extraData) { /// public CustomAttributeCollection CustomAttributes { get { - if (customAttributes == null) + if (customAttributes is null) InitializeCustomAttributes(); return customAttributes; } @@ -239,7 +239,7 @@ protected virtual void InitializeCustomAttributes() => /// public IList CustomDebugInfos { get { - if (customDebugInfos == null) + if (customDebugInfos is null) InitializeCustomDebugInfos(); return customDebugInfos; } @@ -291,7 +291,7 @@ sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD { /// protected override TypeSig GetTypeSigAndExtraData_NoLock(out byte[] extraData) { var sig = readerModule.ReadTypeSignature(signatureOffset, gpContext, out extraData); - if (sig != null) + if (!(sig is null)) sig.Rid = origRid; return sig; } @@ -320,7 +320,7 @@ protected override void InitializeCustomDebugInfos() { /// If is invalid public TypeSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { #if DEBUG - if (readerModule == null) + if (readerModule is null) throw new ArgumentNullException("readerModule"); if (readerModule.TablesStream.TypeSpecTable.IsInvalidRID(rid)) throw new BadImageFormatException($"TypeSpec rid {rid} does not exist"); diff --git a/src/DotNet/UTF8String.cs b/src/DotNet/UTF8String.cs index a222c7ece..2397ee226 100644 --- a/src/DotNet/UTF8String.cs +++ b/src/DotNet/UTF8String.cs @@ -45,7 +45,7 @@ public sealed class UTF8String : IEquatable, IComparable /// public string String { get { - if (asString == null) + if (asString is null) asString = ConvertFromUTF8(data); return asString; } @@ -67,14 +67,14 @@ public string String { /// Gets the length of the raw data. It's the same as Data.Length /// /// - public int DataLength => data == null ? 0 : data.Length; + public int DataLength => data is null ? 0 : data.Length; /// /// Checks whether is null or if its data is null. /// /// The instance to check /// true if null or empty, false otherwise - public static bool IsNull(UTF8String utf8) => (object)utf8 == null || utf8.data == null; + public static bool IsNull(UTF8String utf8) => utf8 is null || utf8.data is null; /// /// Checks whether is null or if its data is null or the @@ -82,13 +82,13 @@ public string String { /// /// The instance to check /// true if null or empty, false otherwise - public static bool IsNullOrEmpty(UTF8String utf8) => (object)utf8 == null || utf8.data == null || utf8.data.Length == 0; + public static bool IsNullOrEmpty(UTF8String utf8) => utf8 is null || utf8.data is null || utf8.data.Length == 0; /// Implicit conversion from to public static implicit operator string(UTF8String s) => UTF8String.ToSystemString(s); /// Implicit conversion from to - public static implicit operator UTF8String(string s) => s == null ? null : new UTF8String(s); + public static implicit operator UTF8String(string s) => s is null ? null : new UTF8String(s); /// /// Converts it to a @@ -96,7 +96,7 @@ public string String { /// The UTF-8 string instace or null /// A or null if is null public static string ToSystemString(UTF8String utf8) { - if ((object)utf8 == null || utf8.data == null) + if (utf8 is null || utf8.data is null) return null; if (utf8.data.Length == 0) return string.Empty; @@ -144,9 +144,9 @@ public static int CaseInsensitiveCompareTo(UTF8String a, UTF8String b) { var sb = ToSystemString(b); if ((object)sa == (object)sb) return 0; - if (sa == null) + if (sa is null) return -1; - if (sb == null) + if (sb is null) return 1; return StringComparer.OrdinalIgnoreCase.Compare(sa, sb); } @@ -200,11 +200,11 @@ public static int CaseInsensitiveCompareTo(UTF8String a, UTF8String b) { /// /// The string public UTF8String(string s) - : this(s == null ? null : Encoding.UTF8.GetBytes(s)) { + : this(s is null ? null : Encoding.UTF8.GetBytes(s)) { } static string ConvertFromUTF8(byte[] data) { - if (data == null) + if (data is null) return null; try { return Encoding.UTF8.GetString(data); @@ -228,7 +228,7 @@ static string ConvertFromUTF8(byte[] data) { /// public override bool Equals(object obj) { var other = obj as UTF8String; - if ((object)other == null) + if (other is null) return false; return CompareTo(this, other) == 0; } diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index 63e463655..35b346e96 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -40,19 +40,19 @@ internal static string GetAssemblyNameString(UTF8String name, Version version, U sb.Append(c); } - if (version != null) { + if (!(version is null)) { sb.Append(", Version="); sb.Append(CreateVersionWithNoUndefinedValues(version).ToString()); } - if ((object)culture != null) { + if (!(culture is null)) { sb.Append(", Culture="); sb.Append(UTF8String.IsNullOrEmpty(culture) ? "neutral" : culture.String); } sb.Append(", "); - sb.Append(publicKey == null || publicKey is PublicKeyToken ? "PublicKeyToken=" : "PublicKey="); - sb.Append(publicKey == null ? "null" : publicKey.ToString()); + sb.Append(publicKey is null || publicKey is PublicKeyToken ? "PublicKeyToken=" : "PublicKey="); + sb.Append(publicKey is null ? "null" : publicKey.ToString()); if ((attributes & AssemblyAttributes.Retargetable) != 0) sb.Append(", Retargetable=Yes"); @@ -70,7 +70,7 @@ internal static string GetAssemblyNameString(UTF8String name, Version version, U /// true if output should be in upper case hex /// as a hex string internal static string ToHex(byte[] bytes, bool upper) { - if (bytes == null) + if (bytes is null) return ""; var chars = new char[bytes.Length * 2]; for (int i = 0, j = 0; i < bytes.Length; i++) { @@ -137,9 +137,9 @@ static int TryParseHexChar(char c) { internal static int CompareTo(byte[] a, byte[] b) { if (a == b) return 0; - if (a == null) + if (a is null) return -1; - if (b == null) + if (b is null) return 1; int count = Math.Min(a.Length, b.Length); for (int i = 0; i < count; i++) { @@ -162,7 +162,7 @@ internal static int CompareTo(byte[] a, byte[] b) { internal static bool Equals(byte[] a, byte[] b) { if (a == b) return true; - if (a == null || b == null) + if (a is null || b is null) return false; if (a.Length != b.Length) return false; @@ -179,7 +179,7 @@ internal static bool Equals(byte[] a, byte[] b) { /// Byte array /// The hash code internal static int GetHashCode(byte[] a) { - if (a == null || a.Length == 0) + if (a is null || a.Length == 0) return 0; int count = Math.Min(a.Length / 2, 20); if (count == 0) @@ -202,9 +202,9 @@ internal static int GetHashCode(byte[] a) { /// Version #2 or null to be treated as v0.0.0.0 /// < 0 if a < b, 0 if a == b, > 0 if a > b internal static int CompareTo(Version a, Version b) { - if (a == null) + if (a is null) a = new Version(); - if (b == null) + if (b is null) b = new Version(); if (a.Major != b.Major) return a.Major.CompareTo(b.Major); @@ -233,7 +233,7 @@ internal static int CompareTo(Version a, Version b) { /// A instance /// A new instance internal static Version CreateVersionWithNoUndefinedValues(Version a) { - if (a == null) + if (a is null) return new Version(0, 0, 0, 0); return new Version(a.Major, a.Minor, GetDefaultVersionValue(a.Build), GetDefaultVersionValue(a.Revision)); } diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index 279a2887f..6b06b4993 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -172,7 +172,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { var mscorlib = module?.CorLibTypes.AssemblyRef; var asm = new AssemblyRefUser(GetName(clrAsm), contractAsmVersion, new PublicKeyToken(GetPublicKeyToken(clrAsm)), UTF8String.Empty); - if (mscorlib != null && mscorlib.Name == mscorlibName && IsValidMscorlibVersion(mscorlib.Version)) + if (!(mscorlib is null) && mscorlib.Name == mscorlibName && IsValidMscorlibVersion(mscorlib.Version)) asm.Version = mscorlib.Version; if (module is ModuleDefMD mod) { Version ver = null; @@ -188,10 +188,10 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { if (!IsValidMscorlibVersion(asmRef.Version)) continue; - if (ver == null || asmRef.Version > ver) + if (ver is null || asmRef.Version > ver) ver = asmRef.Version; } - if (ver != null) + if (!(ver is null)) asm.Version = ver; } @@ -201,7 +201,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { static readonly UTF8String mscorlibName = new UTF8String("mscorlib"); // Silverlight uses 5.0.5.0 - static bool IsValidMscorlibVersion(Version version) => version != null && (uint)version.Major <= 5; + static bool IsValidMscorlibVersion(Version version) => !(version is null) && (uint)version.Major <= 5; static UTF8String GetName(ClrAssembly clrAsm) { switch (clrAsm) { @@ -257,10 +257,10 @@ static byte[] GetPublicKeyToken(ClrAssembly clrAsm) { /// public static TypeRef ToCLR(ModuleDef module, TypeDef td, out bool isClrValueType) { isClrValueType = false; - if (td == null || !td.IsWindowsRuntime) + if (td is null || !td.IsWindowsRuntime) return null; var asm = td.DefinitionAssembly; - if (asm == null || !asm.IsContentTypeWindowsRuntime) + if (asm is null || !asm.IsContentTypeWindowsRuntime) return null; if (!winMDToCLR.TryGetValue(new ClassName(td.Namespace, td.Name), out var pc)) @@ -289,12 +289,12 @@ public static TypeRef ToCLR(ModuleDef module, TypeDef td, out bool isClrValueTyp /// public static TypeRef ToCLR(ModuleDef module, TypeRef tr, out bool isClrValueType) { isClrValueType = false; - if (tr == null) + if (tr is null) return null; var defAsm = tr.DefinitionAssembly; - if (defAsm == null || !defAsm.IsContentTypeWindowsRuntime) + if (defAsm is null || !defAsm.IsContentTypeWindowsRuntime) return null; - if (tr.DeclaringType != null) + if (!(tr.DeclaringType is null)) return null; if (!winMDToCLR.TryGetValue(new ClassName(tr.Namespace, tr.Name), out var pc)) @@ -312,12 +312,12 @@ public static TypeRef ToCLR(ModuleDef module, TypeRef tr, out bool isClrValueTyp /// Type /// public static ExportedType ToCLR(ModuleDef module, ExportedType et) { - if (et == null) + if (et is null) return null; var defAsm = et.DefinitionAssembly; - if (defAsm == null || !defAsm.IsContentTypeWindowsRuntime) + if (defAsm is null || !defAsm.IsContentTypeWindowsRuntime) return null; - if (et.DeclaringType != null) + if (!(et.DeclaringType is null)) return null; if (!winMDToCLR.TryGetValue(new ClassName(et.TypeNamespace, et.TypeName), out var pc)) @@ -334,7 +334,7 @@ public static ExportedType ToCLR(ModuleDef module, ExportedType et) { /// Type /// public static TypeSig ToCLR(ModuleDef module, TypeSig ts) { - if (ts == null) + if (ts is null) return null; var et = ts.ElementType; if (et != ElementType.Class && et != ElementType.ValueType) @@ -346,12 +346,12 @@ public static TypeSig ToCLR(ModuleDef module, TypeSig ts) { bool isClrValueType; if (tdr is TypeDef td) { newTr = ToCLR(module, td, out isClrValueType); - if (newTr == null) + if (newTr is null) return null; } - else if ((tr = tdr as TypeRef) != null) { + else if (!((tr = tdr as TypeRef) is null)) { newTr = ToCLR(module, tr, out isClrValueType); - if (newTr == null) + if (newTr is null) return null; } else @@ -372,13 +372,13 @@ public static TypeSig ToCLR(ModuleDef module, TypeSig ts) { public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { // See WinMDAdapter::CheckIfMethodImplImplementsARedirectedInterface // in coreclr: md/winmd/adapter.cpp - if (mr == null) + if (mr is null) return null; if (mr.Name != CloseName) return null; var msig = mr.MethodSig; - if (msig == null) + if (msig is null) return null; var cl = mr.Class; @@ -386,21 +386,21 @@ public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { TypeSpec ts; if (cl is TypeRef tr) { var newTr = ToCLR(module, tr); - if (newTr == null || !IsIDisposable(newTr)) + if (newTr is null || !IsIDisposable(newTr)) return null; newCl = newTr; } - else if ((ts = cl as TypeSpec) != null) { + else if (!((ts = cl as TypeSpec) is null)) { var gis = ts.TypeSig as GenericInstSig; - if (gis == null || !(gis.GenericType is ClassSig)) + if (gis is null || !(gis.GenericType is ClassSig)) return null; tr = gis.GenericType.TypeRef; - if (tr == null) + if (tr is null) return null; var newTr = ToCLR(module, tr, out bool isClrValueType); - if (newTr == null || !IsIDisposable(newTr)) + if (newTr is null || !IsIDisposable(newTr)) return null; newCl = new TypeSpecUser(new GenericInstSig(isClrValueType ? @@ -427,16 +427,16 @@ public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { /// Method /// public static MemberRef ToCLR(ModuleDef module, MethodDef md) { - if (md == null) + if (md is null) return null; if (md.Name != CloseName) return null; var declType = md.DeclaringType; - if (declType == null) + if (declType is null) return null; var tr = ToCLR(module, declType); - if (tr == null || !IsIDisposable(tr)) + if (tr is null || !IsIDisposable(tr)) return null; return new MemberRefUser(md.Module, DisposeName, md.MethodSig, tr); diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index 129f777ef..908c7180a 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -28,11 +28,11 @@ public sealed class BlobHeap : HeapBase, IOffsetHeap { public void Populate(BlobStream blobStream) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Blob when it's read-only"); - if (originalData != null) + if (!(originalData is null)) throw new InvalidOperationException("Can't call method twice"); if (nextOffset != 1) throw new InvalidOperationException("Add() has already been called"); - if (blobStream == null || blobStream.StreamLength == 0) + if (blobStream is null || blobStream.StreamLength == 0) return; var reader = blobStream.CreateReader(); @@ -67,7 +67,7 @@ void Populate(ref DataReader reader) { public uint Add(byte[] data) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Blob when it's read-only"); - if (data == null || data.Length == 0) + if (data is null || data.Length == 0) return 0; if (cachedDict.TryGetValue(data, out uint offset)) @@ -99,15 +99,15 @@ uint AddToCache(byte[] data) { /// protected override void WriteToImpl(DataWriter writer) { - if (originalData != null) + if (!(originalData is null)) writer.WriteBytes(originalData); else writer.WriteByte(0); - uint offset = originalData != null ? (uint)originalData.Length : 1; + uint offset = !(originalData is null) ? (uint)originalData.Length : 1; foreach (var data in cached) { int rawLen = GetRawDataSize(data); - if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { + if (!(userRawData is null) && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); writer.WriteBytes(rawData); @@ -125,7 +125,7 @@ protected override void WriteToImpl(DataWriter writer) { /// public void SetRawData(uint offset, byte[] rawData) { - if (userRawData == null) + if (userRawData is null) userRawData = new Dictionary(); userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); } @@ -134,7 +134,7 @@ public void SetRawData(uint offset, byte[] rawData) { public IEnumerable> GetAllRawData() { var memStream = new MemoryStream(); var writer = new DataWriter(memStream); - uint offset = originalData != null ? (uint)originalData.Length : 1; + uint offset = !(originalData is null) ? (uint)originalData.Length : 1; foreach (var data in cached) { memStream.Position = 0; memStream.SetLength(0); diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 8ff323493..6dc9deb13 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -57,7 +57,7 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public override bool Equals(object obj) { var other = obj as ByteArrayChunk; - return other != null && Utils.Equals(array, other.array); + return !(other is null) && Utils.Equals(array, other.array); } } } diff --git a/src/DotNet/Writer/ChunkList.cs b/src/DotNet/Writer/ChunkList.cs index ab55dba81..8ca6a008a 100644 --- a/src/DotNet/Writer/ChunkList.cs +++ b/src/DotNet/Writer/ChunkList.cs @@ -21,7 +21,7 @@ public class ChunkList : ChunkListBase where T : class, IChunk { public void Add(T chunk, uint alignment) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); - if (chunk != null) + if (!(chunk is null)) chunks.Add(new Elem(chunk, alignment)); } @@ -33,7 +33,7 @@ public void Add(T chunk, uint alignment) { public uint? Remove(T chunk) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); - if (chunk != null) { + if (!(chunk is null)) { var chunks = this.chunks; for (int i = 0; i < chunks.Count; i++) { if (chunks[i].chunk == chunk) { diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index 2d61c8428..e8e61cb2f 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -85,7 +85,7 @@ internal static byte[] Write(ICustomAttributeWriterHelper helper, IList outStream.ToArray(); void Write(CustomAttribute ca) { - if (ca == null) { + if (ca is null) { helper.Error("The custom attribute is null"); return; } @@ -93,26 +93,26 @@ void Write(CustomAttribute ca) { // Check whether it's raw first. If it is, we don't care whether the ctor is // invalid. Just use the raw data. if (ca.IsRawBlob) { - if ((ca.ConstructorArguments != null && ca.ConstructorArguments.Count > 0) || (ca.NamedArguments != null && ca.NamedArguments.Count > 0)) + if ((!(ca.ConstructorArguments is null) && ca.ConstructorArguments.Count > 0) || (!(ca.NamedArguments is null) && ca.NamedArguments.Count > 0)) helper.Error("Raw custom attribute contains arguments and/or named arguments"); writer.WriteBytes(ca.RawData); return; } - if (ca.Constructor == null) { + if (ca.Constructor is null) { helper.Error("Custom attribute ctor is null"); return; } var methodSig = GetMethodSig(ca.Constructor); - if (methodSig == null) { + if (methodSig is null) { helper.Error("Custom attribute ctor's method signature is invalid"); return; } if (ca.ConstructorArguments.Count != methodSig.Params.Count) helper.Error("Custom attribute arguments count != method sig arguments count"); - if (methodSig.ParamsAfterSentinel != null && methodSig.ParamsAfterSentinel.Count > 0) + if (!(methodSig.ParamsAfterSentinel is null) && methodSig.ParamsAfterSentinel.Count > 0) helper.Error("Custom attribute ctor has parameters after the sentinel"); if (ca.NamedArguments.Count > ushort.MaxValue) helper.Error("Custom attribute has too many named arguments"); @@ -135,7 +135,7 @@ void Write(CustomAttribute ca) { } void Write(IList namedArgs) { - if (namedArgs == null || namedArgs.Count > 0x1FFFFFFF) { + if (namedArgs is null || namedArgs.Count > 0x1FFFFFFF) { helper.Error("Too many custom attribute named arguments"); namedArgs = Array2.Empty(); } @@ -147,13 +147,13 @@ void Write(IList namedArgs) { TypeSig FixTypeSig(TypeSig type) => SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); TypeSig SubstituteGenericParameter(TypeSig type) { - if (genericArguments == null) + if (genericArguments is null) return type; return genericArguments.Resolve(type); } void WriteValue(TypeSig argType, CAArgument value) { - if (argType == null || value.Type == null) { + if (argType is null || value.Type is null) { helper.Error("Custom attribute argument type is null"); return; } @@ -164,7 +164,7 @@ void WriteValue(TypeSig argType, CAArgument value) { if (argType is SZArraySig arrayType) { var argsArray = value.Value as IList; - if (argsArray == null && value.Value != null) + if (argsArray is null && !(value.Value is null)) helper.Error("CAArgument.Value is not null or an array"); WriteArrayValue(arrayType, argsArray); } @@ -175,12 +175,12 @@ void WriteValue(TypeSig argType, CAArgument value) { } void WriteArrayValue(SZArraySig arrayType, IList args) { - if (arrayType == null) { + if (arrayType is null) { helper.Error("Custom attribute: Array type is null"); return; } - if (args == null) + if (args is null) writer.WriteUInt32(uint.MaxValue); else { writer.WriteUInt32((uint)args.Count); @@ -207,17 +207,17 @@ bool VerifyTypeAndValue(CAArgument value, ElementType etype, Type valueType) { helper.Error("Custom attribute arg type != value.Type"); return false; } - return value.Value == null || value.Value.GetType() == valueType; + return value.Value is null || value.Value.GetType() == valueType; } static bool VerifyType(TypeSig type, ElementType etype) { type = type.RemoveModifiers(); // Assume it's an enum if it's a ValueType - return type != null && (etype == type.ElementType || type.ElementType == ElementType.ValueType); + return !(type is null) && (etype == type.ElementType || type.ElementType == ElementType.ValueType); } static bool VerifyValue(object o, ElementType etype) { - if (o == null) + if (o is null) return false; switch (Type.GetTypeCode(o.GetType())) { @@ -243,7 +243,7 @@ static ulong ToUInt64(object o) { } static bool ToUInt64(object o, out ulong result) { - if (o == null) { + if (o is null) { result = 0; return false; } @@ -308,7 +308,7 @@ static double ToDouble(object o) { } static bool ToDouble(object o, out double result) { - if (o == null) { + if (o is null) { result = double.NaN; return false; } @@ -373,10 +373,10 @@ static bool ToDouble(object o, out double result) { /// The ctor arg type, field type, or property type /// The value to write void WriteElem(TypeSig argType, CAArgument value) { - if (argType == null) { + if (argType is null) { helper.Error("Custom attribute: Arg type is null"); argType = value.Type; - if (argType == null) + if (argType is null) return; } if (!recursionCounter.Increment()) { @@ -483,7 +483,7 @@ void WriteElem(TypeSig argType, CAArgument value) { case ElementType.ValueType: tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; underlyingType = GetEnumUnderlyingType(argType); - if (underlyingType != null) + if (!(underlyingType is null)) WriteElem(underlyingType, value); else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value)) { // No error. Assume it's an enum that couldn't be resolved. @@ -498,7 +498,7 @@ void WriteElem(TypeSig argType, CAArgument value) { if (CheckCorLibType(value.Type, "Type")) { if (value.Value is TypeSig ts) WriteType(ts); - else if (value.Value == null) + else if (value.Value is null) WriteUTF8String(null); else { helper.Error("Custom attribute value is not a type"); @@ -555,7 +555,7 @@ void WriteElem(TypeSig argType, CAArgument value) { } bool TryWriteEnumUnderlyingTypeValue(object o) { - if (o == null) + if (o is null) return false; switch (Type.GetTypeCode(o.GetType())) { case TypeCode.Boolean: writer.WriteBoolean((bool)o); break; @@ -580,16 +580,16 @@ bool TryWriteEnumUnderlyingTypeValue(object o) { /// The underlying type or null if we couldn't resolve the type ref static TypeSig GetEnumUnderlyingType(TypeSig type) { var td = GetEnumTypeDef(type); - if (td == null) + if (td is null) return null; return td.GetEnumUnderlyingType().RemoveModifiers(); } static TypeDef GetEnumTypeDef(TypeSig type) { - if (type == null) + if (type is null) return null; var td = GetTypeDef(type); - if (td == null) + if (td is null) return null; if (!td.IsEnum) return null; @@ -606,11 +606,11 @@ static TypeDef GetEnumTypeDef(TypeSig type) { static TypeDef GetTypeDef(TypeSig type) { if (type is TypeDefOrRefSig tdr) { var td = tdr.TypeDef; - if (td != null) + if (!(td is null)) return td; var tr = tdr.TypeRef; - if (tr != null) + if (!(tr is null)) return tr.Resolve(); } @@ -618,7 +618,7 @@ static TypeDef GetTypeDef(TypeSig type) { } void Write(CANamedArgument namedArg) { - if (namedArg == null) { + if (namedArg is null) { helper.Error("Custom attribute named arg is null"); return; } @@ -641,7 +641,7 @@ void Write(CANamedArgument namedArg) { void WriteFieldOrPropType(TypeSig type) { type = type.RemoveModifiers(); - if (type == null) { + if (type is null) { helper.Error("Custom attribute: Field/property type is null"); return; } @@ -690,7 +690,7 @@ void WriteFieldOrPropType(TypeSig type) { tdr = ((TypeDefOrRefSig)type).TypeDefOrRef; var enumType = GetEnumTypeDef(type); // If TypeRef => assume it's an enum that couldn't be resolved - if (enumType != null || tdr is TypeRef) { + if (!(enumType is null) || tdr is TypeRef) { writer.WriteByte((byte)SerializationType.Enum); WriteType(tdr); } @@ -711,7 +711,7 @@ void WriteFieldOrPropType(TypeSig type) { } void WriteType(IType type) { - if (type == null) { + if (type is null) { helper.Error("Custom attribute: Type is null"); WriteUTF8String(UTF8String.Empty); } @@ -721,13 +721,13 @@ void WriteType(IType type) { static bool CheckCorLibType(TypeSig ts, string name) { var tdrs = ts as TypeDefOrRefSig; - if (tdrs == null) + if (tdrs is null) return false; return CheckCorLibType(tdrs.TypeDefOrRef, name); } static bool CheckCorLibType(ITypeDefOrRef tdr, string name) { - if (tdr == null) + if (tdr is null) return false; if (!tdr.DefinitionAssembly.IsCorLib()) return false; @@ -739,7 +739,7 @@ static bool CheckCorLibType(ITypeDefOrRef tdr, string name) { static MethodSig GetMethodSig(ICustomAttributeType ctor) => ctor?.MethodSig; void WriteUTF8String(UTF8String s) { - if ((object)s == null || s.Data == null) + if (s is null || s.Data is null) writer.WriteByte((byte)0xFF); else { writer.WriteCompressedUInt32((uint)s.Data.Length); @@ -751,7 +751,7 @@ void WriteUTF8String(UTF8String s) { public void Dispose() { if (!disposeStream) return; - if (outStream != null) + if (!(outStream is null)) outStream.Dispose(); } } diff --git a/src/DotNet/Writer/DataWriter.cs b/src/DotNet/Writer/DataWriter.cs index dd5bacdf6..50a5eb242 100644 --- a/src/DotNet/Writer/DataWriter.cs +++ b/src/DotNet/Writer/DataWriter.cs @@ -27,7 +27,7 @@ public long Position { /// /// Destination stream public DataWriter(Stream stream) { - if (stream == null) + if (stream is null) ThrowArgumentNullException(nameof(stream)); this.stream = stream; buffer = new byte[BUFFER_LEN]; diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 3905ad4dd..c7ac959b4 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -34,11 +34,11 @@ internal static byte[] Write(ModuleDef module, IList secAttrs } byte[] Write(IList secAttrs) { - if (secAttrs == null) + if (secAttrs is null) secAttrs = Array2.Empty(); var xml = DeclSecurity.GetNet1xXmlStringInternal(secAttrs); - if (xml != null) + if (!(xml is null)) return WriteFormat1(xml); return WriteFormat2(secAttrs); } @@ -54,7 +54,7 @@ byte[] WriteFormat2(IList secAttrs) { int count = secAttrs.Count; for (int i = 0; i < count; i++) { var sa = secAttrs[i]; - if (sa == null) { + if (sa is null) { helper.Error("SecurityAttribute is null"); Write(writer, UTF8String.Empty); WriteCompressedUInt32(writer, 1); @@ -63,7 +63,7 @@ byte[] WriteFormat2(IList secAttrs) { } var attrType = sa.AttributeType; string fqn; - if (attrType == null) { + if (attrType is null) { helper.Error("SecurityAttribute attribute type is null"); fqn = string.Empty; } @@ -71,7 +71,7 @@ byte[] WriteFormat2(IList secAttrs) { fqn = attrType.AssemblyQualifiedName; Write(writer, fqn); - var namedArgsBlob = context == null ? + var namedArgsBlob = context is null ? CustomAttributeWriter.Write(this, sa.NamedArguments) : CustomAttributeWriter.Write(this, sa.NamedArguments, context); if (namedArgsBlob.Length > 0x1FFFFFFF) { diff --git a/src/DotNet/Writer/GuidHeap.cs b/src/DotNet/Writer/GuidHeap.cs index 3c12e9ad6..0d674d155 100644 --- a/src/DotNet/Writer/GuidHeap.cs +++ b/src/DotNet/Writer/GuidHeap.cs @@ -22,7 +22,7 @@ public sealed class GuidHeap : HeapBase, IOffsetHeap { public uint Add(Guid? guid) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #GUID when it's read-only"); - if (guid == null) + if (guid is null) return 0; if (guids.TryGetValue(guid.Value, out uint index)) @@ -40,7 +40,7 @@ public uint Add(Guid? guid) { protected override void WriteToImpl(DataWriter writer) { uint offset = 0; foreach (var kv in guids) { - if (userRawData == null || !userRawData.TryGetValue(offset, out var rawData)) + if (userRawData is null || !userRawData.TryGetValue(offset, out var rawData)) rawData = kv.Key.ToByteArray(); writer.WriteBytes(rawData); offset += 16; @@ -52,9 +52,9 @@ protected override void WriteToImpl(DataWriter writer) { /// public void SetRawData(uint offset, byte[] rawData) { - if (rawData == null || rawData.Length != 16) + if (rawData is null || rawData.Length != 16) throw new ArgumentException("Invalid size of GUID raw data"); - if (userRawData == null) + if (userRawData is null) userRawData = new Dictionary(); userRawData[offset] = rawData; } diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index 754be65c2..d358d3020 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -88,7 +88,7 @@ static void VerifyWriteToThrow(IChunk chunk) => /// Writer /// The data internal static void WriteDataDirectory(this DataWriter writer, IChunk chunk) { - if (chunk == null || chunk.GetVirtualSize() == 0) + if (chunk is null || chunk.GetVirtualSize() == 0) writer.WriteUInt64(0); else { writer.WriteUInt32((uint)chunk.RVA); @@ -97,7 +97,7 @@ internal static void WriteDataDirectory(this DataWriter writer, IChunk chunk) { } internal static void WriteDebugDirectory(this DataWriter writer, DebugDirectory chunk) { - if (chunk == null || chunk.GetVirtualSize() == 0) + if (chunk is null || chunk.GetVirtualSize() == 0) writer.WriteUInt64(0); else { writer.WriteUInt32((uint)chunk.RVA); diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index cdee8bd79..221d9b33c 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -119,7 +119,7 @@ public ManagedExportsWriter(string moduleName, Machine machine, RelocDirectory r internal void AddTextChunks(PESection textSection) { textSection.Add(vtableFixups, DEFAULT_VTBL_FIXUPS_ALIGNMENT); - if (cpuArch != null) + if (!(cpuArch is null)) textSection.Add(stubsChunk, cpuArch.GetStubAlignment(stubType)); } @@ -137,7 +137,7 @@ internal void AddExportedMethods(List methods, uint timestamp) { return; // Only check for an unsupported machine when we know there's at least one exported method - if (cpuArch == null) { + if (cpuArch is null) { logError("The module has exported methods but the CPU architecture isn't supported: {0} (0x{1:X4})", new object[] { machine, (ushort)machine }); return; } @@ -182,8 +182,8 @@ void Initialize(List methods, uint timestamp) { uint stubSize = cpuArch.GetStubSize(stubType); foreach (var method in methods) { var exportInfo = method.ExportInfo; - Debug.Assert(exportInfo != null); - if (exportInfo == null) + Debug.Assert(!(exportInfo is null)); + if (exportInfo is null) continue; var flags = baseFlags; @@ -282,7 +282,7 @@ uint GetOffset(string name, out byte[] bytes) { // If this method gets updated, also update the reader (MethodExportInfoProvider) static byte[] GetNameASCIIZ(string name) { - Debug.Assert(name != null); + Debug.Assert(!(name is null)); int size = Encoding.UTF8.GetByteCount(name); var bytes = new byte[size + 1]; Encoding.UTF8.GetBytes(name, 0, name.Length, bytes, 0); @@ -338,8 +338,8 @@ void WriteSdataBlob(uint timestamp) { foreach (var info in allMethodInfos) { var exportInfo = info.Method.ExportInfo; var name = exportInfo.Name; - if (name == null) { - if (exportInfo.Ordinal != null) { + if (name is null) { + if (!(exportInfo.Ordinal is null)) { sortedOrdinalMethodInfos.Add(info); continue; } @@ -417,7 +417,7 @@ void WriteSdataBlob(uint timestamp) { } void WriteSdata(DataWriter writer) { - if (sdataBytesInfo.Data == null) + if (sdataBytesInfo.Data is null) return; PatchSdataBytesBlob(); writer.WriteBytes(sdataBytesInfo.Data); @@ -484,7 +484,7 @@ void WriteVtableFixups(DataWriter writer) { void WriteStubs(DataWriter writer) { if (vtables.Count == 0) return; - if (cpuArch == null) + if (cpuArch is null) return; ulong imageBase = peHeaders.ImageBase; diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 0f2b71dd2..623037013 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -34,7 +34,7 @@ public static byte[] Write(ModuleDef module, MarshalType marshalType, IWriterErr } byte[] Write(MarshalType marshalType) { - if (marshalType == null) + if (marshalType is null) return null; var type = marshalType.NativeType; @@ -84,7 +84,7 @@ byte[] Write(MarshalType marshalType) { Write(custMarshaler.Guid); Write(custMarshaler.NativeTypeName); var cm = custMarshaler.CustomMarshaler; - var cmName = cm == null ? string.Empty : FullNameFactory.AssemblyQualifiedName(cm, this); + var cmName = cm is null ? string.Empty : FullNameFactory.AssemblyQualifiedName(cm, this); Write(cmName); Write(custMarshaler.Cookie); break; @@ -99,7 +99,7 @@ byte[] Write(MarshalType marshalType) { case NativeType.RawBlob: var data = ((RawMarshalType)marshalType).Data; - if (data != null) + if (!(data is null)) writer.WriteBytes(data); break; diff --git a/src/DotNet/Writer/MaxStackCalculator.cs b/src/DotNet/Writer/MaxStackCalculator.cs index 5e3788bb6..5d0f783b8 100644 --- a/src/DotNet/Writer/MaxStackCalculator.cs +++ b/src/DotNet/Writer/MaxStackCalculator.cs @@ -67,16 +67,16 @@ internal bool Calculate(out uint maxStack) { var stackHeights = this.stackHeights; for (int i = 0; i < exceptionHandlers.Count; i++) { var eh = exceptionHandlers[i]; - if (eh == null) + if (eh is null) continue; Instruction instr; - if ((instr = eh.TryStart) != null) + if (!((instr = eh.TryStart) is null)) stackHeights[instr] = 0; - if ((instr = eh.FilterStart) != null) { + if (!((instr = eh.FilterStart) is null)) { stackHeights[instr] = 1; currentMaxStack = 1; } - if ((instr = eh.HandlerStart) != null) { + if (!((instr = eh.HandlerStart) is null)) { bool pushed = eh.HandlerType == ExceptionHandlerType.Catch || eh.HandlerType == ExceptionHandlerType.Filter; if (pushed) { stackHeights[instr] = 1; @@ -92,7 +92,7 @@ internal bool Calculate(out uint maxStack) { var instructions = this.instructions; for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; - if (instr == null) + if (instr is null) continue; if (resetStack) { @@ -158,7 +158,7 @@ internal bool Calculate(out uint maxStack) { } int WriteStack(Instruction instr, int stack) { - if (instr == null) { + if (instr is null) { hasError = true; return stack; } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 964c0ef35..76fb0cb37 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -252,7 +252,7 @@ public TablesHeapOptions DebugTablesHeapOptions { /// Original module with the heaps /// If true, all custom streams are added to public void PreserveHeapOrder(ModuleDef module, bool addCustomHeaps) { - if (module == null) + if (module is null) throw new ArgumentNullException(nameof(module)); if (module is ModuleDefMD mod) { if (addCustomHeaps) { @@ -595,7 +595,7 @@ Comparison CreateComparison(Comparison comparison) => public uint Rid(T data) => toRid[data]; public bool TryGetRid(T data, out uint rid) { - if (data == null) { + if (data is null) { rid = 0; return false; } @@ -609,7 +609,7 @@ internal sealed class Rows where T : class { public int Count => dict.Count; public bool TryGetRid(T value, out uint rid) { - if (value == null) { + if (value is null) { rid = 0; return false; } @@ -633,7 +633,7 @@ public bool TryGetRid(T value, out uint rid) { /// Debug metadata kind /// A new instance public static Metadata Create(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetadataOptions options = null, DebugMetadataKind debugKind = DebugMetadataKind.None) { - if (options == null) + if (options is null) options = new MetadataOptions(); if ((options.Flags & MetadataFlags.PreserveRids) != 0 && module is ModuleDefMD) return new PreserveTokensMetadata(module, constants, methodBodies, netResources, options, debugKind, false); @@ -1175,7 +1175,7 @@ public uint GetRid(GenericParamConstraint gpc) { /// Value /// Its new rid or 0 public uint GetRid(PdbDocument doc) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.pdbDocumentInfos.TryGetRid(doc, out uint rid); return rid; @@ -1187,7 +1187,7 @@ public uint GetRid(PdbDocument doc) { /// Value /// Its new rid or 0 public uint GetRid(PdbScope scope) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.localScopeInfos.TryGetRid(scope, out uint rid); return rid; @@ -1199,7 +1199,7 @@ public uint GetRid(PdbScope scope) { /// Value /// Its new rid or 0 public uint GetRid(PdbLocal local) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.localVariableInfos.TryGetRid(local, out uint rid); return rid; @@ -1211,7 +1211,7 @@ public uint GetRid(PdbLocal local) { /// Value /// Its new rid or 0 public uint GetRid(PdbConstant constant) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.localConstantInfos.TryGetRid(constant, out uint rid); @@ -1224,7 +1224,7 @@ public uint GetRid(PdbConstant constant) { /// Value /// Its new rid or 0 public uint GetRid(PdbImportScope importScope) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.importScopeInfos.TryGetRid(importScope, out uint rid); return rid; @@ -1236,7 +1236,7 @@ public uint GetRid(PdbImportScope importScope) { /// Value /// Its new rid or 0 public uint GetStateMachineMethodRid(PdbAsyncMethodCustomDebugInfo asyncMethod) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.stateMachineMethodInfos.TryGetRid(asyncMethod, out uint rid); return rid; @@ -1248,7 +1248,7 @@ public uint GetStateMachineMethodRid(PdbAsyncMethodCustomDebugInfo asyncMethod) /// Value /// Its new rid or 0 public uint GetStateMachineMethodRid(PdbIteratorMethodCustomDebugInfo iteratorMethod) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.stateMachineMethodInfos.TryGetRid(iteratorMethod, out uint rid); return rid; @@ -1260,7 +1260,7 @@ public uint GetStateMachineMethodRid(PdbIteratorMethodCustomDebugInfo iteratorMe /// Value /// Its new rid or 0 public uint GetCustomDebugInfoRid(PdbCustomDebugInfo cdi) { - if (debugMetadata == null) + if (debugMetadata is null) return 0; debugMetadata.customDebugInfos.TryGetRid(cdi, out uint rid); return rid; @@ -1273,7 +1273,7 @@ public uint GetCustomDebugInfoRid(PdbCustomDebugInfo cdi) { /// The or null if is /// null or not a method defined in this module. public MethodBody GetMethodBody(MethodDef md) { - if (md == null) + if (md is null) return null; methodToBody.TryGetValue(md, out var mb); return mb; @@ -1293,7 +1293,7 @@ public MethodBody GetMethodBody(MethodDef md) { /// A instance or null if /// is invalid public DataReaderChunk GetChunk(EmbeddedResource er) { - if (er == null) + if (er is null) return null; embeddedResourceToByteArray.TryGetValue(er, out var chunk); return chunk; @@ -1306,7 +1306,7 @@ public DataReaderChunk GetChunk(EmbeddedResource er) { /// A instance or null if /// is invalid public ByteArrayChunk GetInitialValueChunk(FieldDef fd) { - if (fd == null) + if (fd is null) return null; fieldToInitialValue.TryGetValue(fd, out var chunk); return chunk; @@ -1375,7 +1375,7 @@ protected void RaiseProgress(MetadataEvent evt, double subProgress) { public void CreateTables() { OnMetadataEvent(Writer.MetadataEvent.BeginCreateTables); - if (module.Types.Count == 0 || module.Types[0] == null) + if (module.Types.Count == 0 || module.Types[0] is null) throw new ModuleWriterException("Missing global type"); if (module is ModuleDefMD moduleDefMD) { @@ -1446,7 +1446,7 @@ void Create() { AddExportedTypes(); InitializeEntryPoint(); - if (module.Assembly != null) + if (!(module.Assembly is null)) AddAssembly(module.Assembly, AssemblyPublicKey); OnMetadataEvent(Writer.MetadataEvent.BeforeSortTables); @@ -1494,13 +1494,13 @@ void InitializeTypeDefsAndMemberDefs() { notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); } - if (type == null) { + if (type is null) { Error("TypeDef is null"); continue; } uint typeRid = GetRid(type); var typeRow = tablesHeap.TypeDefTable[typeRid]; - typeRow = new RawTypeDefRow((uint)type.Attributes, stringsHeap.Add(type.Name), stringsHeap.Add(type.Namespace), type.BaseType == null ? 0 : AddTypeDefOrRef(type.BaseType), typeRow.FieldList, typeRow.MethodList); + typeRow = new RawTypeDefRow((uint)type.Attributes, stringsHeap.Add(type.Name), stringsHeap.Add(type.Namespace), type.BaseType is null ? 0 : AddTypeDefOrRef(type.BaseType), typeRow.FieldList, typeRow.MethodList); tablesHeap.TypeDefTable[typeRid] = typeRow; AddGenericParams(new MDToken(Table.TypeDef, typeRid), type.GenericParameters); AddDeclSecurities(new MDToken(Table.TypeDef, typeRid), type.DeclSecurities); @@ -1512,7 +1512,7 @@ void InitializeTypeDefsAndMemberDefs() { count = fields.Count; for (int i = 0; i < count; i++) { var field = fields[i]; - if (field == null) { + if (field is null) { Error("Field is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; } @@ -1530,11 +1530,11 @@ void InitializeTypeDefsAndMemberDefs() { count = methods.Count; for (int i = 0; i < count; i++) { var method = methods[i]; - if (method == null) { + if (method is null) { Error("Method is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; } - if (method.ExportInfo != null) + if (!(method.ExportInfo is null)) ExportedMethods.Add(method); uint rid = GetRid(method); var row = tablesHeap.MethodTable[rid]; @@ -1548,7 +1548,7 @@ void InitializeTypeDefsAndMemberDefs() { int count2 = paramDefs.Count; for (int j = 0; j < count2; j++) { var pd = paramDefs[j]; - if (pd == null) { + if (pd is null) { Error("Param is null. Method {0} ({1:X8})", method, method.MDToken.Raw); continue; } @@ -1564,7 +1564,7 @@ void InitializeTypeDefsAndMemberDefs() { count = events.Count; for (int i = 0; i < count; i++) { var evt = events[i]; - if (evt == null) { + if (evt is null) { Error("Event is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; } @@ -1578,7 +1578,7 @@ void InitializeTypeDefsAndMemberDefs() { count = properties.Count; for (int i = 0; i < count; i++) { var prop = properties[i]; - if (prop == null) { + if (prop is null) { Error("Property is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; } @@ -1611,7 +1611,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); } - if (type == null) + if (type is null) continue; if (type.HasCustomAttributes || type.HasCustomDebugInfos) { rid = GetRid(type); @@ -1623,7 +1623,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { count = fields.Count; for (int i = 0; i < count; i++) { var field = fields[i]; - if (field == null) + if (field is null) continue; if (field.HasCustomAttributes || field.HasCustomDebugInfos) { rid = GetRid(field); @@ -1636,7 +1636,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { count = methods.Count; for (int i = 0; i < count; i++) { var method = methods[i]; - if (method == null) + if (method is null) continue; if (method.HasCustomAttributes) { rid = GetRid(method); @@ -1647,7 +1647,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { int count2 = paramDefs.Count; for (int j = 0; j < count2; j++) { var pd = paramDefs[j]; - if (pd == null) + if (pd is null) continue; if (pd.HasCustomAttributes || pd.HasCustomDebugInfos) { rid = GetRid(pd); @@ -1660,7 +1660,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { count = events.Count; for (int i = 0; i < count; i++) { var evt = events[i]; - if (evt == null) + if (evt is null) continue; if (evt.HasCustomAttributes || evt.HasCustomDebugInfos) { rid = GetRid(evt); @@ -1672,7 +1672,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { count = properties.Count; for (int i = 0; i < count; i++) { var prop = properties[i]; - if (prop == null) + if (prop is null) continue; if (prop.HasCustomAttributes || prop.HasCustomDebugInfos) { rid = GetRid(prop); @@ -1688,16 +1688,16 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { /// void InitializeVTableFixups() { var fixups = module.VTableFixups; - if (fixups == null || fixups.VTables.Count == 0) + if (fixups is null || fixups.VTables.Count == 0) return; foreach (var vtable in fixups) { - if (vtable == null) { + if (vtable is null) { Error("VTable is null"); continue; } foreach (var method in vtable) { - if (method == null) + if (method is null) continue; AddMDTokenProvider(method); } @@ -1807,14 +1807,14 @@ void SortTables() { /// void InitializeGenericParamConstraintTable() { foreach (var type in allTypeDefs) { - if (type == null) + if (type is null) continue; AddGenericParamConstraints(type.GenericParameters); var methods = type.Methods; int count = methods.Count; for (int i = 0; i < count; i++) { var method = methods[i]; - if (method == null) + if (method is null) continue; AddGenericParamConstraints(method.GenericParameters); } @@ -1841,7 +1841,7 @@ void InitializeCustomAttributeAndCustomDebugInfoTables() { foreach (var info in customAttributeInfos.infos) tablesHeap.CustomAttributeTable.Create(info.row); - if (debugMetadata != null) { + if (!(debugMetadata is null)) { debugMetadata.stateMachineMethodInfos.Sort((a, b) => a.row.MoveNextMethod.CompareTo(b.row.MoveNextMethod)); debugMetadata.tablesHeap.StateMachineMethodTable.IsSorted = true; foreach (var info in debugMetadata.stateMachineMethodInfos.infos) @@ -1880,7 +1880,7 @@ void WriteMethodBodies() { List methodScopeDebugInfos; List scopeStack; SerializerMethodContext serializerMethodContext; - if (debugMetadata == null) { + if (debugMetadata is null) { methodScopeDebugInfos = null; scopeStack = null; serializerMethodContext = null; @@ -1894,13 +1894,13 @@ void WriteMethodBodies() { bool keepMaxStack = KeepOldMaxStack; var writer = new MethodBodyWriter(this); foreach (var type in allTypeDefs) { - if (type == null) + if (type is null) continue; var methods = type.Methods; for (int i = 0; i < methods.Count; i++) { var method = methods[i]; - if (method == null) + if (method is null) continue; if (methodNum++ == notifyAfter && notifyNum < numNotifyEvents) { @@ -1912,7 +1912,7 @@ void WriteMethodBodies() { uint localVarSigTok = 0; var cilBody = method.Body; - if (cilBody != null) { + if (!(cilBody is null)) { if (!(cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0)) { writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); writer.Write(); @@ -1925,18 +1925,18 @@ void WriteMethodBodies() { } else { var nativeBody = method.NativeBody; - if (nativeBody != null) + if (!(nativeBody is null)) methodToNativeBody[method] = nativeBody; - else if (method.MethodBody != null) + else if (!(method.MethodBody is null)) Error("Unsupported method body"); } - if (debugMetadata != null) { + if (!(debugMetadata is null)) { uint rid = GetRid(method); - if (cilBody != null) { + if (!(cilBody is null)) { var pdbMethod = cilBody.PdbMethod; - if (pdbMethod != null) { + if (!(pdbMethod is null)) { // We don't need to write empty scopes if (!IsEmptyRootScope(cilBody, pdbMethod.Scope)) { serializerMethodContext.SetBody(method); @@ -1963,7 +1963,7 @@ void WriteMethodBodies() { } } } - if (debugMetadata != null) { + if (!(debugMetadata is null)) { methodScopeDebugInfos.Sort((a, b) => { int c = a.MethodRid.CompareTo(b.MethodRid); if (c != 0) @@ -1999,7 +1999,7 @@ void WriteMethodBodies() { foreach (var info in debugMetadata.localScopeInfos.infos) debugMetadata.tablesHeap.LocalScopeTable.Create(info.row); } - if (serializerMethodContext != null) + if (!(serializerMethodContext is null)) Free(ref serializerMethodContext); } @@ -2010,13 +2010,13 @@ static bool IsEmptyRootScope(CilBody cilBody, PdbScope scope) { return false; if (scope.Namespaces.Count != 0) return false; - if (scope.ImportScope != null) + if (!(scope.ImportScope is null)) return false; if (scope.Scopes.Count != 0) return false; if (scope.CustomDebugInfos.Count != 0) return false; - if (scope.End != null) + if (!(scope.End is null)) return false; if (cilBody.Instructions.Count != 0 && cilBody.Instructions[0] != scope.Start) return false; @@ -2031,11 +2031,11 @@ static bool IsEmptyRootScope(CilBody cilBody, PdbScope scope) { /// The list /// true if the list is empty or if it contains only nulls, false otherwise protected static bool IsEmpty(IList list) where T : class { - if (list == null) + if (list is null) return true; int count = list.Count; for (int i = 0; i < count; i++) { - if (list[i] != null) + if (!(list[i] is null)) return false; } return true; @@ -2055,7 +2055,7 @@ public MDToken GetToken(object o) { if (o is FieldSig fieldSig) return new MDToken(Table.StandAloneSig, AddStandAloneSig(fieldSig, 0)); - if (o == null) + if (o is null) Error("Instruction operand is null"); else Error("Invalid instruction operand"); @@ -2064,7 +2064,7 @@ public MDToken GetToken(object o) { /// public virtual MDToken GetToken(IList locals, uint origToken) { - if (locals == null || locals.Count == 0) + if (locals is null || locals.Count == 0) return new MDToken((Table)0, 0); var row = new RawStandAloneSigRow(GetSignature(new LocalSig(locals, false))); @@ -2081,7 +2081,7 @@ public virtual MDToken GetToken(IList locals, uint origToken) { /// Original StandAloneSig token or 0 if none /// Its new rid protected virtual uint AddStandAloneSig(MethodSig methodSig, uint origToken) { - if (methodSig == null) { + if (methodSig is null) { Error("StandAloneSig: MethodSig is null"); return 0; } @@ -2100,7 +2100,7 @@ protected virtual uint AddStandAloneSig(MethodSig methodSig, uint origToken) { /// Original StandAloneSig token or 0 if none /// Its new rid protected virtual uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { - if (fieldSig == null) { + if (fieldSig is null) { Error("StandAloneSig: FieldSig is null"); return 0; } @@ -2113,7 +2113,7 @@ protected virtual uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { } uint AddMDTokenProvider(IMDTokenProvider tp) { - if (tp != null) { + if (!(tp is null)) { switch (tp.MDToken.Table) { case Table.Module: return AddModule((ModuleDef)tp); @@ -2207,7 +2207,7 @@ uint AddMDTokenProvider(IMDTokenProvider tp) { } } - if (tp == null) + if (tp is null) Error("IMDTokenProvider is null"); else Error("Invalid IMDTokenProvider"); @@ -2220,7 +2220,7 @@ uint AddMDTokenProvider(IMDTokenProvider tp) { /// Value /// Its encoded token protected uint AddTypeDefOrRef(ITypeDefOrRef tdr) { - if (tdr == null) { + if (tdr is null) { Error("TypeDefOrRef is null"); return 0; } @@ -2239,7 +2239,7 @@ protected uint AddTypeDefOrRef(ITypeDefOrRef tdr) { /// Value /// Its encoded token protected uint AddResolutionScope(IResolutionScope rs) { - if (rs == null) { + if (rs is null) { Error("ResolutionScope is null"); return 0; } @@ -2258,7 +2258,7 @@ protected uint AddResolutionScope(IResolutionScope rs) { /// Value /// Its encoded token protected uint AddMethodDefOrRef(IMethodDefOrRef mdr) { - if (mdr == null) { + if (mdr is null) { Error("MethodDefOrRef is null"); return 0; } @@ -2277,7 +2277,7 @@ protected uint AddMethodDefOrRef(IMethodDefOrRef mdr) { /// Value /// Its encoded token protected uint AddMemberRefParent(IMemberRefParent parent) { - if (parent == null) { + if (parent is null) { Error("MemberRefParent is null"); return 0; } @@ -2296,7 +2296,7 @@ protected uint AddMemberRefParent(IMemberRefParent parent) { /// Value /// Its encoded token protected uint AddImplementation(IImplementation impl) { - if (impl == null) { + if (impl is null) { Error("Implementation is null"); return 0; } @@ -2315,7 +2315,7 @@ protected uint AddImplementation(IImplementation impl) { /// Value /// Its encoded token protected uint AddCustomAttributeType(ICustomAttributeType cat) { - if (cat == null) { + if (cat is null) { Error("CustomAttributeType is null"); return 0; } @@ -2334,7 +2334,7 @@ protected uint AddCustomAttributeType(ICustomAttributeType cat) { /// Nested type /// Declaring type protected void AddNestedType(TypeDef nestedType, TypeDef declaringType) { - if (nestedType == null || declaringType == null) + if (nestedType is null || declaringType is null) return; uint nestedRid = GetRid(nestedType); uint dtRid = GetRid(declaringType); @@ -2350,7 +2350,7 @@ protected void AddNestedType(TypeDef nestedType, TypeDef declaringType) { /// Module /// Its new rid protected uint AddModule(ModuleDef module) { - if (module == null) { + if (module is null) { Error("Module is null"); return 0; } @@ -2376,7 +2376,7 @@ protected uint AddModule(ModuleDef module) { /// Module ref /// Its new rid protected uint AddModuleRef(ModuleRef modRef) { - if (modRef == null) { + if (modRef is null) { Error("ModuleRef is null"); return 0; } @@ -2396,7 +2396,7 @@ protected uint AddModuleRef(ModuleRef modRef) { /// Assembly ref /// Its new rid protected uint AddAssemblyRef(AssemblyRef asmRef) { - if (asmRef == null) { + if (asmRef is null) { Error("AssemblyRef is null"); return 0; } @@ -2426,7 +2426,7 @@ protected uint AddAssemblyRef(AssemblyRef asmRef) { /// The public key that should be used /// Its new rid protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { - if (asm == null) { + if (asm is null) { Error("Assembly is null"); return 0; } @@ -2434,7 +2434,7 @@ protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { return rid; var asmAttrs = asm.Attributes; - if (publicKey != null) + if (!(publicKey is null)) asmAttrs |= AssemblyAttributes.PublicKey; else publicKey = PublicKeyBase.GetRawData(asm.PublicKeyOrToken); @@ -2463,7 +2463,7 @@ protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { /// New token of owner /// All generic params protected void AddGenericParams(MDToken token, IList gps) { - if (gps == null) + if (gps is null) return; int count = gps.Count; for (int i = 0; i < count; i++) @@ -2476,7 +2476,7 @@ protected void AddGenericParams(MDToken token, IList gps) { /// New token of owner /// Generic paramater protected void AddGenericParam(MDToken owner, GenericParam gp) { - if (gp == null) { + if (gp is null) { Error("GenericParam is null"); return; } @@ -2488,17 +2488,17 @@ protected void AddGenericParam(MDToken owner, GenericParam gp) { (ushort)gp.Flags, encodedOwner, stringsHeap.Add(gp.Name), - gp.Kind == null ? 0 : AddTypeDefOrRef(gp.Kind)); + gp.Kind is null ? 0 : AddTypeDefOrRef(gp.Kind)); genericParamInfos.Add(gp, row); } void AddGenericParamConstraints(IList gps) { - if (gps == null) + if (gps is null) return; int count = gps.Count; for (int i = 0; i < count; i++) { var gp = gps[i]; - if (gp == null) + if (gp is null) continue; uint rid = genericParamInfos.Rid(gp); AddGenericParamConstraints(rid, gp.GenericParamConstraints); @@ -2511,7 +2511,7 @@ void AddGenericParamConstraints(IList gps) { /// New rid of owner generic param /// Its constraints protected void AddGenericParamConstraints(uint gpRid, IList constraints) { - if (constraints == null) + if (constraints is null) return; int count = constraints.Count; for (int i = 0; i < count; i++) @@ -2524,7 +2524,7 @@ protected void AddGenericParamConstraints(uint gpRid, IListNew rid of owner generic param /// Generic parameter constraint protected void AddGenericParamConstraint(uint gpRid, GenericParamConstraint gpc) { - if (gpc == null) { + if (gpc is null) { Error("GenericParamConstraint is null"); return; } @@ -2541,7 +2541,7 @@ protected void AddInterfaceImpls(uint typeDefRid, IList ifaces) { int count = ifaces.Count; for (int i = 0; i < count; i++) { var iface = ifaces[i]; - if (iface == null) + if (iface is null) continue; var row = new RawInterfaceImplRow(typeDefRid, AddTypeDefOrRef(iface.Interface)); @@ -2554,7 +2554,7 @@ protected void AddInterfaceImpls(uint typeDefRid, IList ifaces) { /// /// Owner field protected void AddFieldLayout(FieldDef field) { - if (field == null || field.FieldOffset == null) + if (field is null || field.FieldOffset is null) return; var rid = GetRid(field); var row = new RawFieldLayoutRow(field.FieldOffset.Value, rid); @@ -2567,7 +2567,7 @@ protected void AddFieldLayout(FieldDef field) { /// New owner token /// Owner protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { - if (hfm == null || hfm.MarshalType == null) + if (hfm is null || hfm.MarshalType is null) return; var fieldMarshal = hfm.MarshalType; if (!CodedToken.HasFieldMarshal.Encode(parent, out uint encodedParent)) { @@ -2591,7 +2591,7 @@ protected void AddFieldRVA(FieldDef field) { fieldRVAInfos.Add(field, row); } else { - if (field == null || field.InitialValue == null) + if (field is null || field.InitialValue is null) return; var ivBytes = field.InitialValue; if (!VerifyFieldSize(field, ivBytes.Length)) @@ -2605,10 +2605,10 @@ protected void AddFieldRVA(FieldDef field) { } static bool VerifyFieldSize(FieldDef field, int size) { - if (field == null) + if (field is null) return false; var sig = field.FieldSig; - if (sig == null) + if (sig is null) return false; return field.GetFieldSize() == size; } @@ -2619,7 +2619,7 @@ static bool VerifyFieldSize(FieldDef field, int size) { /// New owner token /// Owner protected void AddImplMap(MDToken parent, IMemberForwarded mf) { - if (mf == null || mf.ImplMap == null) + if (mf is null || mf.ImplMap is null) return; var implMap = mf.ImplMap; if (!CodedToken.MemberForwarded.Encode(parent, out uint encodedParent)) { @@ -2639,7 +2639,7 @@ protected void AddImplMap(MDToken parent, IMemberForwarded mf) { /// New owner token /// Owner protected void AddConstant(MDToken parent, IHasConstant hc) { - if (hc == null || hc.Constant == null) + if (hc is null || hc.Constant is null) return; var constant = hc.Constant; if (!CodedToken.HasConstant.Encode(parent, out uint encodedParent)) { @@ -2655,7 +2655,7 @@ protected void AddConstant(MDToken parent, IHasConstant hc) { static readonly byte[] constantClassByteArray = new byte[4]; static readonly byte[] constantDefaultByteArray = new byte[8]; byte[] GetConstantValueAsByteArray(ElementType etype, object o) { - if (o == null) { + if (o is null) { if (etype == ElementType.Class) return constantClassByteArray; Error("Constant is null"); @@ -2733,7 +2733,7 @@ void VerifyConstantType(ElementType realType, ElementType expectedType) { /// New owner token /// All DeclSecurity rows protected void AddDeclSecurities(MDToken parent, IList declSecurities) { - if (declSecurities == null) + if (declSecurities is null) return; if (!CodedToken.HasDeclSecurity.Encode(parent, out uint encodedParent)) { Error("Can't encode HasDeclSecurity token {0:X8}", parent.Raw); @@ -2743,7 +2743,7 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit int count = declSecurities.Count; for (int i = 0; i < count; i++) { var decl = declSecurities[i]; - if (decl == null) + if (decl is null) continue; var row = new RawDeclSecurityRow((short)decl.Action, encodedParent, @@ -2758,7 +2758,7 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit /// /// Event protected void AddMethodSemantics(EventDef evt) { - if (evt == null) { + if (evt is null) { Error("Event is null"); return; } @@ -2777,7 +2777,7 @@ protected void AddMethodSemantics(EventDef evt) { /// /// Property protected void AddMethodSemantics(PropertyDef prop) { - if (prop == null) { + if (prop is null) { Error("Property is null"); return; } @@ -2791,7 +2791,7 @@ protected void AddMethodSemantics(PropertyDef prop) { } void AddMethodSemantics(MDToken owner, IList methods, MethodSemanticsAttributes attrs) { - if (methods == null) + if (methods is null) return; int count = methods.Count; for (int i = 0; i < count; i++) @@ -2799,7 +2799,7 @@ void AddMethodSemantics(MDToken owner, IList methods, MethodSemantics } void AddMethodSemantics(MDToken owner, MethodDef method, MethodSemanticsAttributes flags) { - if (method == null) + if (method is null) return; uint methodRid = GetRid(method); if (methodRid == 0) @@ -2813,10 +2813,10 @@ void AddMethodSemantics(MDToken owner, MethodDef method, MethodSemanticsAttribut } void AddMethodImpls(MethodDef method, IList overrides) { - if (overrides == null) + if (overrides is null) return; - if (method.DeclaringType == null) { - Error("Method declaring type == null. Method {0} ({1:X8})", method, method.MDToken.Raw); + if (method.DeclaringType is null) { + Error("Method declaring type is null. Method {0} ({1:X8})", method, method.MDToken.Raw); return; } if (overrides.Count != 0) { @@ -2837,7 +2837,7 @@ void AddMethodImpls(MethodDef method, IList overrides) { /// /// Type protected void AddClassLayout(TypeDef type) { - if (type == null || type.ClassLayout == null) + if (type is null || type.ClassLayout is null) return; var rid = GetRid(type); var classLayout = type.ClassLayout; @@ -2846,7 +2846,7 @@ protected void AddClassLayout(TypeDef type) { } void AddResources(IList resources) { - if (resources == null) + if (resources is null) return; int count = resources.Count; for (int i = 0; i < count; i++) @@ -2869,7 +2869,7 @@ void AddResource(Resource resource) { return; } - if (resource == null) + if (resource is null) Error("Resource is null"); else Error("Invalid resource type: {0}", resource.GetType()); @@ -2877,7 +2877,7 @@ void AddResource(Resource resource) { uint AddEmbeddedResource(EmbeddedResource er) { Debug.Assert(!isStandaloneDebugMetadata); - if (er == null) { + if (er is null) { Error("EmbeddedResource is null"); return 0; } @@ -2896,7 +2896,7 @@ uint AddEmbeddedResource(EmbeddedResource er) { } uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { - if (alr == null) { + if (alr is null) { Error("AssemblyLinkedResource is null"); return 0; } @@ -2914,7 +2914,7 @@ uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { } uint AddLinkedResource(LinkedResource lr) { - if (lr == null) { + if (lr is null) { Error("LinkedResource is null"); return 0; } @@ -2937,7 +2937,7 @@ uint AddLinkedResource(LinkedResource lr) { /// File /// Its new rid protected uint AddFile(FileDef file) { - if (file == null) { + if (file is null) { Error("FileDef is null"); return 0; } @@ -2959,7 +2959,7 @@ protected uint AddFile(FileDef file) { /// Exported type /// Its new rid protected uint AddExportedType(ExportedType et) { - if (et == null) { + if (et is null) { Error("ExportedType is null"); return 0; } @@ -2987,7 +2987,7 @@ protected uint AddExportedType(ExportedType et) { /// #Blob offset protected uint GetSignature(TypeSig ts, byte[] extraData) { byte[] blob; - if (ts == null) { + if (ts is null) { Error("TypeSig is null"); blob = null; } @@ -3006,7 +3006,7 @@ protected uint GetSignature(TypeSig ts, byte[] extraData) { /// Signature /// #Blob offset protected uint GetSignature(CallingConventionSig sig) { - if (sig == null) { + if (sig is null) { Error("CallingConventionSig is null"); return 0; } @@ -3019,8 +3019,8 @@ protected uint GetSignature(CallingConventionSig sig) { } void AppendExtraData(ref byte[] blob, byte[] extraData) { - if (PreserveExtraSignatureData && extraData != null && extraData.Length > 0) { - int blen = blob == null ? 0 : blob.Length; + if (PreserveExtraSignatureData && !(extraData is null) && extraData.Length > 0) { + int blen = blob is null ? 0 : blob.Length; Array.Resize(ref blob, blen + extraData.Length); Array.Copy(extraData, 0, blob, blen, extraData.Length); } @@ -3042,7 +3042,7 @@ void AddCustomAttributes(Table table, uint rid, CustomAttributeCollection caList } void AddCustomAttribute(MDToken token, CustomAttribute ca) { - if (ca == null) { + if (ca is null) { Error("Custom attribute is null"); return; } @@ -3060,8 +3060,8 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { } void AddCustomDebugInformationList(MethodDef method, uint rid, uint localVarSigToken) { - Debug.Assert(debugMetadata != null); - if (debugMetadata == null) + Debug.Assert(!(debugMetadata is null)); + if (debugMetadata is null) return; var serializerMethodContext = AllocSerializerMethodContext(); serializerMethodContext.SetBody(method); @@ -3072,9 +3072,9 @@ void AddCustomDebugInformationList(MethodDef method, uint rid, uint localVarSigT } void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken) { - Debug.Assert(debugMetadata != null); + Debug.Assert(!(debugMetadata is null)); var body = method.Body; - if (body == null) + if (body is null) return; GetSingleDocument(body, out var singleDoc, out var firstDoc, out bool hasNoSeqPoints); @@ -3088,7 +3088,7 @@ void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken outStream.Position = 0; writer.WriteCompressedUInt32(localVarSigToken); - if (singleDoc == null) + if (singleDoc is null) writer.WriteCompressedUInt32(VerifyGetRid(firstDoc)); var instrs = body.Instructions; @@ -3100,9 +3100,9 @@ void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken for (int i = 0; i < instrs.Count; i++, instrOffset += (uint)instr.GetSize()) { instr = instrs[i]; var seqPoint = instr.SequencePoint; - if (seqPoint == null) + if (seqPoint is null) continue; - if (seqPoint.Document == null) { + if (seqPoint.Document is null) { Error("PDB document is null"); return; } @@ -3153,14 +3153,14 @@ void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken } var seqPointsBlob = outStream.ToArray(); - var row = new RawMethodDebugInformationRow(singleDoc == null ? 0 : AddPdbDocument(singleDoc), debugMetadata.blobHeap.Add(seqPointsBlob)); + var row = new RawMethodDebugInformationRow(singleDoc is null ? 0 : AddPdbDocument(singleDoc), debugMetadata.blobHeap.Add(seqPointsBlob)); debugMetadata.tablesHeap.MethodDebugInformationTable[rid] = row; debugMetadata.methodDebugInformationInfosUsed = true; Free(ref bwctx); } uint VerifyGetRid(PdbDocument doc) { - Debug.Assert(debugMetadata != null); + Debug.Assert(!(debugMetadata is null)); if (!debugMetadata.pdbDocumentInfos.TryGetRid(doc, out uint rid)) { Error("PDB document has been removed"); return 0; @@ -3175,12 +3175,12 @@ static void GetSingleDocument(CilBody body, out PdbDocument singleDoc, out PdbDo firstDoc = null; for (int i = 0; i < instrs.Count; i++) { var seqPt = instrs[i].SequencePoint; - if (seqPt == null) + if (seqPt is null) continue; var doc = seqPt.Document; - if (doc == null) + if (doc is null) continue; - if (firstDoc == null) + if (firstDoc is null) firstDoc = doc; if (singleDoc != doc) { singleDoc = doc; @@ -3202,7 +3202,7 @@ static void GetSingleDocument(CilBody body, out PdbDocument singleDoc, out PdbDo /// Onwer protected void AddCustomDebugInformationList(Table table, uint rid, IHasCustomDebugInformation hcdi) { Debug.Assert(table != Table.Method); - if (debugMetadata == null) + if (debugMetadata is null) return; if (hcdi.CustomDebugInfos.Count == 0) return; @@ -3214,7 +3214,7 @@ protected void AddCustomDebugInformationList(Table table, uint rid, IHasCustomDe void AddCustomDebugInformationList(Table table, uint rid, IList cdis) { Debug.Assert(table != Table.Method); - if (debugMetadata == null) + if (debugMetadata is null) return; if (cdis.Count == 0) return; @@ -3225,7 +3225,7 @@ void AddCustomDebugInformationList(Table table, uint rid, IList cdis) { - Debug.Assert(debugMetadata != null); + Debug.Assert(!(debugMetadata is null)); Debug.Assert(cdis.Count != 0); var token = new MDToken(table, rid); @@ -3236,7 +3236,7 @@ void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodConte for (int i = 0; i < cdis.Count; i++) { var cdi = cdis[i]; - if (cdi == null) { + if (cdi is null) { Error("Custom debug info is null"); continue; } @@ -3246,7 +3246,7 @@ void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodConte } void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, uint token, uint encodedToken, PdbCustomDebugInfo cdi) { - Debug.Assert(debugMetadata != null); + Debug.Assert(!(debugMetadata is null)); switch (cdi.Kind) { case PdbCustomDebugInfoKind.UsingGroups: @@ -3291,8 +3291,8 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, MethodDef kickoffMethod) { Debug.Assert(new MDToken(moveNextMethodToken).Table == Table.Method); - Debug.Assert(debugMetadata != null); - if (kickoffMethod == null) { + Debug.Assert(!(debugMetadata is null)); + if (kickoffMethod is null) { Error("KickoffMethod is null"); return; } @@ -3301,7 +3301,7 @@ void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, Met } void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodContext, uint encodedToken, PdbCustomDebugInfo cdi, Guid cdiGuid) { - Debug.Assert(debugMetadata != null); + Debug.Assert(!(debugMetadata is null)); var bwctx = AllocBinaryWriterContext(); var cdiBlob = PortablePdbCustomDebugInfoWriter.Write(this, serializerMethodContext, this, cdi, bwctx); @@ -3314,7 +3314,7 @@ void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodConte } void InitializeMethodDebugInformation() { - if (debugMetadata == null) + if (debugMetadata is null) return; int numMethods = NumberOfMethods; for (int i = 0; i < numMethods; i++) @@ -3322,15 +3322,15 @@ void InitializeMethodDebugInformation() { } void AddPdbDocuments() { - if (debugMetadata == null) + if (debugMetadata is null) return; foreach (var doc in module.PdbState.Documents) AddPdbDocument(doc); } uint AddPdbDocument(PdbDocument doc) { - Debug.Assert(debugMetadata != null); - if (doc == null) { + Debug.Assert(!(debugMetadata is null)); + if (doc is null) { Error("PdbDocument is null"); return 0; } @@ -3347,8 +3347,8 @@ uint AddPdbDocument(PdbDocument doc) { } uint GetDocumentNameBlobOffset(string name) { - Debug.Assert(debugMetadata != null); - if (name == null) { + Debug.Assert(!(debugMetadata is null)); + if (name is null) { Error("Document name is null"); name = string.Empty; } @@ -3377,8 +3377,8 @@ uint GetDocumentNameBlobOffset(string name) { static readonly char[] directorySeparatorCharArray = new char[] { Path.DirectorySeparatorChar }; uint AddImportScope(PdbImportScope scope) { - Debug.Assert(debugMetadata != null); - if (scope == null) + Debug.Assert(!(debugMetadata is null)); + if (scope is null) return 0; if (debugMetadata.importScopeInfos.TryGetRid(scope, out uint rid)) { if (rid == 0) @@ -3405,8 +3405,8 @@ uint AddImportScope(PdbImportScope scope) { } void AddLocalVariable(PdbLocal local) { - Debug.Assert(debugMetadata != null); - if (local == null) { + Debug.Assert(!(debugMetadata is null)); + if (local is null) { Error("PDB local is null"); return; } @@ -3417,8 +3417,8 @@ void AddLocalVariable(PdbLocal local) { } void AddLocalConstant(PdbConstant constant) { - Debug.Assert(debugMetadata != null); - if (constant == null) { + Debug.Assert(!(debugMetadata is null)); + if (constant is null) { Error("PDB constant is null"); return; } @@ -3445,7 +3445,7 @@ void AddLocalConstant(PdbConstant constant) { /// Entry point token /// Updated with the offset of the 20-byte PDB ID. The caller is responsible for initializing it with the PDB ID internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdbIdOffset) { - if (debugMetadata == null) + if (debugMetadata is null) throw new InvalidOperationException(); var pdbHeap = debugMetadata.PdbHeap; pdbHeap.EntryPoint = entryPointToken; @@ -3674,9 +3674,9 @@ public void WriteTo(DataWriter writer) { protected static List Sort(IEnumerable pds) { var sorted = new List(pds); sorted.Sort((a, b) => { - if (a == null) + if (a is null) return -1; - if (b == null) + if (b is null) return 1; return a.Sequence.CompareTo(b.Sequence); }); diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index eaf76dc88..6c3871d87 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -53,7 +53,7 @@ public sealed class MethodBody : IChunk { /// /// true if there's an extra section /// - public bool HasExtraSections => extraSections != null && extraSections.Length > 0; + public bool HasExtraSections => !(extraSections is null) && extraSections.Length > 0; /// /// Constructor @@ -90,7 +90,7 @@ public MethodBody(byte[] code, byte[] extraSections, uint localVarSigTok) { /// public int GetApproximateSizeOfMethodBody() { int len = code.Length; - if (extraSections != null) { + if (!(extraSections is null)) { len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); len += extraSections.Length; len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); @@ -148,7 +148,7 @@ public void WriteTo(DataWriter writer) { /// public override bool Equals(object obj) { var other = obj as MethodBody; - if (other == null) + if (other is null) return false; return Utils.Equals(code, other.code) && Utils.Equals(extraSections, other.extraSections); diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index 1bbcbb8e6..3b5c177dc 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -105,7 +105,7 @@ internal MethodBody Add(MethodBody methodBody, RVA origRva, uint origSize) { /// The method body /// if the method body is removed public bool Remove(MethodBody methodBody) { - if (methodBody == null) + if (methodBody is null) throw new ArgumentNullException(nameof(methodBody)); if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index f62f8c5eb..6890cef44 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -114,9 +114,9 @@ public void Write() { /// The code and any exception handlers public byte[] GetFullMethodBody() { int padding = Utils.AlignUp(code.Length, 4) - code.Length; - var bytes = new byte[code.Length + (extraSections == null ? 0 : padding + extraSections.Length)]; + var bytes = new byte[code.Length + (extraSections is null ? 0 : padding + extraSections.Length)]; Array.Copy(code, 0, bytes, 0, code.Length); - if (extraSections != null) + if (!(extraSections is null)) Array.Copy(extraSections, 0, bytes, code.Length + padding, extraSections.Length); return bytes; } @@ -201,7 +201,7 @@ bool FitsInSmallExceptionClause(Instruction start, Instruction end) { } uint GetOffset2(Instruction instr) { - if (instr == null) + if (instr is null) return codeSize; return GetOffset(instr); } diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index 73f421ebd..3d6a648fe 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -82,7 +82,7 @@ protected uint GetMaxStack() { /// The offset or 0 if is null or not /// present in the list of all instructions. protected uint GetOffset(Instruction instr) { - if (instr == null) { + if (instr is null) { Error("Instruction is null"); return 0; } @@ -101,7 +101,7 @@ protected uint InitializeInstructionOffsets() { var instructions = this.instructions; for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; - if (instr == null) + if (instr is null) continue; offsets[instr] = offset; offset += GetSizeOfInstruction(instr); @@ -126,7 +126,7 @@ protected uint WriteInstructions(ref ArrayWriter writer) { var instructions = this.instructions; for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; - if (instr == null) + if (instr is null) continue; WriteInstruction(ref writer, instr); } @@ -309,7 +309,7 @@ protected virtual void WriteInlineR(ref ArrayWriter writer, Instruction instr) { /// Instruction protected virtual void WriteInlineSwitch(ref ArrayWriter writer, Instruction instr) { var targets = instr.Operand as IList; - if (targets == null) { + if (targets is null) { Error("switch operand is not a list of instructions"); writer.WriteInt32(0); } @@ -344,7 +344,7 @@ protected virtual void WriteInlineSwitch(ref ArrayWriter writer, Instruction ins /// Instruction protected virtual void WriteInlineVar(ref ArrayWriter writer, Instruction instr) { var variable = instr.Operand as IVariable; - if (variable == null) { + if (variable is null) { Error("Operand is not a local/arg"); writer.WriteUInt16(0); } @@ -411,7 +411,7 @@ protected virtual void WriteShortInlineR(ref ArrayWriter writer, Instruction ins /// Instruction protected virtual void WriteShortInlineVar(ref ArrayWriter writer, Instruction instr) { var variable = instr.Operand as IVariable; - if (variable == null) { + if (variable is null) { Error("Operand is not a local/arg"); writer.WriteByte(0); } diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 138987d45..6373680e2 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -169,7 +169,7 @@ void CreateSections() { sections.Add(mvidSection = new PESection(".mvid", 0x42000040)); sections.Add(textSection = new PESection(".text", 0x60000020)); sections.Add(sdataSection = new PESection(".sdata", 0xC0000040)); - if (GetWin32Resources() != null) + if (!(GetWin32Resources() is null)) sections.Add(rsrcSection = new PESection(".rsrc", 0x40000040)); // Should be last so any data in a previous section can add relocations sections.Add(relocSection = new PESection(".reloc", 0x42000040)); @@ -205,7 +205,7 @@ void AddChunksToSections() { bool is64bit = machine.Is64Bit(); uint pointerAlignment = is64bit ? 8U : 4; - if (mvidSection != null) + if (!(mvidSection is null)) mvidSection.Add(new ByteArrayChunk((module.Mvid ?? Guid.Empty).ToByteArray()), MVID_ALIGNMENT); textSection.Add(importAddressTable, pointerAlignment); textSection.Add(imageCor20Header, DEFAULT_COR20HEADER_ALIGNMENT); @@ -219,7 +219,7 @@ void AddChunksToSections() { textSection.Add(importDirectory, pointerAlignment); textSection.Add(startupStub, startupStub.Alignment); managedExportsWriter.AddSdataChunks(sdataSection); - if (GetWin32Resources() != null) + if (!(GetWin32Resources() is null)) rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); relocSection.Add(relocDirectory, DEFAULT_RELOC_ALIGNMENT); } @@ -264,7 +264,7 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.EndWriteChunks); OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); - if (Options.StrongNameKey != null) + if (!(Options.StrongNameKey is null)) StrongNameSign((long)strongNameSignature.FileOffset); OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 91b68cc3c..1c05d9266 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -359,10 +359,10 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PEHeadersOptions.NumberOfRvaAndSizes = 0x10; Cor20HeaderOptions.Flags = module.Cor20HeaderFlags; - if (module.Assembly != null && !PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey)) + if (!(module.Assembly is null) && !PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey)) Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; - if (module.Cor20HeaderRuntimeVersion != null) { + if (!(module.Cor20HeaderRuntimeVersion is null)) { Cor20HeaderOptions.MajorRuntimeVersion = (ushort)(module.Cor20HeaderRuntimeVersion.Value >> 16); Cor20HeaderOptions.MinorRuntimeVersion = (ushort)module.Cor20HeaderRuntimeVersion.Value; } @@ -375,7 +375,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { Cor20HeaderOptions.MinorRuntimeVersion = 5; } - if (module.TablesHeaderVersion != null) { + if (!(module.TablesHeaderVersion is null)) { MetadataOptions.TablesHeapOptions.MajorVersion = (byte)(module.TablesHeaderVersion.Value >> 8); MetadataOptions.TablesHeapOptions.MinorVersion = (byte)module.TablesHeaderVersion.Value; } @@ -394,7 +394,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { MetadataOptions.Flags |= MetadataFlags.AlwaysCreateGuidHeap; var modDefMD = module as ModuleDefMD; - if (modDefMD != null) { + if (!(modDefMD is null)) { var ntHeaders = modDefMD.Metadata.PEImage.ImageNTHeaders; PEHeadersOptions.TimeDateStamp = ntHeaders.FileHeader.TimeDateStamp; PEHeadersOptions.MajorLinkerVersion = ntHeaders.OptionalHeader.MajorLinkerVersion; @@ -421,7 +421,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PEHeadersOptions.Characteristics &= ~Characteristics.Bit32Machine; PEHeadersOptions.Characteristics |= Characteristics.LargeAddressAware; } - else if (modDefMD == null) + else if (modDefMD is null) PEHeadersOptions.Characteristics |= Characteristics.Bit32Machine; } @@ -487,7 +487,7 @@ static bool TryGetPdbChecksumAlgorithm(ref DataReader reader, out ChecksumAlgori public void InitializeStrongNameSigning(ModuleDef module, StrongNameKey signatureKey) { StrongNameKey = signatureKey; StrongNamePublicKey = null; - if (module.Assembly != null) + if (!(module.Assembly is null)) module.Assembly.CustomAttributes.RemoveAll("System.Reflection.AssemblySignatureKeyAttribute"); } @@ -517,7 +517,7 @@ public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey signatureKey, StrongNamePublicKey signaturePubKey, StrongNameKey identityKey, StrongNamePublicKey identityPubKey) { StrongNameKey = signatureKey.WithHashAlgorithm(signaturePubKey.HashAlgorithm); StrongNamePublicKey = identityPubKey; - if (module.Assembly != null) + if (!(module.Assembly is null)) module.Assembly.UpdateOrCreateAssemblySignatureKeyAttribute(identityPubKey, identityKey, signaturePubKey); } } @@ -676,13 +676,13 @@ static void DeleteFileNoThrow(string fileName) { /// /// Destination stream public void Write(Stream dest) { - pdbState = TheOptions.WritePdb && Module.PdbState != null ? Module.PdbState : null; + pdbState = TheOptions.WritePdb && !(Module.PdbState is null) ? Module.PdbState : null; if (TheOptions.DelaySign) { - Debug.Assert(TheOptions.StrongNamePublicKey != null, "Options.StrongNamePublicKey must be initialized when delay signing the assembly"); - Debug.Assert(TheOptions.StrongNameKey == null, "Options.StrongNameKey must be null when delay signing the assembly"); + Debug.Assert(!(TheOptions.StrongNamePublicKey is null), "Options.StrongNamePublicKey must be initialized when delay signing the assembly"); + Debug.Assert(TheOptions.StrongNameKey is null, "Options.StrongNameKey must be null when delay signing the assembly"); TheOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.StrongNameSigned; } - else if (TheOptions.StrongNameKey != null || TheOptions.StrongNamePublicKey != null) + else if (!(TheOptions.StrongNameKey is null) || !(TheOptions.StrongNamePublicKey is null)) TheOptions.Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; destStream = dest; @@ -710,13 +710,13 @@ public void Write(Stream dest) { /// set or wants to sign the assembly. /// protected void CreateStrongNameSignature() { - if (TheOptions.DelaySign && TheOptions.StrongNamePublicKey != null) { + if (TheOptions.DelaySign && !(TheOptions.StrongNamePublicKey is null)) { int len = TheOptions.StrongNamePublicKey.CreatePublicKey().Length - 0x20; strongNameSignature = new StrongNameSignature(len > 0 ? len : 0x80); } - else if (TheOptions.StrongNameKey != null) + else if (!(TheOptions.StrongNameKey is null)) strongNameSignature = new StrongNameSignature(TheOptions.StrongNameKey.SignatureSize); - else if (Module.Assembly != null && !PublicKeyBase.IsNullOrEmpty2(Module.Assembly.PublicKey)) { + else if (!(Module.Assembly is null) && !PublicKeyBase.IsNullOrEmpty2(Module.Assembly.PublicKey)) { int len = Module.Assembly.PublicKey.Data.Length - 0x20; strongNameSignature = new StrongNameSignature(len > 0 ? len : 0x80); } @@ -735,7 +735,7 @@ protected void CreateMetadataChunks(ModuleDef module) { netResources = new NetResources(DEFAULT_NETRESOURCES_ALIGNMENT); DebugMetadataKind debugKind; - if (pdbState != null && (pdbState.PdbFileKind == PdbFileKind.PortablePDB || pdbState.PdbFileKind == PdbFileKind.EmbeddedPortablePDB)) + if (!(pdbState is null) && (pdbState.PdbFileKind == PdbFileKind.PortablePDB || pdbState.PdbFileKind == PdbFileKind.EmbeddedPortablePDB)) debugKind = DebugMetadataKind.Standalone; else debugKind = DebugMetadataKind.None; @@ -747,13 +747,13 @@ protected void CreateMetadataChunks(ModuleDef module) { // StrongNamePublicKey is used if the user wants to override the assembly's // public key or when enhanced strong naming the assembly. var pk = TheOptions.StrongNamePublicKey; - if (pk != null) + if (!(pk is null)) metadata.AssemblyPublicKey = pk.CreatePublicKey(); - else if (TheOptions.StrongNameKey != null) + else if (!(TheOptions.StrongNameKey is null)) metadata.AssemblyPublicKey = TheOptions.StrongNameKey.PublicKey; var w32Resources = GetWin32Resources(); - if (w32Resources != null) + if (!(w32Resources is null)) win32Resources = new Win32ResourcesChunk(w32Resources); } @@ -816,7 +816,7 @@ protected void StrongNameSign(long snSigOffset) { snSigner.WriteSignature(TheOptions.StrongNameKey, snSigOffset); } - bool CanWritePdb() => pdbState != null; + bool CanWritePdb() => !(pdbState is null); /// /// Creates the debug directory if a PDB file should be written @@ -833,10 +833,10 @@ protected void CreateDebugDirectory() { protected void WritePdbFile() { if (!CanWritePdb()) return; - if (debugDirectory == null) + if (debugDirectory is null) throw new InvalidOperationException("debugDirectory is null but WritePdb is true"); - if (pdbState == null) { + if (pdbState is null) { Error("TheOptions.WritePdb is true but module has no PdbState"); return; } @@ -885,7 +885,7 @@ void WriteWindowsPdb(PdbState pdbState) { bool addPdbChecksumDebugDirectoryEntry = (TheOptions.PdbOptions & PdbWriterOptions.PdbChecksum) != 0; addPdbChecksumDebugDirectoryEntry = false;//TODO: If this is true, get the checksum from the PDB writer var symWriter = GetWindowsPdbSymbolWriter(TheOptions.PdbOptions, out var pdbFilename); - if (symWriter == null) { + if (symWriter is null) { Error("Could not create a PDB symbol writer. A Windows OS might be required."); return; } @@ -905,7 +905,7 @@ void WriteWindowsPdb(PdbState pdbState) { } else { Debug.Fail("Failed to get the PDB content ID"); - if (codeViewData == null) + if (codeViewData is null) throw new InvalidOperationException(); var entry = debugDirectory.Add(codeViewData); entry.DebugDirectory = idd; @@ -933,7 +933,7 @@ protected uint GetTimeDateStamp() { } SymbolWriter GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbFilename) { - if (TheOptions.PdbStream != null) { + if (!(TheOptions.PdbStream is null)) { return Pdb.Dss.SymbolReaderWriterFactory.Create(options, TheOptions.PdbStream, pdbFilename = TheOptions.PdbFileName ?? GetStreamName(TheOptions.PdbStream) ?? @@ -946,7 +946,7 @@ SymbolWriter GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbF } createdPdbFileName = pdbFilename = GetDefaultPdbFileName(); - if (createdPdbFileName == null) + if (createdPdbFileName is null) return null; return Pdb.Dss.SymbolReaderWriterFactory.Create(options, createdPdbFileName); } @@ -983,7 +983,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { } else pdbStream = GetStandalonePortablePdbStream(out ownsStream); - if (pdbStream == null) + if (pdbStream is null) throw new ModuleWriterException("Couldn't create a PDB stream"); var pdbFilename = TheOptions.PdbFileName ?? GetStreamName(pdbStream) ?? GetDefaultPdbFileName(); @@ -991,7 +991,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { pdbFilename = Path.GetFileName(pdbFilename); uint entryPointToken; - if (pdbState.UserEntryPoint == null) + if (pdbState.UserEntryPoint is null) entryPointToken = 0; else entryPointToken = new MDToken(Table.Method, metadata.GetRid(pdbState.UserEntryPoint)).Raw; @@ -1005,7 +1005,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { byte[] checksumBytes; if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0 || (TheOptions.PdbOptions & PdbWriterOptions.PdbChecksum) != 0 || - TheOptions.GetPdbContentId == null) { + TheOptions.GetPdbContentId is null) { pdbStream.Position = 0; checksumBytes = Hasher.Hash(TheOptions.PdbChecksumAlgorithm, pdbStream, pdbStream.Length); if (checksumBytes.Length < 20) @@ -1036,14 +1036,14 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, timeDateStamp: codeViewTimestamp); - if (checksumBytes != null) + if (!(checksumBytes is null)) AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm); if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0) AddReproduciblePdbDebugDirectoryEntry(); if (isEmbeddedPortablePdb) { - Debug.Assert(embeddedMemoryStream != null); + Debug.Assert(!(embeddedMemoryStream is null)); debugDirectory.Add(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream), type: ImageDebugType.EmbeddedPortablePdb, majorVersion: PortablePdbConstants.FormatVersion, @@ -1052,7 +1052,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { } } finally { - if (ownsStream && pdbStream != null) + if (ownsStream && !(pdbStream is null)) pdbStream.Dispose(); } } @@ -1091,7 +1091,7 @@ static byte[] GetCodeViewData(Guid guid, uint age, string filename) { } Stream GetStandalonePortablePdbStream(out bool ownsStream) { - if (TheOptions.PdbStream != null) { + if (!(TheOptions.PdbStream is null)) { ownsStream = false; return TheOptions.PdbStream; } @@ -1100,7 +1100,7 @@ Stream GetStandalonePortablePdbStream(out bool ownsStream) { createdPdbFileName = TheOptions.PdbFileName; else createdPdbFileName = GetDefaultPdbFileName(); - if (createdPdbFileName == null) { + if (createdPdbFileName is null) { ownsStream = false; return null; } diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 95694de23..20470ccc6 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -194,7 +194,7 @@ protected override long WriteImpl() { return Write(); } finally { - if (origSections != null) { + if (!(origSections is null)) { foreach (var section in origSections) section.Dispose(); } @@ -247,7 +247,7 @@ void AddChunksToSections() { textSection.Add(netResources, DEFAULT_NETRESOURCES_ALIGNMENT); textSection.Add(metadata, DEFAULT_METADATA_ALIGNMENT); textSection.Add(debugDirectory, DebugDirectory.DEFAULT_DEBUGDIRECTORY_ALIGNMENT); - if (rsrcSection != null) + if (!(rsrcSection is null)) rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); } @@ -261,7 +261,7 @@ protected override Win32Resources GetWin32Resources() { void CreatePESections() { sections = new List(); sections.Add(textSection = new PESection(".text", 0x60000020)); - if (GetWin32Resources() != null) + if (!(GetWin32Resources() is null)) sections.Add(rsrcSection = new PESection(".rsrc", 0x40000040)); } @@ -345,14 +345,14 @@ uint GetLastFileSectionOffset() { void ReuseIfPossible(PESection section, IReuseChunk chunk, RVA origRva, uint origSize, uint requiredAlignment) { if (origRva == 0 || origSize == 0) return; - if (chunk == null) + if (chunk is null) return; if (!chunk.CanReuse(origRva, origSize)) return; if (((uint)origRva & (requiredAlignment - 1)) != 0) return; - if (section.Remove(chunk) == null) + if (section.Remove(chunk) is null) throw new InvalidOperationException(); reusedChunks.Add(new ReusedChunkInfo(chunk, origRva)); } @@ -381,7 +381,7 @@ long WriteFile() { ReuseIfPossible(textSection, metadata, mdDataDir.VirtualAddress, mdDataDir.Size, DEFAULT_METADATA_ALIGNMENT); var resourceDataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[2]; - if (win32Resources != null && resourceDataDir.VirtualAddress != 0 && resourceDataDir.Size != 0) { + if (!(win32Resources is null) && resourceDataDir.VirtualAddress != 0 && resourceDataDir.Size != 0) { var win32ResourcesOffset = peImage.ToFileOffset(resourceDataDir.VirtualAddress); if (win32Resources.CheckValidOffset(win32ResourcesOffset)) { win32Resources.SetOffset(win32ResourcesOffset, resourceDataDir.VirtualAddress); @@ -407,7 +407,7 @@ long WriteFile() { textSection.Remove(netResources); if (textSection.IsEmpty) sections.Remove(textSection); - if (rsrcSection != null && rsrcSection.IsEmpty) { + if (!(rsrcSection is null) && rsrcSection.IsEmpty) { sections.Remove(rsrcSection); rsrcSection = null; } @@ -415,7 +415,7 @@ long WriteFile() { var headerSection = CreateHeaderSection(out var extraHeaderData); var chunks = new List(); uint headerLen; - if (extraHeaderData != null) { + if (!(extraHeaderData is null)) { var list = new ChunkList(); list.Add(headerSection, 1); list.Add(extraHeaderData, 1); @@ -430,7 +430,7 @@ long WriteFile() { chunks.Add(origSection.Chunk); foreach (var section in sections) chunks.Add(section); - if (extraData != null) + if (!(extraData is null)) chunks.Add(extraData); if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { @@ -477,7 +477,7 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.EndWriteChunks); OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); - if (Options.StrongNameKey != null) + if (!(Options.StrongNameKey is null)) StrongNameSign((long)strongNameSignature.FileOffset); OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); @@ -623,7 +623,7 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin } // Update Win32 resources data directory, if we wrote a new one - if (win32Resources != null) { + if (!(win32Resources is null)) { writer.Position = dataDirOffset + 2 * 8; writer.WriteDataDirectory(win32Resources); } @@ -674,49 +674,49 @@ static void WriteDataDirectory(DataWriter writer, ImageDataDirectory dataDir) { } static void WriteByte(DataWriter writer, byte? value) { - if (value == null) + if (value is null) writer.Position++; else writer.WriteByte(value.Value); } static void WriteUInt16(DataWriter writer, ushort? value) { - if (value == null) + if (value is null) writer.Position += 2; else writer.WriteUInt16(value.Value); } static void WriteUInt16(DataWriter writer, Subsystem? value) { - if (value == null) + if (value is null) writer.Position += 2; else writer.WriteUInt16((ushort)value.Value); } static void WriteUInt16(DataWriter writer, DllCharacteristics? value) { - if (value == null) + if (value is null) writer.Position += 2; else writer.WriteUInt16((ushort)value.Value); } static void WriteUInt32(DataWriter writer, uint? value) { - if (value == null) + if (value is null) writer.Position += 4; else writer.WriteUInt32(value.Value); } static void WriteUInt32(DataWriter writer, ulong? value) { - if (value == null) + if (value is null) writer.Position += 4; else writer.WriteUInt32((uint)value.Value); } static void WriteUInt64(DataWriter writer, ulong? value) { - if (value == null) + if (value is null) writer.Position += 8; else writer.WriteUInt64(value.Value); @@ -724,7 +724,7 @@ static void WriteUInt64(DataWriter writer, ulong? value) { ComImageFlags GetComImageFlags(bool isManagedEntryPoint) { var flags = Options.Cor20HeaderOptions.Flags ?? module.Cor20HeaderFlags; - if (Options.Cor20HeaderOptions.EntryPoint != null) + if (!(Options.Cor20HeaderOptions.EntryPoint is null)) return flags; if (isManagedEntryPoint) return flags & ~ComImageFlags.NativeEntryPoint; @@ -761,7 +761,7 @@ IEnumerable GetSectionSizeInfos() { void UpdateVTableFixups(DataWriter writer) { var vtableFixups = module.VTableFixups; - if (vtableFixups == null || vtableFixups.VTables.Count == 0) + if (vtableFixups is null || vtableFixups.VTables.Count == 0) return; writer.Position = ToWriterOffset(vtableFixups.RVA); @@ -806,7 +806,7 @@ uint GetMethodToken(IMethod method) { if (method is MethodSpec ms) return new MDToken(Table.MethodSpec, metadata.GetRid(ms)).Raw; - if (method == null) + if (method is null) return 0; Error("Invalid VTable method type: {0}", method.GetType()); @@ -821,7 +821,7 @@ uint GetMethodToken(IMethod method) { /// false if it's a native entry point bool GetEntryPoint(out uint ep) { var tok = Options.Cor20HeaderOptions.EntryPoint; - if (tok != null) { + if (!(tok is null)) { ep = tok.Value; return ep == 0 || ((Options.Cor20HeaderOptions.Flags ?? 0) & ComImageFlags.NativeEntryPoint) == 0; } diff --git a/src/DotNet/Writer/NormalMetadata.cs b/src/DotNet/Writer/NormalMetadata.cs index baf52ee3d..13ef316d0 100644 --- a/src/DotNet/Writer/NormalMetadata.cs +++ b/src/DotNet/Writer/NormalMetadata.cs @@ -36,7 +36,7 @@ protected override TypeDef[] GetAllTypeDefs() { /// protected override void AllocateTypeDefRids() { foreach (var type in allTypeDefs) { - if (type == null) + if (type is null) continue; uint rid = tablesHeap.TypeDefTable.Create(new RawTypeDefRow()); typeDefInfos.Add(type, rid); @@ -62,7 +62,7 @@ protected override void AllocateMemberDefRids() { notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); } - if (type == null) + if (type is null) continue; uint typeRid = GetRid(type); var typeRow = tablesHeap.TypeDefTable[typeRid]; @@ -73,7 +73,7 @@ protected override void AllocateMemberDefRids() { count = fields.Count; for (int i = 0; i < count; i++) { var field = fields[i]; - if (field == null) + if (field is null) continue; uint rid = fieldListRid++; if (rid != tablesHeap.FieldTable.Create(new RawFieldRow())) @@ -85,7 +85,7 @@ protected override void AllocateMemberDefRids() { count = methods.Count; for (int i = 0; i < count; i++) { var method = methods[i]; - if (method == null) + if (method is null) continue; uint rid = methodListRid++; var row = new RawMethodRow(0, 0, 0, 0, 0, paramListRid); @@ -93,7 +93,7 @@ protected override void AllocateMemberDefRids() { throw new ModuleWriterException("Invalid method rid"); methodDefInfos.Add(method, rid); foreach (var pd in Sort(method.ParamDefs)) { - if (pd == null) + if (pd is null) continue; uint pdRid = paramListRid++; if (pdRid != tablesHeap.ParamTable.Create(new RawParamRow())) @@ -109,7 +109,7 @@ protected override void AllocateMemberDefRids() { count = events.Count; for (int i = 0; i < count; i++) { var evt = events[i]; - if (evt == null) + if (evt is null) continue; uint rid = eventListRid++; if (rid != tablesHeap.EventTable.Create(new RawEventRow())) @@ -125,7 +125,7 @@ protected override void AllocateMemberDefRids() { count = properties.Count; for (int i = 0; i < count; i++) { var prop = properties[i]; - if (prop == null) + if (prop is null) continue; uint rid = propertyListRid++; if (rid != tablesHeap.PropertyTable.Create(new RawPropertyRow())) @@ -146,7 +146,7 @@ public override uint GetRid(TypeRef tr) { public override uint GetRid(TypeDef td) { if (typeDefInfos.TryGetRid(td, out uint rid)) return rid; - if (td == null) + if (td is null) Error("TypeDef is null"); else Error("TypeDef {0} ({1:X8}) is not defined in this module ({2}). A type was removed that is still referenced by this module.", td, td.MDToken.Raw, module); @@ -157,7 +157,7 @@ public override uint GetRid(TypeDef td) { public override uint GetRid(FieldDef fd) { if (fieldDefInfos.TryGetRid(fd, out uint rid)) return rid; - if (fd == null) + if (fd is null) Error("Field is null"); else Error("Field {0} ({1:X8}) is not defined in this module ({2}). A field was removed that is still referenced by this module.", fd, fd.MDToken.Raw, module); @@ -168,7 +168,7 @@ public override uint GetRid(FieldDef fd) { public override uint GetRid(MethodDef md) { if (methodDefInfos.TryGetRid(md, out uint rid)) return rid; - if (md == null) + if (md is null) Error("Method is null"); else Error("Method {0} ({1:X8}) is not defined in this module ({2}). A method was removed that is still referenced by this module.", md, md.MDToken.Raw, module); @@ -179,7 +179,7 @@ public override uint GetRid(MethodDef md) { public override uint GetRid(ParamDef pd) { if (paramDefInfos.TryGetRid(pd, out uint rid)) return rid; - if (pd == null) + if (pd is null) Error("Param is null"); else Error("Param {0} ({1:X8}) is not defined in this module ({2}). A parameter was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); @@ -202,7 +202,7 @@ public override uint GetRid(StandAloneSig sas) { public override uint GetRid(EventDef ed) { if (eventDefInfos.TryGetRid(ed, out uint rid)) return rid; - if (ed == null) + if (ed is null) Error("Event is null"); else Error("Event {0} ({1:X8}) is not defined in this module ({2}). An event was removed that is still referenced by this module.", ed, ed.MDToken.Raw, module); @@ -213,7 +213,7 @@ public override uint GetRid(EventDef ed) { public override uint GetRid(PropertyDef pd) { if (propertyDefInfos.TryGetRid(pd, out uint rid)) return rid; - if (pd == null) + if (pd is null) Error("Property is null"); else Error("Property {0} ({1:X8}) is not defined in this module ({2}). A property was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); @@ -234,7 +234,7 @@ public override uint GetRid(MethodSpec ms) { /// protected override uint AddTypeRef(TypeRef tr) { - if (tr == null) { + if (tr is null) { Error("TypeRef is null"); return 0; } @@ -256,7 +256,7 @@ protected override uint AddTypeRef(TypeRef tr) { /// protected override uint AddTypeSpec(TypeSpec ts) { - if (ts == null) { + if (ts is null) { Error("TypeSpec is null"); return 0; } @@ -276,7 +276,7 @@ protected override uint AddTypeSpec(TypeSpec ts) { /// protected override uint AddMemberRef(MemberRef mr) { - if (mr == null) { + if (mr is null) { Error("MemberRef is null"); return 0; } @@ -295,7 +295,7 @@ protected override uint AddMemberRef(MemberRef mr) { /// protected override uint AddStandAloneSig(StandAloneSig sas) { - if (sas == null) { + if (sas is null) { Error("StandAloneSig is null"); return 0; } @@ -311,7 +311,7 @@ protected override uint AddStandAloneSig(StandAloneSig sas) { /// protected override uint AddMethodSpec(MethodSpec ms) { - if (ms == null) { + if (ms is null) { Error("MethodSpec is null"); return 0; } diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 745f3e092..899f7ec9d 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -356,7 +356,7 @@ public void WriteTo(DataWriter writer) { var sectionSizes = new SectionSizes(fileAlignment, sectionAlignment, length, () => GetSectionSizeInfos()); // Image optional header - uint ep = StartupStub == null || !StartupStub.Enable ? 0 : (uint)StartupStub.EntryPointRVA; + uint ep = StartupStub is null || !StartupStub.Enable ? 0 : (uint)StartupStub.EntryPointRVA; if (Use32BitOptionalHeader()) { writer.WriteUInt16((ushort)0x010B); writer.WriteByte(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION); diff --git a/src/DotNet/Writer/PreserveTokensMetadata.cs b/src/DotNet/Writer/PreserveTokensMetadata.cs index 0970f7dd5..de7c66cc9 100644 --- a/src/DotNet/Writer/PreserveTokensMetadata.cs +++ b/src/DotNet/Writer/PreserveTokensMetadata.cs @@ -192,7 +192,7 @@ public void SortDefs() { public PreserveTokensMetadata(ModuleDef module, UniqueChunkList constants, MethodBodyChunks methodBodies, NetResources netResources, MetadataOptions options, DebugMetadataKind debugKind, bool isStandaloneDebugMetadata) : base(module, constants, methodBodies, netResources, options, debugKind, isStandaloneDebugMetadata) { mod = module as ModuleDefMD; - if (mod == null) + if (mod is null) throw new ModuleWriterException("Not a ModuleDefMD"); } @@ -204,7 +204,7 @@ public override uint GetRid(TypeRef tr) { /// public override uint GetRid(TypeDef td) { - if (td == null) { + if (td is null) { Error("TypeDef is null"); return 0; } @@ -218,7 +218,7 @@ public override uint GetRid(TypeDef td) { public override uint GetRid(FieldDef fd) { if (fieldDefInfos.TryGetRid(fd, out uint rid)) return rid; - if (fd == null) + if (fd is null) Error("Field is null"); else Error("Field {0} ({1:X8}) is not defined in this module ({2}). A field was removed that is still referenced by this module.", fd, fd.MDToken.Raw, module); @@ -229,7 +229,7 @@ public override uint GetRid(FieldDef fd) { public override uint GetRid(MethodDef md) { if (methodDefInfos.TryGetRid(md, out uint rid)) return rid; - if (md == null) + if (md is null) Error("Method is null"); else Error("Method {0} ({1:X8}) is not defined in this module ({2}). A method was removed that is still referenced by this module.", md, md.MDToken.Raw, module); @@ -240,7 +240,7 @@ public override uint GetRid(MethodDef md) { public override uint GetRid(ParamDef pd) { if (paramDefInfos.TryGetRid(pd, out uint rid)) return rid; - if (pd == null) + if (pd is null) Error("Param is null"); else Error("Param {0} ({1:X8}) is not defined in this module ({2}). A parameter was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); @@ -263,7 +263,7 @@ public override uint GetRid(StandAloneSig sas) { public override uint GetRid(EventDef ed) { if (eventDefInfos.TryGetRid(ed, out uint rid)) return rid; - if (ed == null) + if (ed is null) Error("Event is null"); else Error("Event {0} ({1:X8}) is not defined in this module ({2}). An event was removed that is still referenced by this module.", ed, ed.MDToken.Raw, module); @@ -274,7 +274,7 @@ public override uint GetRid(EventDef ed) { public override uint GetRid(PropertyDef pd) { if (propertyDefInfos.TryGetRid(pd, out uint rid)) return rid; - if (pd == null) + if (pd is null) Error("Property is null"); else Error("Property {0} ({1:X8}) is not defined in this module ({2}). A property was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); @@ -318,7 +318,7 @@ protected override TypeDef[] GetAllTypeDefs() { const uint IS_TYPEDEFMD = 0x80000000; const uint INDEX_BITS = 0x00FFFFFF; foreach (var type in module.GetTypes()) { - if (type == null) + if (type is null) continue; types.Add(type); uint val = (uint)index++; @@ -390,7 +390,7 @@ protected override TypeDef[] GetAllTypeDefs() { void InitializeTypeToRid(TypeDef[] types) { uint rid = 1; foreach (var type in types) { - if (type == null) + if (type is null) continue; if (typeToRid.ContainsKey(type)) continue; @@ -841,7 +841,7 @@ void FindMemberDefs() { var added = new Dictionary(); int pos; foreach (var type in allTypeDefs) { - if (type == null) + if (type is null) continue; pos = 0; @@ -849,7 +849,7 @@ void FindMemberDefs() { count = fields.Count; for (int i = 0; i < count; i++) { var field = fields[i]; - if (field == null) + if (field is null) continue; fieldDefInfos.Add(field, pos++); } @@ -859,7 +859,7 @@ void FindMemberDefs() { count = methods.Count; for (int i = 0; i < count; i++) { var method = methods[i]; - if (method == null) + if (method is null) continue; methodDefInfos.Add(method, pos++); } @@ -869,7 +869,7 @@ void FindMemberDefs() { count = events.Count; for (int i = 0; i < count; i++) { var evt = events[i]; - if (evt == null || added.ContainsKey(evt)) + if (evt is null || added.ContainsKey(evt)) continue; added[evt] = true; eventDefInfos.Add(evt, pos++); @@ -880,7 +880,7 @@ void FindMemberDefs() { count = properties.Count; for (int i = 0; i < count; i++) { var prop = properties[i]; - if (prop == null || added.ContainsKey(prop)) + if (prop is null || added.ContainsKey(prop)) continue; added[prop] = true; propertyDefInfos.Add(prop, pos++); @@ -896,7 +896,7 @@ void FindMemberDefs() { var method = methodDefInfos.Get(i).Def; pos = 0; foreach (var param in Sort(method.ParamDefs)) { - if (param == null) + if (param is null) continue; paramDefInfos.Add(param, pos++); } @@ -906,8 +906,8 @@ void FindMemberDefs() { void SortFields() => fieldDefInfos.Sort((a, b) => { - var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; - var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; + var dta = a.Def.DeclaringType is null ? 0 : typeToRid[a.Def.DeclaringType]; + var dtb = b.Def.DeclaringType is null ? 0 : typeToRid[b.Def.DeclaringType]; if (dta == 0 || dtb == 0) return a.Rid.CompareTo(b.Rid); if (dta != dtb) @@ -917,8 +917,8 @@ void SortFields() => void SortMethods() => methodDefInfos.Sort((a, b) => { - var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; - var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; + var dta = a.Def.DeclaringType is null ? 0 : typeToRid[a.Def.DeclaringType]; + var dtb = b.Def.DeclaringType is null ? 0 : typeToRid[b.Def.DeclaringType]; if (dta == 0 || dtb == 0) return a.Rid.CompareTo(b.Rid); if (dta != dtb) @@ -928,8 +928,8 @@ void SortMethods() => void SortParameters() => paramDefInfos.Sort((a, b) => { - var dma = a.Def.DeclaringMethod == null ? 0 : methodDefInfos.Rid(a.Def.DeclaringMethod); - var dmb = b.Def.DeclaringMethod == null ? 0 : methodDefInfos.Rid(b.Def.DeclaringMethod); + var dma = a.Def.DeclaringMethod is null ? 0 : methodDefInfos.Rid(a.Def.DeclaringMethod); + var dmb = b.Def.DeclaringMethod is null ? 0 : methodDefInfos.Rid(b.Def.DeclaringMethod); if (dma == 0 || dmb == 0) return a.Rid.CompareTo(b.Rid); if (dma != dmb) @@ -939,8 +939,8 @@ void SortParameters() => void SortEvents() => eventDefInfos.Sort((a, b) => { - var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; - var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; + var dta = a.Def.DeclaringType is null ? 0 : typeToRid[a.Def.DeclaringType]; + var dtb = b.Def.DeclaringType is null ? 0 : typeToRid[b.Def.DeclaringType]; if (dta == 0 || dtb == 0) return a.Rid.CompareTo(b.Rid); if (dta != dtb) @@ -950,8 +950,8 @@ void SortEvents() => void SortProperties() => propertyDefInfos.Sort((a, b) => { - var dta = a.Def.DeclaringType == null ? 0 : typeToRid[a.Def.DeclaringType]; - var dtb = b.Def.DeclaringType == null ? 0 : typeToRid[b.Def.DeclaringType]; + var dta = a.Def.DeclaringType is null ? 0 : typeToRid[a.Def.DeclaringType]; + var dtb = b.Def.DeclaringType is null ? 0 : typeToRid[b.Def.DeclaringType]; if (dta == 0 || dtb == 0) return a.Rid.CompareTo(b.Rid); if (dta != dtb) @@ -978,7 +978,7 @@ void InitializeParamList() { var row = tablesHeap.MethodTable[methodRid]; row = new RawMethodRow(row.RVA, row.ImplFlags, row.Flags, row.Name, row.Signature, ridList); tablesHeap.MethodTable[methodRid] = row; - if (methodInfo != null) + if (!(methodInfo is null)) ridList += (uint)methodInfo.Def.ParamDefs.Count; } } @@ -1015,7 +1015,7 @@ void InitializePropertyMap() { /// protected override uint AddTypeRef(TypeRef tr) { - if (tr == null) { + if (tr is null) { Error("TypeRef is null"); return 0; } @@ -1044,7 +1044,7 @@ protected override uint AddTypeRef(TypeRef tr) { protected override uint AddTypeSpec(TypeSpec ts) => AddTypeSpec(ts, false); uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { - if (ts == null) { + if (ts is null) { Error("TypeSpec is null"); return 0; } @@ -1073,7 +1073,7 @@ uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { protected override uint AddMemberRef(MemberRef mr) => AddMemberRef(mr, false); uint AddMemberRef(MemberRef mr, bool forceIsOld) { - if (mr == null) { + if (mr is null) { Error("MemberRef is null"); return 0; } @@ -1098,7 +1098,7 @@ uint AddMemberRef(MemberRef mr, bool forceIsOld) { protected override uint AddStandAloneSig(StandAloneSig sas) => AddStandAloneSig(sas, false); uint AddStandAloneSig(StandAloneSig sas, bool forceIsOld) { - if (sas == null) { + if (sas is null) { Error("StandAloneSig is null"); return 0; } @@ -1193,7 +1193,7 @@ bool IsValidStandAloneSigToken(uint token) { protected override uint AddMethodSpec(MethodSpec ms) => AddMethodSpec(ms, false); uint AddMethodSpec(MethodSpec ms, bool forceIsOld) { - if (ms == null) { + if (ms is null) { Error("MethodSpec is null"); return 0; } diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index 64ad033d7..a2f8e1bf1 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -50,7 +50,7 @@ public void SetOffset(FileOffset offset, RVA rva) { var allRvas = new List(allRelocRvas.Count); foreach (var info in allRelocRvas) { uint relocRva; - if (info.Chunk != null) + if (!(info.Chunk is null)) relocRva = (uint)info.Chunk.RVA + info.OffsetOrRva; else relocRva = info.OffsetOrRva; @@ -64,14 +64,14 @@ public void SetOffset(FileOffset offset, RVA rva) { uint page = relocRva & ~0xFFFU; if (page != prevPage) { prevPage = page; - if (pageList != null) + if (!(pageList is null)) totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); pageList = new List(); relocSections.Add(pageList); } pageList.Add(relocRva); } - if (pageList != null) + if (!(pageList is null)) totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); } diff --git a/src/DotNet/Writer/SerializerMethodContext.cs b/src/DotNet/Writer/SerializerMethodContext.cs index 64f42a494..b1ebbb10a 100644 --- a/src/DotNet/Writer/SerializerMethodContext.cs +++ b/src/DotNet/Writer/SerializerMethodContext.cs @@ -13,7 +13,7 @@ sealed class SerializerMethodContext { uint bodySize; bool dictInitd; - public bool HasBody => body != null; + public bool HasBody => !(body is null); public SerializerMethodContext(IWriterError helper) { toOffset = new Dictionary(); @@ -31,12 +31,12 @@ internal void SetBody(MethodDef method) { public uint GetOffset(Instruction instr) { if (!dictInitd) { - Debug.Assert(body != null); - if (body == null) + Debug.Assert(!(body is null)); + if (body is null) return 0; InitializeDict(); } - if (instr == null) + if (instr is null) return bodySize; if (toOffset.TryGetValue(instr, out uint offset)) return offset; @@ -47,7 +47,7 @@ public uint GetOffset(Instruction instr) { public bool IsSameMethod(MethodDef method) => this.method == method; void InitializeDict() { - Debug.Assert(body != null); + Debug.Assert(!(body is null)); Debug.Assert(toOffset.Count == 0); uint offset = 0; var instrs = body.Instructions; diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index 1ae7e2b96..f74531cc2 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -89,7 +89,7 @@ internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig void Write(TypeSig typeSig) { const ElementType DEFAULT_ELEMENT_TYPE = ElementType.Boolean; - if (typeSig == null) { + if (typeSig is null) { helper.Error("TypeSig is null"); writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); return; @@ -205,7 +205,7 @@ void Write(TypeSig typeSig) { } void Write(ITypeDefOrRef tdr) { - if (tdr == null) { + if (tdr is null) { helper.Error("TypeDefOrRef is null"); WriteCompressedUInt32(0); return; @@ -220,7 +220,7 @@ void Write(ITypeDefOrRef tdr) { } void Write(CallingConventionSig sig) { - if (sig == null) { + if (sig is null) { helper.Error("sig is null"); return; } @@ -234,13 +234,13 @@ void Write(CallingConventionSig sig) { LocalSig ls; GenericInstMethodSig gim; - if ((mbs = sig as MethodBaseSig) != null) + if (!((mbs = sig as MethodBaseSig) is null)) Write(mbs); - else if ((fs = sig as FieldSig) != null) + else if (!((fs = sig as FieldSig) is null)) Write(fs); - else if ((ls = sig as LocalSig) != null) + else if (!((ls = sig as LocalSig) is null)) Write(ls); - else if ((gim = sig as GenericInstMethodSig) != null) + else if (!((gim = sig as GenericInstMethodSig) is null)) Write(gim); else { helper.Error("Unknown calling convention sig"); @@ -251,7 +251,7 @@ void Write(CallingConventionSig sig) { } void Write(MethodBaseSig sig) { - if (sig == null) { + if (sig is null) { helper.Error("sig is null"); return; } @@ -265,7 +265,7 @@ void Write(MethodBaseSig sig) { WriteCompressedUInt32(sig.GenParamCount); uint numParams = (uint)sig.Params.Count; - if (sig.ParamsAfterSentinel != null) + if (!(sig.ParamsAfterSentinel is null)) numParams += (uint)sig.ParamsAfterSentinel.Count; uint count = WriteCompressedUInt32(numParams); @@ -273,7 +273,7 @@ void Write(MethodBaseSig sig) { for (uint i = 0; i < count && i < (uint)sig.Params.Count; i++) Write(sig.Params[(int)i]); - if (sig.ParamsAfterSentinel != null && sig.ParamsAfterSentinel.Count > 0) { + if (!(sig.ParamsAfterSentinel is null) && sig.ParamsAfterSentinel.Count > 0) { writer.WriteByte((byte)ElementType.Sentinel); for (uint i = 0, j = (uint)sig.Params.Count; i < (uint)sig.ParamsAfterSentinel.Count && j < count; i++, j++) Write(sig.ParamsAfterSentinel[(int)i]); @@ -283,7 +283,7 @@ void Write(MethodBaseSig sig) { } void Write(FieldSig sig) { - if (sig == null) { + if (sig is null) { helper.Error("sig is null"); return; } @@ -299,7 +299,7 @@ void Write(FieldSig sig) { } void Write(LocalSig sig) { - if (sig == null) { + if (sig is null) { helper.Error("sig is null"); return; } @@ -321,7 +321,7 @@ void Write(LocalSig sig) { } void Write(GenericInstMethodSig sig) { - if (sig == null) { + if (sig is null) { helper.Error("sig is null"); return; } @@ -342,7 +342,7 @@ void Write(GenericInstMethodSig sig) { public void Dispose() { if (!disposeStream) return; - if (outStream != null) + if (!(outStream is null)) outStream.Dispose(); } } diff --git a/src/DotNet/Writer/StartupStub.cs b/src/DotNet/Writer/StartupStub.cs index e46f26f4a..e5c36f64d 100644 --- a/src/DotNet/Writer/StartupStub.cs +++ b/src/DotNet/Writer/StartupStub.cs @@ -36,10 +36,10 @@ public sealed class StartupStub : IChunk { /// /// Gets the address of the JMP instruction /// - public RVA EntryPointRVA => rva + (cpuArch == null ? 0 : cpuArch.GetStubCodeOffset(stubType)); + public RVA EntryPointRVA => rva + (cpuArch is null ? 0 : cpuArch.GetStubCodeOffset(stubType)); internal bool Enable { get; set; } - internal uint Alignment => cpuArch == null ? 1 : cpuArch.GetStubAlignment(stubType); + internal uint Alignment => cpuArch is null ? 1 : cpuArch.GetStubAlignment(stubType); /// /// Constructor @@ -62,7 +62,7 @@ public void SetOffset(FileOffset offset, RVA rva) { if (!Enable) return; - if (cpuArch == null) { + if (cpuArch is null) { logError("The module needs an unmanaged entry point but the CPU architecture isn't supported: {0} (0x{1:X4})", new object[] { machine, (ushort)machine }); return; } @@ -74,7 +74,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetFileLength() { if (!Enable) return 0; - if (cpuArch == null) + if (cpuArch is null) return 0; return cpuArch.GetStubSize(stubType); } @@ -86,7 +86,7 @@ public uint GetFileLength() { public void WriteTo(DataWriter writer) { if (!Enable) return; - if (cpuArch == null) + if (cpuArch is null) return; cpuArch.WriteStub(stubType, writer, PEHeaders.ImageBase, (uint)rva, (uint)ImportDirectory.IatCorXxxMainRVA); } diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index ff65928d9..b27bd78d2 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -45,11 +45,11 @@ public StringsOffsetInfo(UTF8String value, uint stringsId) { public void Populate(StringsStream stringsStream) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); - if (originalData != null) + if (!(originalData is null)) throw new InvalidOperationException("Can't call method twice"); if (nextOffset != 1) throw new InvalidOperationException("Add() has already been called"); - if (stringsStream == null || stringsStream.StreamLength == 0) + if (stringsStream is null || stringsStream.StreamLength == 0) return; var reader = stringsStream.CreateReader(); @@ -63,7 +63,7 @@ void Populate(ref DataReader reader) { while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; var bytes = reader.TryReadBytesUntil(0); - if (bytes == null) + if (bytes is null) break; reader.ReadByte(); // terminating zero @@ -85,7 +85,7 @@ internal void AddOptimizedStringsAndSetReadOnly() { StringsOffsetInfo prevInfo = null; foreach (var info in stringsOffsetInfos) { - if (prevInfo != null && EndsWith(prevInfo.Value, info.Value)) + if (!(prevInfo is null) && EndsWith(prevInfo.Value, info.Value)) info.StringsOffset = prevInfo.StringsOffset + (uint)(prevInfo.Value.Data.Length - info.Value.Data.Length); else info.StringsOffset = AddToCache(info.Value); @@ -199,14 +199,14 @@ uint AddToCache(UTF8String s) { /// protected override void WriteToImpl(DataWriter writer) { - if (originalData != null) + if (!(originalData is null)) writer.WriteBytes(originalData); else writer.WriteByte(0); - uint offset = originalData != null ? (uint)originalData.Length : 1; + uint offset = !(originalData is null) ? (uint)originalData.Length : 1; foreach (var s in cached) { - if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { + if (!(userRawData is null) && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != s.Data.Length + 1) throw new InvalidOperationException("Invalid length of raw data"); writer.WriteBytes(rawData); @@ -224,14 +224,14 @@ protected override void WriteToImpl(DataWriter writer) { /// public void SetRawData(uint offset, byte[] rawData) { - if (userRawData == null) + if (userRawData is null) userRawData = new Dictionary(); userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); } /// public IEnumerable> GetAllRawData() { - uint offset = originalData != null ? (uint)originalData.Length : 1; + uint offset = !(originalData is null) ? (uint)originalData.Length : 1; foreach (var s in cached) { var rawData = new byte[s.Data.Length + 1]; Array.Copy(s.Data, rawData, s.Data.Length); diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index 09a858f1e..f6b7f0a6e 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -26,11 +26,11 @@ public sealed class USHeap : HeapBase, IOffsetHeap { /// /// The #US stream with the original content public void Populate(USStream usStream) { - if (originalData != null) + if (!(originalData is null)) throw new InvalidOperationException("Can't call method twice"); if (nextOffset != 1) throw new InvalidOperationException("Add() has already been called"); - if (usStream == null || usStream.StreamLength == 0) + if (usStream is null || usStream.StreamLength == 0) return; var reader = usStream.CreateReader(); @@ -69,7 +69,7 @@ void Populate(ref DataReader reader) { public uint Add(string s) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #US when it's read-only"); - if (s == null) + if (s is null) s = string.Empty; if (cachedDict.TryGetValue(s, out uint offset)) @@ -103,15 +103,15 @@ uint AddToCache(string s) { /// protected override void WriteToImpl(DataWriter writer) { - if (originalData != null) + if (!(originalData is null)) writer.WriteBytes(originalData); else writer.WriteByte(0); - uint offset = originalData != null ? (uint)originalData.Length : 1; + uint offset = !(originalData is null) ? (uint)originalData.Length : 1; foreach (var s in cached) { int rawLen = GetRawDataSize(s); - if (userRawData != null && userRawData.TryGetValue(offset, out var rawData)) { + if (!(userRawData is null) && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); writer.WriteBytes(rawData); @@ -139,7 +139,7 @@ void WriteString(DataWriter writer, string s) { /// public void SetRawData(uint offset, byte[] rawData) { - if (userRawData == null) + if (userRawData is null) userRawData = new Dictionary(); userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); } @@ -148,7 +148,7 @@ public void SetRawData(uint offset, byte[] rawData) { public IEnumerable> GetAllRawData() { var memStream = new MemoryStream(); var writer = new DataWriter(memStream); - uint offset = originalData != null ? (uint)originalData.Length : 1; + uint offset = !(originalData is null) ? (uint)originalData.Length : 1; foreach (var s in cached) { memStream.Position = 0; memStream.SetLength(0); diff --git a/src/DotNet/Writer/UniqueChunkList.cs b/src/DotNet/Writer/UniqueChunkList.cs index 65b85daa6..c8cf0f15b 100644 --- a/src/DotNet/Writer/UniqueChunkList.cs +++ b/src/DotNet/Writer/UniqueChunkList.cs @@ -44,7 +44,7 @@ public override void SetOffset(FileOffset offset, RVA rva) { public T Add(T chunk, uint alignment) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); - if (chunk == null) + if (chunk is null) return null; var elem = new Elem(chunk, alignment); if (dict.TryGetValue(elem, out var other)) diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 5f8e571e8..92d97179c 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -93,7 +93,7 @@ public RVA GetRVA(ResourceDirectoryEntry dirEntry) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(ResourceDirectory dir, out FileOffset fileOffset, out RVA rva) { - if (dir == null || !dirDict.TryGetValue(dir, out uint offs)) { + if (dir is null || !dirDict.TryGetValue(dir, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -137,7 +137,7 @@ public RVA GetRVA(ResourceDirectory dir) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(ResourceData dataHeader, out FileOffset fileOffset, out RVA rva) { - if (dataHeader == null || !dataHeaderDict.TryGetValue(dataHeader, out uint offs)) { + if (dataHeader is null || !dataHeaderDict.TryGetValue(dataHeader, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -182,7 +182,7 @@ public RVA GetRVA(ResourceData dataHeader) { /// and have been updated. false /// if is not part of the Win32 resources. public bool GetFileOffsetAndRvaOf(string name, out FileOffset fileOffset, out RVA rva) { - if (name == null || !stringsDict.TryGetValue(name, out uint offs)) { + if (name is null || !stringsDict.TryGetValue(name, out uint offs)) { fileOffset = 0; rva = 0; return false; @@ -229,7 +229,7 @@ bool IReuseChunk.CanReuse(RVA origRva, uint origSize) { internal bool CheckValidOffset(FileOffset offset) { GetMaxAlignment(offset, out var error); - return error == null; + return error is null; } static uint GetMaxAlignment(FileOffset offset, out string error) { @@ -252,7 +252,7 @@ public void SetOffset(FileOffset offset, RVA rva) { bool initAll = this.offset == 0; this.offset = offset; this.rva = rva; - if (win32Resources == null) + if (win32Resources is null) return; if (!initAll) { @@ -277,7 +277,7 @@ public void SetOffset(FileOffset offset, RVA rva) { uint rsrcOffset = 0; var maxAlignment = GetMaxAlignment(offset, out var error); - if (error != null) + if (!(error is null)) throw new ModuleWriterException(error); foreach (var dir in dirList) { diff --git a/src/IO/ByteArrayDataReaderFactory.cs b/src/IO/ByteArrayDataReaderFactory.cs index a452b28c9..323d1ba4b 100644 --- a/src/IO/ByteArrayDataReaderFactory.cs +++ b/src/IO/ByteArrayDataReaderFactory.cs @@ -39,7 +39,7 @@ public sealed class ByteArrayDataReaderFactory : DataReaderFactory { /// The filename or null if the data is not from a file /// public static ByteArrayDataReaderFactory Create(byte[] data, string filename) { - if (data == null) + if (data is null) throw new ArgumentNullException(nameof(data)); return new ByteArrayDataReaderFactory(data, filename); } diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index f97968575..2565033ae 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -86,7 +86,7 @@ public uint Position { /// Start offset of data /// Length of data public DataReader(DataStream stream, uint offset, uint length) { - Debug.Assert(stream != null || (offset == 0 && length == 0)); + Debug.Assert(!(stream is null) || (offset == 0 && length == 0)); Debug.Assert(offset + length >= offset); this.stream = stream; startOffset = offset; @@ -398,7 +398,7 @@ public string ReadUtf16String(int chars) { /// Destination pointer /// Number of bytes to read public unsafe void ReadBytes(void* destination, int length) { - if (destination == null && length != 0) + if (destination is null && length != 0) ThrowArgumentNullException(nameof(destination)); if (length < 0) ThrowInvalidArgument(nameof(length)); @@ -421,7 +421,7 @@ public unsafe void ReadBytes(void* destination, int length) { /// Destination index /// Number of bytes to read public void ReadBytes(byte[] destination, int destinationIndex, int length) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); if (destinationIndex < 0) ThrowInvalidArgument(nameof(destinationIndex)); @@ -626,7 +626,7 @@ public uint Read7BitEncodedUInt32() { /// Encoding /// public string ReadSerializedString(Encoding encoding) { - if (encoding == null) + if (encoding is null) ThrowArgumentNullException(nameof(encoding)); int length = Read7BitEncodedInt32(); if (length < 0) @@ -697,7 +697,7 @@ public byte[] TryReadBytesUntil(byte value) { /// Encoding /// public string TryReadZeroTerminatedString(Encoding encoding) { - if (encoding == null) + if (encoding is null) ThrowArgumentNullException(nameof(encoding)); VerifyState(); var currentOffset = this.currentOffset; @@ -732,7 +732,7 @@ public string TryReadZeroTerminatedString(Encoding encoding) { public string ReadString(int byteCount, Encoding encoding) { if (byteCount < 0) ThrowInvalidArgument(nameof(byteCount)); - if (encoding == null) + if (encoding is null) ThrowArgumentNullException(nameof(encoding)); if (byteCount == 0) return string.Empty; @@ -760,7 +760,7 @@ public string ReadString(int byteCount, Encoding encoding) { /// Destination /// Number of bytes written public void CopyTo(DataWriter destination) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); if (Position >= Length) return; @@ -774,7 +774,7 @@ public void CopyTo(DataWriter destination) { /// Temp buffer during writing /// Number of bytes written public void CopyTo(DataWriter destination, byte[] dataBuffer) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); CopyTo(destination.InternalStream, dataBuffer); } @@ -785,7 +785,7 @@ public void CopyTo(DataWriter destination, byte[] dataBuffer) { /// Destination /// Number of bytes written public void CopyTo(BinaryWriter destination) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); if (Position >= Length) return; @@ -799,7 +799,7 @@ public void CopyTo(BinaryWriter destination) { /// Temp buffer during writing /// Number of bytes written public void CopyTo(BinaryWriter destination, byte[] dataBuffer) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); CopyTo(destination.BaseStream, dataBuffer); } @@ -810,7 +810,7 @@ public void CopyTo(BinaryWriter destination, byte[] dataBuffer) { /// Destination /// Number of bytes written public void CopyTo(Stream destination) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); if (Position >= Length) return; @@ -824,9 +824,9 @@ public void CopyTo(Stream destination) { /// Temp buffer during writing /// Number of bytes written public void CopyTo(Stream destination, byte[] dataBuffer) { - if (destination == null) + if (destination is null) ThrowArgumentNullException(nameof(destination)); - if (dataBuffer == null) + if (dataBuffer is null) ThrowArgumentNullException(nameof(dataBuffer)); if (Position >= Length) return; diff --git a/src/IO/DataReaderFactoryFactory.cs b/src/IO/DataReaderFactoryFactory.cs index aa72044b7..134dfb5db 100644 --- a/src/IO/DataReaderFactoryFactory.cs +++ b/src/IO/DataReaderFactoryFactory.cs @@ -16,7 +16,7 @@ static DataReaderFactoryFactory() { public static DataReaderFactory Create(string fileName, bool mapAsImage) { var creator = CreateDataReaderFactory(fileName, mapAsImage); - if (creator != null) + if (!(creator is null)) return creator; return ByteArrayDataReaderFactory.Create(File.ReadAllBytes(fileName), fileName); diff --git a/src/IO/DataReaderStream.cs b/src/IO/DataReaderStream.cs index c640190c5..9afd0aa14 100644 --- a/src/IO/DataReaderStream.cs +++ b/src/IO/DataReaderStream.cs @@ -42,7 +42,7 @@ public override long Seek(long offset, SeekOrigin origin) { } public override int Read(byte[] buffer, int offset, int count) { - if (buffer == null) + if (buffer is null) throw new ArgumentNullException(nameof(buffer)); if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset)); diff --git a/src/IO/DataStreamFactory.cs b/src/IO/DataStreamFactory.cs index af204c5f4..808d6e97f 100644 --- a/src/IO/DataStreamFactory.cs +++ b/src/IO/DataStreamFactory.cs @@ -33,7 +33,7 @@ static bool CalculateSupportsUnalignedAccesses() { /// Pointer to data /// public static DataStream Create(byte* data) { - if (data == null) + if (data is null) throw new ArgumentNullException(nameof(data)); if (supportsUnalignedAccesses) return new UnalignedNativeMemoryDataStream(data); @@ -46,7 +46,7 @@ public static DataStream Create(byte* data) { /// Data /// public static DataStream Create(byte[] data) { - if (data == null) + if (data is null) throw new ArgumentNullException(nameof(data)); if (supportsUnalignedAccesses) return new UnalignedByteArrayDataStream(data); diff --git a/src/IO/MemoryMappedDataReaderFactory.cs b/src/IO/MemoryMappedDataReaderFactory.cs index 0a4c117bb..a510f7c65 100644 --- a/src/IO/MemoryMappedDataReaderFactory.cs +++ b/src/IO/MemoryMappedDataReaderFactory.cs @@ -272,14 +272,14 @@ void Dispose(bool disposing) { /// /// true if memory mapped I/O is enabled /// - internal bool IsMemoryMappedIO => dataAry == null; + internal bool IsMemoryMappedIO => dataAry is null; /// /// Call this to disable memory mapped I/O. This must only be called if no other code is /// trying to access the memory since that could lead to an exception. /// internal void UnsafeDisableMemoryMappedIO() { - if (dataAry != null) + if (!(dataAry is null)) return; var newAry = new byte[length]; Marshal.Copy(data, newAry, 0, newAry.Length); @@ -293,7 +293,7 @@ internal void UnsafeDisableMemoryMappedIO() { } void FreeMemoryMappedIoData() { - if (dataAry == null) { + if (dataAry is null) { var origData = Interlocked.Exchange(ref data, IntPtr.Zero); if (origData != IntPtr.Zero) { length = 0; diff --git a/src/IO/NativeMemoryDataReaderFactory.cs b/src/IO/NativeMemoryDataReaderFactory.cs index 83aa796a9..c2746e025 100644 --- a/src/IO/NativeMemoryDataReaderFactory.cs +++ b/src/IO/NativeMemoryDataReaderFactory.cs @@ -37,7 +37,7 @@ public sealed unsafe class NativeMemoryDataReaderFactory : DataReaderFactory { /// The filename or null if the data is not from a file /// public static NativeMemoryDataReaderFactory Create(byte* data, uint length, string filename) { - if (data == null) + if (data is null) throw new ArgumentNullException(nameof(data)); return new NativeMemoryDataReaderFactory(data, length, filename); } diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index 6d8b8e0db..b09aa1a82 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -75,7 +75,7 @@ sealed class MemoryPEType : IPEType { /// public IList ImageDebugDirectories { get { - if (imageDebugDirectories == null) + if (imageDebugDirectories is null) imageDebugDirectories = ReadImageDebugDirectories(); return imageDebugDirectories; } @@ -97,7 +97,7 @@ public Win32Resources Win32Resources { } win32Resources.Value = value; - if (origValue != null) + if (!(origValue is null)) origValue.Dispose(); } } @@ -307,7 +307,7 @@ public PEImage(IntPtr baseAddr) /// public void Dispose() { IDisposable id; - if (win32Resources.IsValueInitialized && (id = win32Resources.Value) != null) + if (win32Resources.IsValueInitialized && !((id = win32Resources.Value) is null)) id.Dispose(); dataReaderFactory?.Dispose(); win32Resources.Value = null; @@ -341,7 +341,7 @@ void IInternalPEImage.UnsafeDisableMemoryMappedIO() { bool IInternalPEImage.IsMemoryMappedIO { get { var creator = dataReaderFactory as MemoryMappedDataReaderFactory; - return creator == null ? false : creator.IsMemoryMappedIO; + return creator is null ? false : creator.IsMemoryMappedIO; } } diff --git a/src/PE/PEInfo.cs b/src/PE/PEInfo.cs index 02e0d35f9..afbd5c995 100644 --- a/src/PE/PEInfo.cs +++ b/src/PE/PEInfo.cs @@ -91,7 +91,7 @@ public ImageSectionHeader ToImageSectionHeader(RVA rva) { /// The RVA public RVA ToRVA(FileOffset offset) { var section = ToImageSectionHeader(offset); - if (section != null) + if (!(section is null)) return (uint)(offset - section.PointerToRawData) + section.VirtualAddress; return (RVA)offset; } @@ -103,7 +103,7 @@ public RVA ToRVA(FileOffset offset) { /// The file offset public FileOffset ToFileOffset(RVA rva) { var section = ToImageSectionHeader(rva); - if (section != null) + if (!(section is null)) return (FileOffset)(rva - section.VirtualAddress + section.PointerToRawData); return (FileOffset)rva; } diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index bc22a78b6..c0d5f13ac 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -26,7 +26,7 @@ public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) = public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) { machine = 0; var processArchitectureMethod = System_Runtime_InteropServices_RuntimeInformation?.GetMethod("get_ProcessArchitecture", Array2.Empty()); - if ((object)processArchitectureMethod == null) + if (processArchitectureMethod is null) return false; var result = processArchitectureMethod.Invoke(null, Array2.Empty()); diff --git a/src/Utils/LazyList.cs b/src/Utils/LazyList.cs index 7ac86d413..a915c53ea 100644 --- a/src/Utils/LazyList.cs +++ b/src/Utils/LazyList.cs @@ -157,7 +157,7 @@ public TValue this[int index] { internal TValue Get_NoLock(int index) => list[index].GetValue_NoLock(index); void Set_NoLock(int index, TValue value) { - if (listener != null) { + if (!(listener is null)) { listener.OnRemove(index, list[index].GetValue_NoLock(index)); listener.OnAdd(index, value); } @@ -217,10 +217,10 @@ public void Insert(int index, TValue item) { } void Insert_NoLock(int index, TValue item) { - if (listener != null) + if (!(listener is null)) listener.OnAdd(index, item); list.Insert(index, new Element(item)); - if (listener != null) + if (!(listener is null)) listener.OnResize(index); id++; } @@ -237,10 +237,10 @@ public void RemoveAt(int index) { } void RemoveAt_NoLock(int index) { - if (listener != null) + if (!(listener is null)) listener.OnRemove(index, list[index].GetValue_NoLock(index)); list.RemoveAt(index); - if (listener != null) + if (!(listener is null)) listener.OnResize(index); id++; } @@ -258,10 +258,10 @@ public void Add(TValue item) { void Add_NoLock(TValue item) { int index = list.Count; - if (listener != null) + if (!(listener is null)) listener.OnAdd(index, item); list.Add(new Element(item)); - if (listener != null) + if (!(listener is null)) listener.OnResize(index); id++; } @@ -278,10 +278,10 @@ public void Clear() { } void Clear_NoLock() { - if (listener != null) + if (!(listener is null)) listener.OnClear(); list.Clear(); - if (listener != null) + if (!(listener is null)) listener.OnResize(0); id++; } @@ -444,11 +444,11 @@ sealed class LazyElement : Element { LazyList lazyList; /// - public override bool IsInitialized_NoLock => lazyList == null; + public override bool IsInitialized_NoLock => lazyList is null; /// public override TValue GetValue_NoLock(int index) { - if (lazyList != null) { + if (!(lazyList is null)) { value = lazyList.ReadOriginalValue_NoLock(index, origIndex); lazyList = null; } @@ -473,11 +473,11 @@ public LazyElement(int origIndex, LazyList lazyList) { /// public override string ToString() { - if (lazyList != null) { + if (!(lazyList is null)) { value = lazyList.ReadOriginalValue_NoLock(this); lazyList = null; } - return value == null ? string.Empty : value.ToString(); + return value is null ? string.Empty : value.ToString(); } } diff --git a/src/Utils/SimpleLazyList.cs b/src/Utils/SimpleLazyList.cs index 55cece186..a71a59d0e 100644 --- a/src/Utils/SimpleLazyList.cs +++ b/src/Utils/SimpleLazyList.cs @@ -33,7 +33,7 @@ public T this[uint index] { get { if (index >= length) return null; - if (elements[index] == null) + if (elements[index] is null) Interlocked.CompareExchange(ref elements[index], readElementByRID(index + 1), null); return elements[index]; } @@ -81,7 +81,7 @@ sealed class SimpleLazyList2 where T : class, IContainsGenericParameter { get { if (index >= length) return null; - if (elements[index] == null) { + if (elements[index] is null) { var elem = readElementByRID(index + 1, gpContext); // Don't cache it if it contains GPs since each GP could hold a reference // to the type/method context. These GPs can't be shared. diff --git a/src/W32Resources/ResourceName.cs b/src/W32Resources/ResourceName.cs index cecb08a4d..4ca8c4533 100644 --- a/src/W32Resources/ResourceName.cs +++ b/src/W32Resources/ResourceName.cs @@ -13,12 +13,12 @@ namespace dnlib.W32Resources { /// /// true if is valid /// - public bool HasId => name == null; + public bool HasId => name is null; /// /// true if is valid /// - public bool HasName => name != null; + public bool HasName => !(name is null); /// /// The ID. It's only valid if is true diff --git a/src/W32Resources/Win32Resources.cs b/src/W32Resources/Win32Resources.cs index 9cb1fc503..89fd7cf4a 100644 --- a/src/W32Resources/Win32Resources.cs +++ b/src/W32Resources/Win32Resources.cs @@ -24,7 +24,7 @@ public abstract class Win32Resources : IDisposable { /// The or null if none found public ResourceDirectory Find(ResourceName type) { var dir = Root; - if (dir == null) + if (dir is null) return null; return dir.FindDirectory(type); } @@ -37,7 +37,7 @@ public ResourceDirectory Find(ResourceName type) { /// The or null if none found public ResourceDirectory Find(ResourceName type, ResourceName name) { var dir = Find(type); - if (dir == null) + if (dir is null) return null; return dir.FindDirectory(name); } @@ -51,7 +51,7 @@ public ResourceDirectory Find(ResourceName type, ResourceName name) { /// The or null if none found public ResourceData Find(ResourceName type, ResourceName name, ResourceName langId) { var dir = Find(type, name); - if (dir == null) + if (dir is null) return null; return dir.FindData(langId); } @@ -189,7 +189,7 @@ public Win32ResourcesPE(IPEImage peImage, DataReaderFactory rsrcReader_factory, dataReader_factory = peImage.DataReaderFactory; dataReader_offset = 0; dataReader_length = dataReader_factory.Length; - if (rsrcReader_factory != null) { + if (!(rsrcReader_factory is null)) { this.rsrcReader_factory = rsrcReader_factory; this.rsrcReader_offset = rsrcReader_offset; this.rsrcReader_length = rsrcReader_length; @@ -215,7 +215,7 @@ public Win32ResourcesPE(IPEImage peImage, DataReaderFactory rsrcReader_factory, void Initialize() { root.ReadOriginalValue = () => { var rsrcReader_factory = this.rsrcReader_factory; - if (rsrcReader_factory == null) + if (rsrcReader_factory is null) return null; // It's disposed var reader = rsrcReader_factory.CreateReader(rsrcReader_offset, rsrcReader_length); return new ResourceDirectoryPE(0, new ResourceName("root"), this, ref reader); From 523d2ebbe43f7a999778483f4d34fadd52efbf71 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 16 Jul 2019 19:48:21 +0200 Subject: [PATCH 315/511] Remove unused usings --- Examples/Example5.cs | 2 -- Examples/Example6.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/Examples/Example5.cs b/Examples/Example5.cs index 30e8c79f4..8116fe53f 100644 --- a/Examples/Example5.cs +++ b/Examples/Example5.cs @@ -1,8 +1,6 @@ using System; using System.IO; using dnlib.DotNet; -using dnlib.PE; -using dnlib.IO; namespace dnlib.Examples { /// diff --git a/Examples/Example6.cs b/Examples/Example6.cs index f00adb5a3..83a3ce48e 100644 --- a/Examples/Example6.cs +++ b/Examples/Example6.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using dnlib.DotNet; using dnlib.DotNet.MD; using dnlib.DotNet.Writer; From e2e47613a0545ce24fc026fd6fa6b1326a0c4c0a Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 16 Jul 2019 19:48:35 +0200 Subject: [PATCH 316/511] Fix custom heaps check --- src/DotNet/Writer/Metadata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 76fb0cb37..3e3d7b9d4 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -256,7 +256,7 @@ public void PreserveHeapOrder(ModuleDef module, bool addCustomHeaps) { throw new ArgumentNullException(nameof(module)); if (module is ModuleDefMD mod) { if (addCustomHeaps) { - var otherStreams = mod.Metadata.AllStreams.Where(a => a.GetType() == typeof(DotNetStream)).Select(a => new DataReaderHeap(a)); + var otherStreams = mod.Metadata.AllStreams.Where(a => a.GetType() == typeof(CustomDotNetStream)).Select(a => new DataReaderHeap(a)); CustomHeaps.AddRange(otherStreams.OfType()); } var streamToOrder = new Dictionary(mod.Metadata.AllStreams.Count); From 9cff9121784fee116593d5d554dd317bbb431484 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 19 Jul 2019 18:41:56 +0200 Subject: [PATCH 317/511] Get nested System.Type's namespace, closes #286 --- src/DotNet/Importer.cs | 3 ++- src/DotNet/ReflectionExtensions.cs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 0e031a0cd..2fc54e578 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -343,7 +343,8 @@ static bool Equals(IAssembly a, IAssembly b) { TypeRef CreateTypeRef2(Type type) { if (!type.IsNested) return module.UpdateRowId(new TypeRefUser(module, type.Namespace ?? string.Empty, type.Name ?? string.Empty, CreateScopeReference(type))); - return module.UpdateRowId(new TypeRefUser(module, string.Empty, type.Name ?? string.Empty, CreateTypeRef2(type.DeclaringType))); + type.GetTypeNamespaceAndName_TypeDefOrRef(out var @namespace, out var name); + return module.UpdateRowId(new TypeRefUser(module, @namespace ?? string.Empty, name ?? string.Empty, CreateTypeRef2(type.DeclaringType))); } IResolutionScope CreateScopeReference(Type type) { diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index c6cde5e8f..c1a148f5f 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Diagnostics; using System.Reflection; namespace dnlib.DotNet { @@ -8,6 +9,21 @@ namespace dnlib.DotNet { /// Extension methods for reflection types, methods, fields /// static class ReflectionExtensions { + public static void GetTypeNamespaceAndName_TypeDefOrRef(this Type type, out string @namespace, out string name) { + Debug.Assert(type.IsTypeDef()); + name = type.Name ?? string.Empty; + if (!type.IsNested) + @namespace = type.Namespace ?? string.Empty; + else { + var declTypeFullName = type.DeclaringType.FullName; + var typeFullName = type.FullName; + if (declTypeFullName.Length + 1 + name.Length == typeFullName.Length) + @namespace = string.Empty; + else + @namespace = typeFullName.Substring(declTypeFullName.Length + 1, typeFullName.Length - declTypeFullName.Length - 1 - name.Length - 1); + } + } + /// /// Checks whether it's a /// From f742c115ea99aa3b4799a262ee44b97e88259dbb Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 22 Jul 2019 23:05:52 +0200 Subject: [PATCH 318/511] Use latest sourcelink version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a339424e9..44c88c17c 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -53,7 +53,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + From 89a093c16f6f0a8d677ccce823dd808cee58f716 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sun, 28 Jul 2019 07:56:09 +0200 Subject: [PATCH 319/511] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0d4c99f21..85c6325b9 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ Compiling --------- -v3.0 requires VS2017 (C#7.3) or later to build it. .NET Core SDK 2.1 or later is also required. See below for breaking changes going from 2.1 to 3.0 +v3.0 requires VS2019 or later to build it. .NET Core SDK 2.1 or later is also required. See below for breaking changes going from 2.1 to 3.0 An [older v2.1 branch](https://github.com/0xd4d/dnlib/tree/v2.1_VS2010) can be used to build with older VS versions. This branch won't get any new updates. v3.0 breaking changes --------------------- -- VS2017, C# 7.2 is required to compile it +- VS2019 is required to compile it - It targets .NET Framework 3.5 or later and netstandard 2.0 or later (.NET Framework 2.0 and 3.0 aren't supported) - `*MetaData*` -> `*Metadata*` - `IMetaData` interface is an abstract class `Metadata` From f67f9696bfafc119f89eae19d31f5ec48d140810 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 28 Jul 2019 08:08:45 +0200 Subject: [PATCH 320/511] Update sln file to require VS2019 --- dnlib.sln | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnlib.sln b/dnlib.sln index 50fd6003d..e3a916c93 100644 --- a/dnlib.sln +++ b/dnlib.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 -MinimumVisualStudioVersion = 15.0.26206.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28729.10 +MinimumVisualStudioVersion = 16.0.28729.10 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib", "src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples", "Examples\Examples.csproj", "{F27E72B5-C4BD-40BF-AD19-4C8A99B55872}" From e90652dc1d32c051b2fbf2997f9c15382e5bbfd0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 31 Jul 2019 23:27:05 +0200 Subject: [PATCH 321/511] Add options to disable writing bodies, field data, win32/.NET resources --- src/DotNet/Writer/Metadata.cs | 64 +++++++++++++++++++++++++ src/DotNet/Writer/ModuleWriter.cs | 6 ++- src/DotNet/Writer/ModuleWriterBase.cs | 9 ++++ src/DotNet/Writer/NativeModuleWriter.cs | 2 + 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 3e3d7b9d4..370b19b6c 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -162,6 +162,21 @@ public enum MetadataFlags : uint { /// according to the ECMA spec, see https://github.com/dotnet/roslyn/issues/3905 /// RoslynSortInterfaceImpl = 0x100000, + + /// + /// Don't write method bodies + /// + NoMethodBodies = 0x200000, + + /// + /// Don't write .NET resources + /// + NoDotNetResources = 0x400000, + + /// + /// Don't write field data + /// + NoFieldData = 0x800000, } /// @@ -831,6 +846,45 @@ public bool RoslynSortInterfaceImpl { } } + /// + /// Gets/sets the bit + /// + public bool NoMethodBodies { + get => (options.Flags & MetadataFlags.NoMethodBodies) != 0; + set { + if (value) + options.Flags |= MetadataFlags.NoMethodBodies; + else + options.Flags &= ~MetadataFlags.NoMethodBodies; + } + } + + /// + /// Gets/sets the bit + /// + public bool NoDotNetResources { + get => (options.Flags & MetadataFlags.NoDotNetResources) != 0; + set { + if (value) + options.Flags |= MetadataFlags.NoDotNetResources; + else + options.Flags &= ~MetadataFlags.NoDotNetResources; + } + } + + /// + /// Gets/sets the bit + /// + public bool NoFieldData { + get => (options.Flags & MetadataFlags.NoFieldData) != 0; + set { + if (value) + options.Flags |= MetadataFlags.NoFieldData; + else + options.Flags &= ~MetadataFlags.NoFieldData; + } + } + /// /// If true, use the original Field RVAs. If it has no RVA, assume it's a new /// field value and create a new Field RVA. @@ -1866,6 +1920,8 @@ struct MethodScopeDebugInfo { /// void WriteMethodBodies() { Debug.Assert(!isStandaloneDebugMetadata); + if (NoMethodBodies) + return; int numMethods = NumberOfMethods; int methodNum = 0; int notifyNum = 0; @@ -2585,6 +2641,8 @@ protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { /// The field protected void AddFieldRVA(FieldDef field) { Debug.Assert(!isStandaloneDebugMetadata); + if (NoFieldData) + return; if (field.RVA != 0 && KeepFieldRVA) { uint rid = GetRid(field); var row = new RawFieldRVARow((uint)field.RVA, rid); @@ -2846,6 +2904,8 @@ protected void AddClassLayout(TypeDef type) { } void AddResources(IList resources) { + if (NoDotNetResources) + return; if (resources is null) return; int count = resources.Count; @@ -2854,6 +2914,7 @@ void AddResources(IList resources) { } void AddResource(Resource resource) { + Debug.Assert(!NoDotNetResources); if (resource is EmbeddedResource er) { AddEmbeddedResource(er); return; @@ -2877,6 +2938,7 @@ void AddResource(Resource resource) { uint AddEmbeddedResource(EmbeddedResource er) { Debug.Assert(!isStandaloneDebugMetadata); + Debug.Assert(!NoDotNetResources); if (er is null) { Error("EmbeddedResource is null"); return 0; @@ -2896,6 +2958,7 @@ uint AddEmbeddedResource(EmbeddedResource er) { } uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { + Debug.Assert(!NoDotNetResources); if (alr is null) { Error("AssemblyLinkedResource is null"); return 0; @@ -2914,6 +2977,7 @@ uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { } uint AddLinkedResource(LinkedResource lr) { + Debug.Assert(!NoDotNetResources); if (lr is null) { Error("LinkedResource is null"); return 0; diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 6373680e2..14adb0bc5 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -161,7 +161,11 @@ void Initialize() { } /// - protected override Win32Resources GetWin32Resources() => Options.Win32Resources ?? module.Win32Resources; + protected override Win32Resources GetWin32Resources() { + if (Options.NoWin32Resources) + return null; + return Options.Win32Resources ?? module.Win32Resources; + } void CreateSections() { sections = new List(); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 1c05d9266..b360d7b03 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -149,6 +149,7 @@ public class ModuleWriterOptionsBase { MetadataOptions metadataOptions; ILogger logger; ILogger metadataLogger; + bool noWin32Resources; Win32Resources win32Resources; StrongNameKey strongNameKey; StrongNamePublicKey strongNamePublicKey; @@ -210,6 +211,14 @@ public MetadataOptions MetadataOptions { set => metadataOptions = value; } + /// + /// If true, Win32 resources aren't written to the output + /// + public bool NoWin32Resources { + get => noWin32Resources; + set => noWin32Resources = value; + } + /// /// Gets/sets the Win32 resources. If this is null, use the module's /// Win32 resources if any. diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 20470ccc6..1c391317f 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -255,6 +255,8 @@ void AddChunksToSections() { protected override Win32Resources GetWin32Resources() { if (Options.KeepWin32Resources) return null; + if (Options.NoWin32Resources) + return null; return Options.Win32Resources ?? module.Win32Resources; } From efa88b63173c682591f7e688dc39cfcf126d85df Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 31 Jul 2019 23:27:13 +0200 Subject: [PATCH 322/511] Mono reader improvements --- src/DotNet/MD/CompressedMetadata.cs | 10 +- src/DotNet/MD/ENCMetadata.cs | 177 +++++++++++++++++++--------- src/DotNet/MD/MetadataFactory.cs | 105 +++++++++-------- src/DotNet/MD/MetadataHeader.cs | 27 +++-- src/DotNet/MD/StreamHeader.cs | 10 +- src/DotNet/MD/TablesStream.cs | 28 ++++- src/DotNet/ModuleCreationOptions.cs | 39 ++++++ src/DotNet/ModuleDefMD.cs | 20 ++-- 8 files changed, 284 insertions(+), 132 deletions(-) diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index f0b87eda1..3db74a9ed 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -10,17 +10,21 @@ namespace dnlib.DotNet.MD { /// Used when a #~ stream is present in the metadata /// sealed class CompressedMetadata : MetadataBase { + readonly CLRRuntimeReaderKind runtime; + /// public override bool IsCompressed => true; /// - public CompressedMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader) + public CompressedMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader, CLRRuntimeReaderKind runtime) : base(peImage, cor20Header, mdHeader) { + this.runtime = runtime; } /// - internal CompressedMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb) + internal CompressedMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb, CLRRuntimeReaderKind runtime) : base(mdHeader, isStandalonePortablePdb) { + this.runtime = runtime; } /// @@ -65,7 +69,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui case "#~": if (tablesStream is null) { - tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh); + tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime); newAllStreams.Add(tablesStream); continue; } diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 736faee96..61c91c461 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using dnlib.IO; using dnlib.PE; using dnlib.Threading; @@ -14,6 +15,7 @@ sealed class ENCMetadata : MetadataBase { static readonly UTF8String DeletedName = "_Deleted"; bool hasMethodPtr, hasFieldPtr, hasParamPtr, hasEventPtr, hasPropertyPtr; bool hasDeletedRows; + readonly CLRRuntimeReaderKind runtime; readonly Dictionary sortedTables = new Dictionary(); #if THREAD_SAFE readonly Lock theLock = Lock.Create(); @@ -23,75 +25,140 @@ sealed class ENCMetadata : MetadataBase { public override bool IsCompressed => false; /// - public ENCMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader) + public ENCMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader, CLRRuntimeReaderKind runtime) : base(peImage, cor20Header, mdHeader) { + this.runtime = runtime; } /// - internal ENCMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb) + internal ENCMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb, CLRRuntimeReaderKind runtime) : base(mdHeader, isStandalonePortablePdb) { + this.runtime = runtime; } /// protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset) { DotNetStream dns = null; try { - foreach (var sh in mdHeader.StreamHeaders) { - switch (sh.Name.ToUpperInvariant()) { - case "#STRINGS": - if (stringsStream is null) { - stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(stringsStream); - continue; + if (runtime == CLRRuntimeReaderKind.Mono) { + var newAllStreams = new List(allStreams); + for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--) { + var sh = mdHeader.StreamHeaders[i]; + switch (sh.Name) { + case "#Strings": + if (stringsStream is null) { + stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh); + newAllStreams.Add(stringsStream); + continue; + } + break; + + case "#US": + if (usStream is null) { + usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh); + newAllStreams.Add(usStream); + continue; + } + break; + + case "#Blob": + if (blobStream is null) { + blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh); + newAllStreams.Add(blobStream); + continue; + } + break; + + case "#GUID": + if (guidStream is null) { + guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh); + newAllStreams.Add(guidStream); + continue; + } + break; + + case "#-": + if (tablesStream is null) { + tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime); + newAllStreams.Add(tablesStream); + continue; + } + break; + + case "#Pdb": + if (isStandalonePortablePdb && pdbStream is null) { + pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(pdbStream); + continue; + } + break; } - break; - - case "#US": - if (usStream is null) { - usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(usStream); - continue; - } - break; - - case "#BLOB": - if (blobStream is null) { - blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(blobStream); - continue; - } - break; - - case "#GUID": - if (guidStream is null) { - guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(guidStream); - continue; - } - break; - - case "#~": // Only if #Schema is used - case "#-": - if (tablesStream is null) { - tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(tablesStream); - continue; - } - break; - - case "#PDB": - // Case sensitive comparison since it's a stream that's not read by the CLR, - // only by other libraries eg. System.Reflection.Metadata. - if (isStandalonePortablePdb && pdbStream is null && sh.Name == "#Pdb") { - pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(pdbStream); - continue; + dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); + newAllStreams.Add(dns); + dns = null; + } + newAllStreams.Reverse(); + allStreams = newAllStreams; + } + else { + Debug.Assert(runtime == CLRRuntimeReaderKind.CLR); + foreach (var sh in mdHeader.StreamHeaders) { + switch (sh.Name.ToUpperInvariant()) { + case "#STRINGS": + if (stringsStream is null) { + stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(stringsStream); + continue; + } + break; + + case "#US": + if (usStream is null) { + usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(usStream); + continue; + } + break; + + case "#BLOB": + if (blobStream is null) { + blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(blobStream); + continue; + } + break; + + case "#GUID": + if (guidStream is null) { + guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(guidStream); + continue; + } + break; + + case "#~": // Only if #Schema is used + case "#-": + if (tablesStream is null) { + tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime); + allStreams.Add(tablesStream); + continue; + } + break; + + case "#PDB": + // Case sensitive comparison since it's a stream that's not read by the CLR, + // only by other libraries eg. System.Reflection.Metadata. + if (isStandalonePortablePdb && pdbStream is null && sh.Name == "#Pdb") { + pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(pdbStream); + continue; + } + break; } - break; + dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); + allStreams.Add(dns); + dns = null; } - dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(dns); - dns = null; } } finally { diff --git a/src/DotNet/MD/MetadataFactory.cs b/src/DotNet/MD/MetadataFactory.cs index f6fcf1961..192eafa0c 100644 --- a/src/DotNet/MD/MetadataFactory.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -16,15 +16,10 @@ enum MetadataType { ENC, // #- (edit and continue) } - /// - /// Create a instance - /// - /// The file to load - /// A new instance - internal static MetadataBase Load(string fileName) { + internal static MetadataBase Load(string fileName, CLRRuntimeReaderKind runtime) { IPEImage peImage = null; try { - return Load(peImage = new PEImage(fileName)); + return Load(peImage = new PEImage(fileName), runtime); } catch { if (!(peImage is null)) @@ -33,15 +28,10 @@ internal static MetadataBase Load(string fileName) { } } - /// - /// Create a instance - /// - /// The .NET file data - /// A new instance - internal static MetadataBase Load(byte[] data) { + internal static MetadataBase Load(byte[] data, CLRRuntimeReaderKind runtime) { IPEImage peImage = null; try { - return Load(peImage = new PEImage(data)); + return Load(peImage = new PEImage(data), runtime); } catch { if (!(peImage is null)) @@ -50,17 +40,12 @@ internal static MetadataBase Load(byte[] data) { } } - /// - /// Create a instance - /// - /// Address of a .NET file in memory - /// A new instance - internal static MetadataBase Load(IntPtr addr) { + internal static MetadataBase Load(IntPtr addr, CLRRuntimeReaderKind runtime) { IPEImage peImage = null; // We don't know what layout it is. Memory is more common so try that first. try { - return Load(peImage = new PEImage(addr, ImageLayout.Memory, true)); + return Load(peImage = new PEImage(addr, ImageLayout.Memory, true), runtime); } catch { if (!(peImage is null)) @@ -69,7 +54,7 @@ internal static MetadataBase Load(IntPtr addr) { } try { - return Load(peImage = new PEImage(addr, ImageLayout.File, true)); + return Load(peImage = new PEImage(addr, ImageLayout.File, true), runtime); } catch { if (!(peImage is null)) @@ -78,16 +63,10 @@ internal static MetadataBase Load(IntPtr addr) { } } - /// - /// Create a instance - /// - /// Address of a .NET file in memory - /// Image layout of the file in memory - /// A new instance - internal static MetadataBase Load(IntPtr addr, ImageLayout imageLayout) { + internal static MetadataBase Load(IntPtr addr, ImageLayout imageLayout, CLRRuntimeReaderKind runtime) { IPEImage peImage = null; try { - return Load(peImage = new PEImage(addr, imageLayout, true)); + return Load(peImage = new PEImage(addr, imageLayout, true), runtime); } catch { if (!(peImage is null)) @@ -96,35 +75,48 @@ internal static MetadataBase Load(IntPtr addr, ImageLayout imageLayout) { } } + internal static MetadataBase Load(IPEImage peImage, CLRRuntimeReaderKind runtime) => Create(peImage, runtime, true); + /// - /// Create a instance + /// Create a instance /// /// The PE image - /// A new instance - internal static MetadataBase Load(IPEImage peImage) => Create(peImage, true); + /// A new instance + public static Metadata CreateMetadata(IPEImage peImage) => CreateMetadata(peImage, CLRRuntimeReaderKind.CLR); + + /// + /// Create a instance + /// + /// The PE image + /// Runtime reader kind + /// A new instance + public static Metadata CreateMetadata(IPEImage peImage, CLRRuntimeReaderKind runtime) => Create(peImage, runtime, true); /// /// Create a instance /// /// The PE image + /// true if we should verify that it's a .NET PE file /// A new instance - public static Metadata CreateMetadata(IPEImage peImage) => Create(peImage, true); + public static Metadata CreateMetadata(IPEImage peImage, bool verify) => CreateMetadata(peImage, CLRRuntimeReaderKind.CLR, verify); /// /// Create a instance /// /// The PE image + /// Runtime reader kind /// true if we should verify that it's a .NET PE file /// A new instance - public static Metadata CreateMetadata(IPEImage peImage, bool verify) => Create(peImage, verify); + public static Metadata CreateMetadata(IPEImage peImage, CLRRuntimeReaderKind runtime, bool verify) => Create(peImage, runtime, verify); /// /// Create a instance /// /// The PE image + /// Runtime reader kind /// true if we should verify that it's a .NET PE file /// A new instance - static MetadataBase Create(IPEImage peImage, bool verify) { + static MetadataBase Create(IPEImage peImage, CLRRuntimeReaderKind runtime, bool verify) { MetadataBase md = null; try { var dotNetDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14]; @@ -132,13 +124,13 @@ static MetadataBase Create(IPEImage peImage, bool verify) { if (dotNetDir.VirtualAddress == 0) throw new BadImageFormatException(".NET data directory RVA is 0"); var cor20HeaderReader = peImage.CreateReader(dotNetDir.VirtualAddress, 0x48); - var cor20Header = new ImageCor20Header(ref cor20HeaderReader, verify); + var cor20Header = new ImageCor20Header(ref cor20HeaderReader, verify && runtime == CLRRuntimeReaderKind.CLR); if (cor20Header.Metadata.VirtualAddress == 0) throw new BadImageFormatException(".NET metadata RVA is 0"); var mdRva = cor20Header.Metadata.VirtualAddress; // Don't use the size field, Mono ignores it. Create a reader that can read to EOF. var mdHeaderReader = peImage.CreateReader(mdRva); - var mdHeader = new MetadataHeader(ref mdHeaderReader, verify); + var mdHeader = new MetadataHeader(ref mdHeaderReader, runtime, verify); if (verify) { foreach (var sh in mdHeader.StreamHeaders) { if ((ulong)sh.Offset + sh.StreamSize > mdHeaderReader.EndOffset) @@ -146,13 +138,13 @@ static MetadataBase Create(IPEImage peImage, bool verify) { } } - switch (GetMetadataType(mdHeader.StreamHeaders)) { + switch (GetMetadataType(mdHeader.StreamHeaders, runtime)) { case MetadataType.Compressed: - md = new CompressedMetadata(peImage, cor20Header, mdHeader); + md = new CompressedMetadata(peImage, cor20Header, mdHeader, runtime); break; case MetadataType.ENC: - md = new ENCMetadata(peImage, cor20Header, mdHeader); + md = new ENCMetadata(peImage, cor20Header, mdHeader, runtime); break; default: @@ -176,10 +168,11 @@ static MetadataBase Create(IPEImage peImage, bool verify) { /// true if we should verify that it's a .NET PE file /// A new instance internal static MetadataBase CreateStandalonePortablePDB(DataReaderFactory mdReaderFactory, bool verify) { + const CLRRuntimeReaderKind runtime = CLRRuntimeReaderKind.CLR; MetadataBase md = null; try { var reader = mdReaderFactory.CreateReader(); - var mdHeader = new MetadataHeader(ref reader, verify); + var mdHeader = new MetadataHeader(ref reader, runtime, verify); if (verify) { foreach (var sh in mdHeader.StreamHeaders) { if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > reader.Length) @@ -187,13 +180,13 @@ internal static MetadataBase CreateStandalonePortablePDB(DataReaderFactory mdRea } } - switch (GetMetadataType(mdHeader.StreamHeaders)) { + switch (GetMetadataType(mdHeader.StreamHeaders, runtime)) { case MetadataType.Compressed: - md = new CompressedMetadata(mdHeader, true); + md = new CompressedMetadata(mdHeader, true, runtime); break; case MetadataType.ENC: - md = new ENCMetadata(mdHeader, true); + md = new ENCMetadata(mdHeader, true, runtime); break; default: @@ -209,18 +202,30 @@ internal static MetadataBase CreateStandalonePortablePDB(DataReaderFactory mdRea } } - static MetadataType GetMetadataType(IList streamHeaders) { + static MetadataType GetMetadataType(IList streamHeaders, CLRRuntimeReaderKind runtime) { MetadataType? mdType = null; - foreach (var sh in streamHeaders) { - if (mdType is null) { + if (runtime == CLRRuntimeReaderKind.CLR) { + foreach (var sh in streamHeaders) { + if (mdType is null) { + if (sh.Name == "#~") + mdType = MetadataType.Compressed; + else if (sh.Name == "#-") + mdType = MetadataType.ENC; + } + if (sh.Name == "#Schema") + mdType = MetadataType.ENC; + } + } + else if (runtime == CLRRuntimeReaderKind.Mono) { + foreach (var sh in streamHeaders) { if (sh.Name == "#~") mdType = MetadataType.Compressed; else if (sh.Name == "#-") mdType = MetadataType.ENC; } - if (sh.Name == "#Schema") - mdType = MetadataType.ENC; } + else + throw new ArgumentOutOfRangeException(nameof(runtime)); if (mdType is null) return MetadataType.Unknown; return mdType.Value; diff --git a/src/DotNet/MD/MetadataHeader.cs b/src/DotNet/MD/MetadataHeader.cs index e3d7f1831..69604afd1 100644 --- a/src/DotNet/MD/MetadataHeader.cs +++ b/src/DotNet/MD/MetadataHeader.cs @@ -84,7 +84,18 @@ public sealed class MetadataHeader : FileSection { /// PE file reader pointing to the start of this section /// Verify section /// Thrown if verification fails - public MetadataHeader(ref DataReader reader, bool verify) { + public MetadataHeader(ref DataReader reader, bool verify) + : this(ref reader, CLRRuntimeReaderKind.CLR, verify) { + } + + /// + /// Constructor + /// + /// PE file reader pointing to the start of this section + /// Runtime reader kind + /// Verify section + /// Thrown if verification fails + public MetadataHeader(ref DataReader reader, CLRRuntimeReaderKind runtime, bool verify) { SetStartOffset(ref reader); signature = reader.ReadUInt32(); if (verify && signature != 0x424A5342) @@ -93,7 +104,7 @@ public MetadataHeader(ref DataReader reader, bool verify) { minorVersion = reader.ReadUInt16(); reserved1 = reader.ReadUInt32(); stringLength = reader.ReadUInt32(); - versionString = ReadString(ref reader, stringLength); + versionString = ReadString(ref reader, stringLength, runtime); offset2ndPart = (FileOffset)reader.CurrentOffset; flags = (StorageFlags)reader.ReadByte(); reserved2 = reader.ReadByte(); @@ -101,7 +112,7 @@ public MetadataHeader(ref DataReader reader, bool verify) { streamHeaders = new StreamHeader[streams]; for (int i = 0; i < streamHeaders.Count; i++) { // Mono doesn't verify all of these so we can't either - var sh = new StreamHeader(ref reader, throwOnError: false, verify, out bool failedVerification); + var sh = new StreamHeader(ref reader, throwOnError: false, verify, runtime, out bool failedVerification); if (failedVerification || (ulong)sh.Offset + sh.StreamSize > reader.EndOffset) sh = new StreamHeader(0, 0, ""); streamHeaders[i] = sh; @@ -109,9 +120,11 @@ public MetadataHeader(ref DataReader reader, bool verify) { SetEndoffset(ref reader); } - static string ReadString(ref DataReader reader, uint maxLength) { - ulong endPos = (ulong)reader.Position + maxLength; - if (endPos > reader.Length) + static string ReadString(ref DataReader reader, uint maxLength, CLRRuntimeReaderKind runtime) { + ulong endOffset = (ulong)reader.CurrentOffset + maxLength; + if (runtime == CLRRuntimeReaderKind.Mono) + endOffset = (endOffset + 3) / 4 * 4; + if (endOffset > reader.EndOffset) throw new BadImageFormatException("Invalid MD version string"); var utf8Bytes = new byte[maxLength]; uint i; @@ -121,7 +134,7 @@ static string ReadString(ref DataReader reader, uint maxLength) { break; utf8Bytes[i] = b; } - reader.Position = (uint)endPos; + reader.CurrentOffset = (uint)endOffset; return Encoding.UTF8.GetString(utf8Bytes, 0, (int)i); } } diff --git a/src/DotNet/MD/StreamHeader.cs b/src/DotNet/MD/StreamHeader.cs index 0f1252976..dac48bfdf 100644 --- a/src/DotNet/MD/StreamHeader.cs +++ b/src/DotNet/MD/StreamHeader.cs @@ -37,16 +37,22 @@ public sealed class StreamHeader : FileSection { /// Verify section /// Thrown if verification fails public StreamHeader(ref DataReader reader, bool verify) - : this(ref reader, verify, verify, out _) { + : this(ref reader, verify, verify, CLRRuntimeReaderKind.CLR, out _) { } - internal StreamHeader(ref DataReader reader, bool throwOnError, bool verify, out bool failedVerification) { + internal StreamHeader(ref DataReader reader, bool throwOnError, bool verify, CLRRuntimeReaderKind runtime, out bool failedVerification) { failedVerification = false; SetStartOffset(ref reader); offset = reader.ReadUInt32(); streamSize = reader.ReadUInt32(); name = ReadString(ref reader, 32, verify, ref failedVerification); SetEndoffset(ref reader); + if (runtime == CLRRuntimeReaderKind.Mono) { + if (offset > reader.Length) + offset = reader.Length; + // Mono ignores the size (eg. it can be 0 or max value) so set it to the max possible value + streamSize = reader.Length - offset; + } if (verify && offset + size < offset) failedVerification = true; if (throwOnError && failedVerification) diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index f05d873ec..488451306 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -22,6 +22,7 @@ public sealed partial class TablesStream : DotNetStream { IColumnReader columnReader; IRowReader methodRowReader; + readonly CLRRuntimeReaderKind runtime; #pragma warning disable 1591 // XML doc comment public MDTable ModuleTable { get; private set; } @@ -154,26 +155,43 @@ public IRowReader MethodRowReader { /// /// Gets the bit /// - public bool HasPadding => (flags & MDStreamFlags.Padding) != 0; + public bool HasPadding => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.Padding) != 0; /// /// Gets the bit /// - public bool HasDeltaOnly => (flags & MDStreamFlags.DeltaOnly) != 0; + public bool HasDeltaOnly => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.DeltaOnly) != 0; /// /// Gets the bit /// - public bool HasExtraData => (flags & MDStreamFlags.ExtraData) != 0; + public bool HasExtraData => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.ExtraData) != 0; /// /// Gets the bit /// - public bool HasDelete => (flags & MDStreamFlags.HasDelete) != 0; + public bool HasDelete => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.HasDelete) != 0; - /// + /// + /// Constructor + /// + /// factory + /// Offset of metadata + /// Stream header public TablesStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) + : this(mdReaderFactory, metadataBaseOffset, streamHeader, CLRRuntimeReaderKind.CLR) { + } + + /// + /// Constructor + /// + /// factory + /// Offset of metadata + /// Stream header + /// Runtime kind + public TablesStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader, CLRRuntimeReaderKind runtime) : base(mdReaderFactory, metadataBaseOffset, streamHeader) { + this.runtime = runtime; } /// diff --git a/src/DotNet/ModuleCreationOptions.cs b/src/DotNet/ModuleCreationOptions.cs index 72a76f860..dc0020f8d 100644 --- a/src/DotNet/ModuleCreationOptions.cs +++ b/src/DotNet/ModuleCreationOptions.cs @@ -42,6 +42,12 @@ public sealed class ModuleCreationOptions { /// public AssemblyRef CorLibAssemblyRef { get; set; } + /// + /// Runtime reader kind, default is . It should be + /// set to if it's an obfuscated Mono/Unity assembly. + /// + public CLRRuntimeReaderKind Runtime { get; set; } = CLRRuntimeReaderKind.CLR; + /// /// Default constructor /// @@ -52,5 +58,38 @@ public ModuleCreationOptions() { } /// /// Module context public ModuleCreationOptions(ModuleContext context) => Context = context; + + /// + /// Constructor + /// + /// Runtime reader kind, default is . It should be + /// set to if it's an obfuscated Mono/Unity assembly. + public ModuleCreationOptions(CLRRuntimeReaderKind runtime) => Runtime = runtime; + + /// + /// Constructor + /// + /// Module context + /// Runtime reader kind, default is . It should be + /// set to if it's an obfuscated Mono/Unity assembly. + public ModuleCreationOptions(ModuleContext context, CLRRuntimeReaderKind runtime) { + Context = context; + Runtime = runtime; + } + } + + /// + /// Runtime reader kind + /// + public enum CLRRuntimeReaderKind { + /// + /// Microsoft's CLRs (.NET Framework, .NET Core) + /// + CLR, + + /// + /// Mono's CLR (Mono, Unity) + /// + Mono, } } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 6835c5bdb..18e99c734 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -149,7 +149,7 @@ protected override VTableFixups GetVTableFixups_NoLock() { /// File name of an existing .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) => Load(MetadataFactory.Load(fileName), options); + public static ModuleDefMD Load(string fileName, ModuleCreationOptions options = null) => Load(MetadataFactory.Load(fileName, options?.Runtime ?? CLRRuntimeReaderKind.CLR), options); /// /// Creates a instance from a byte[] @@ -165,7 +165,7 @@ protected override VTableFixups GetVTableFixups_NoLock() { /// Contents of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) => Load(MetadataFactory.Load(data), options); + public static ModuleDefMD Load(byte[] data, ModuleCreationOptions options = null) => Load(MetadataFactory.Load(data, options?.Runtime ?? CLRRuntimeReaderKind.CLR), options); /// /// Creates a instance from a reflection module @@ -240,7 +240,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// /// Address of a .NET module/assembly /// A new instance - public static ModuleDefMD Load(IntPtr addr) => Load(MetadataFactory.Load(addr), (ModuleCreationOptions)null); + public static ModuleDefMD Load(IntPtr addr) => Load(MetadataFactory.Load(addr, CLRRuntimeReaderKind.CLR), (ModuleCreationOptions)null); /// /// Creates a instance from a memory location @@ -248,7 +248,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Address of a .NET module/assembly /// Module context or null /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleContext context) => Load(MetadataFactory.Load(addr), new ModuleCreationOptions(context)); + public static ModuleDefMD Load(IntPtr addr, ModuleContext context) => Load(MetadataFactory.Load(addr, CLRRuntimeReaderKind.CLR), new ModuleCreationOptions(context)); /// /// Creates a instance from a memory location @@ -256,14 +256,14 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Address of a .NET module/assembly /// Module creation options or null /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options) => Load(MetadataFactory.Load(addr), options); + public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options) => Load(MetadataFactory.Load(addr, options?.Runtime ?? CLRRuntimeReaderKind.CLR), options); /// /// Creates a instance /// /// PE image /// A new instance - public static ModuleDefMD Load(IPEImage peImage) => Load(MetadataFactory.Load(peImage), (ModuleCreationOptions)null); + public static ModuleDefMD Load(IPEImage peImage) => Load(MetadataFactory.Load(peImage, CLRRuntimeReaderKind.CLR), (ModuleCreationOptions)null); /// /// Creates a instance @@ -271,7 +271,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// PE image /// Module context or null /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) => Load(MetadataFactory.Load(peImage), new ModuleCreationOptions(context)); + public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) => Load(MetadataFactory.Load(peImage, CLRRuntimeReaderKind.CLR), new ModuleCreationOptions(context)); /// /// Creates a instance @@ -279,7 +279,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// PE image /// Module creation options or null /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) => Load(MetadataFactory.Load(peImage), options); + public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) => Load(MetadataFactory.Load(peImage, options?.Runtime ?? CLRRuntimeReaderKind.CLR), options); /// /// Creates a instance from a memory location @@ -288,7 +288,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Module context or null /// Image layout of the file in memory /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout imageLayout) => Load(MetadataFactory.Load(addr, imageLayout), new ModuleCreationOptions(context)); + public static ModuleDefMD Load(IntPtr addr, ModuleContext context, ImageLayout imageLayout) => Load(MetadataFactory.Load(addr, imageLayout, CLRRuntimeReaderKind.CLR), new ModuleCreationOptions(context)); /// /// Creates a instance from a memory location @@ -297,7 +297,7 @@ public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptio /// Module creation options or null /// Image layout of the file in memory /// A new instance - public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, ImageLayout imageLayout) => Load(MetadataFactory.Load(addr, imageLayout), options); + public static ModuleDefMD Load(IntPtr addr, ModuleCreationOptions options, ImageLayout imageLayout) => Load(MetadataFactory.Load(addr, imageLayout, options?.Runtime ?? CLRRuntimeReaderKind.CLR), options); /// /// Creates a instance from a stream From 2ed6c0c9c3d9868bf5e165f7238954a7a8f69deb Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 31 Jul 2019 23:34:32 +0200 Subject: [PATCH 323/511] Store it in other list --- src/DotNet/MD/CompressedMetadata.cs | 2 +- src/DotNet/MD/ENCMetadata.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index 3db74a9ed..97c020970 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -78,7 +78,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui case "#Pdb": if (isStandalonePortablePdb && pdbStream is null) { pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(pdbStream); + newAllStreams.Add(pdbStream); continue; } break; diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 61c91c461..97d1f5194 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -88,7 +88,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui case "#Pdb": if (isStandalonePortablePdb && pdbStream is null) { pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(pdbStream); + newAllStreams.Add(pdbStream); continue; } break; From 6043d9133fccf1073b2b5efed5fa4eed5a7c05fd Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 1 Aug 2019 20:52:48 +0200 Subject: [PATCH 324/511] Mono: Use uncompressed stream if #- was found, even if there's a #~ stream after it --- src/DotNet/MD/ENCMetadata.cs | 1 + src/DotNet/MD/MetadataFactory.cs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 97d1f5194..83a81b3fe 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -77,6 +77,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui } break; + case "#~": case "#-": if (tablesStream is null) { tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime); diff --git a/src/DotNet/MD/MetadataFactory.cs b/src/DotNet/MD/MetadataFactory.cs index 192eafa0c..7f276b2b9 100644 --- a/src/DotNet/MD/MetadataFactory.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -220,8 +220,10 @@ static MetadataType GetMetadataType(IList streamHeaders, CLRRuntim foreach (var sh in streamHeaders) { if (sh.Name == "#~") mdType = MetadataType.Compressed; - else if (sh.Name == "#-") + else if (sh.Name == "#-") { mdType = MetadataType.ENC; + break; + } } } else From 5bf183e7f0826aa71012d60f6dc86f8837685877 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 11 Aug 2019 22:11:57 +0200 Subject: [PATCH 325/511] Don't re-add standalonesig if it's already been added and it contains generic types, closes #299 --- src/DotNet/Writer/PreserveTokensMetadata.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Writer/PreserveTokensMetadata.cs b/src/DotNet/Writer/PreserveTokensMetadata.cs index de7c66cc9..42d5611c8 100644 --- a/src/DotNet/Writer/PreserveTokensMetadata.cs +++ b/src/DotNet/Writer/PreserveTokensMetadata.cs @@ -480,8 +480,11 @@ void InitializeMemberRefTableRows() { initdMemberRef = true; uint rows = mod.TablesStream.MemberRefTable.Rows; - for (uint rid = 1; rid <= rows; rid++) + for (uint rid = 1; rid <= rows; rid++) { + if (tablesHeap.MemberRefTable[rid].Class != 0) + continue; AddMemberRef(mod.ResolveMemberRef(rid), true); + } tablesHeap.MemberRefTable.ReAddRows(); } @@ -492,8 +495,11 @@ void InitializeStandAloneSigTableRows() { initdStandAloneSig = true; uint rows = mod.TablesStream.StandAloneSigTable.Rows; - for (uint rid = 1; rid <= rows; rid++) + for (uint rid = 1; rid <= rows; rid++) { + if (tablesHeap.StandAloneSigTable[rid].Signature != 0) + continue; AddStandAloneSig(mod.ResolveStandAloneSig(rid), true); + } tablesHeap.StandAloneSigTable.ReAddRows(); } @@ -504,8 +510,11 @@ void InitializeTypeSpecTableRows() { initdTypeSpec = true; uint rows = mod.TablesStream.TypeSpecTable.Rows; - for (uint rid = 1; rid <= rows; rid++) + for (uint rid = 1; rid <= rows; rid++) { + if (tablesHeap.TypeSpecTable[rid].Signature != 0) + continue; AddTypeSpec(mod.ResolveTypeSpec(rid), true); + } tablesHeap.TypeSpecTable.ReAddRows(); } @@ -516,8 +525,11 @@ void InitializeMethodSpecTableRows() { initdMethodSpec = true; uint rows = mod.TablesStream.MethodSpecTable.Rows; - for (uint rid = 1; rid <= rows; rid++) + for (uint rid = 1; rid <= rows; rid++) { + if (tablesHeap.MethodSpecTable[rid].Method != 0) + continue; AddMethodSpec(mod.ResolveMethodSpec(rid), true); + } tablesHeap.MethodSpecTable.ReAddRows(); } From 1c2d8783c617c1cc048e1c7f6c857af50ca9a433 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 11 Aug 2019 22:15:17 +0200 Subject: [PATCH 326/511] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 85c6325b9..f16ce0534 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,10 @@ To get the assembly, use its Assembly property: Console.WriteLine("Assembly: {0}", asm); ``` +If it's an obfuscated Unity/Mono assembly, you need to create a `ModuleCreationOptions` +and write `CLRRuntimeReaderKind.Mono` to `ModuleCreationOptions.Runtime` and pass in +this `ModuleCreationOptions` instance to one of the `ModuleDefMD.Load(...)` methods. + Saving a .NET assembly/module ----------------------------- From 8ff66b51f47db19eb438ade9af233699ce945a77 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 5 Sep 2019 19:48:26 +0200 Subject: [PATCH 327/511] Update appveyor.yml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index bd268a4e9..b30737689 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,4 +24,4 @@ deploy: on: APPVEYOR_REPO_TAG: true api_key: - secure: en/ChGrnyp08i9CgI/8WXLKhl0OHCpPsuBSRv9wt286kvKlI9P4732egbzq+ycfx + secure: 1oWvNqv/17WGGwHiBAuPEXRbFUqG5ZIX83m51TNF1u/jIqAkjt8Ec4LI+jB9N5zh From 7cc9e189afcc69f518a24c0c2f86155d5f4864c8 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 23 Sep 2019 18:40:16 +0200 Subject: [PATCH 328/511] Update SRE nuget package versions --- src/dnlib.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 44c88c17c..87e0570b9 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -57,8 +57,8 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - - + + From 97a2a756c890c3eed4a3f83dcc7c83678c23173d Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 23 Sep 2019 21:59:58 +0200 Subject: [PATCH 329/511] Update VS version in sln file --- dnlib.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnlib.sln b/dnlib.sln index e3a916c93..cc58351cd 100644 --- a/dnlib.sln +++ b/dnlib.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.28729.10 -MinimumVisualStudioVersion = 16.0.28729.10 +VisualStudioVersion = 16.0.29318.209 +MinimumVisualStudioVersion = 16.0.29318.209 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib", "src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples", "Examples\Examples.csproj", "{F27E72B5-C4BD-40BF-AD19-4C8A99B55872}" From 57e5e781f82d98d0481ae1856e76022e19d20df1 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 25 Sep 2019 01:22:02 +0200 Subject: [PATCH 330/511] Enable GitHub Actions --- .github/workflows/build.yml | 43 +++++++++++++++++++++++++++++++++++++ README.md | 2 +- appveyor.yml | 23 ++++++++++++++------ 3 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..94f045a86 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,43 @@ +name: GitHub CI +on: [push, pull_request] + +jobs: + build: + name: Build + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + with: + submodules: true + fetch-depth: 1 + + - name: Install .NET Core + shell: pwsh + run: | + Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile "$env:temp\dotnet-install.ps1" + & $env:temp\dotnet-install.ps1 -Version 3.0.100 -InstallDir "$env:ProgramFiles\dotnet" -Architecture x64 + + - name: Install VS build tools + shell: pwsh + run: | + # To get an updated EXE URL, go to https://visualstudio.microsoft.com/downloads/ -> Tools for VS -> Build Tools for VS + Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/1d102ee6-9263-4353-8676-6430f0cc5998/c0457643c8a80b008250148151a51cb6cc0aa2ccb57316db496628faa9b9a84f/vs_BuildTools.exe' -UseBasicParsing -OutFile "$env:temp\vs_BuildTools.exe" + # List of ids: https://docs.microsoft.com/visualstudio/install/workload-component-id-vs-build-tools?vs-2019&view=vs-2019 + & "$env:TEMP\vs_BuildTools.exe" --quiet --wait --norestart --installPath "C:\vsbuildtools" --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools --add Microsoft.VisualStudio.Workload.NetCoreBuildTools + Wait-Process vs_BuildTools + + - name: Build + run: | + set path=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%path% + msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln + msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln + + - name: upload-artifact doesn't support wildcards + run: | + mkdir nuget_files + copy "src\bin\Release\*.*nupkg" nuget_files + + - uses: actions/upload-artifact@v1 + with: + name: nupkg + path: nuget_files diff --git a/README.md b/README.md index f16ce0534..ea184f452 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# dnlib [![Build status](https://ci.appveyor.com/api/projects/status/h7dqmfac6qjh4hap/branch/master?svg=true)](https://ci.appveyor.com/project/0xd4d/dnlib/branch/master) [![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) +# dnlib [![Build status](https://ci.appveyor.com/api/projects/status/h7dqmfac6qjh4hap/branch/master?svg=true)](https://ci.appveyor.com/project/0xd4d/dnlib/branch/master) [![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) [![](https://github.com/0xd4d/dnlib/workflows/GitHub%20CI/badge.svg)](https://github.com/0xd4d/dnlib/actions) .NET module/assembly reader/writer library diff --git a/appveyor.yml b/appveyor.yml index b30737689..0423694e7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,14 +1,23 @@ version: x.x.{build} image: Visual Studio 2019 configuration: Release -before_build: -- cmd: appveyor-retry nuget restore -build: - project: dnlib.sln - parallel: true - verbosity: normal +install: +- cmd: | + appveyor DownloadFile https://dot.net/v1/dotnet-install.ps1 + powershell -NoLogo -NoProfile -File dotnet-install.ps1 -Version 3.0.100 -InstallDir "%ProgramFiles%\dotnet" -Architecture x64 + REM To get an updated EXE URL, go to https://visualstudio.microsoft.com/downloads/ -> Tools for VS -> Build Tools for VS + appveyor DownloadFile https://download.visualstudio.microsoft.com/download/pr/1d102ee6-9263-4353-8676-6430f0cc5998/c0457643c8a80b008250148151a51cb6cc0aa2ccb57316db496628faa9b9a84f/vs_BuildTools.exe + start /wait vs_BuildTools.exe --quiet --wait --norestart --installPath "C:\vsbuildtools" --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools --add Microsoft.VisualStudio.Workload.NetCoreBuildTools +build_script: +- cmd: | + set path=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%path% + msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln + msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln +test: off before_package: -- cmd: msbuild /m /p:Configuration=Release /t:Pack dnlib.sln +- cmd: | + set path=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%path% + msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln artifacts: - path: src\bin\Release\*.*nupkg name: dnlib NuGet Packages From 48f8550d9bd59836ec774465c22af857b362710e Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 25 Sep 2019 19:30:31 +0200 Subject: [PATCH 331/511] Update build files --- .github/workflows/build.yml | 18 +++++++++++------- appveyor.yml | 22 ++-------------------- build.cmd | 10 ++++++++++ 3 files changed, 23 insertions(+), 27 deletions(-) create mode 100644 build.cmd diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 94f045a86..f2061a54e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,5 @@ name: GitHub CI -on: [push, pull_request] +on: push jobs: build: @@ -7,9 +7,6 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v1 - with: - submodules: true - fetch-depth: 1 - name: Install .NET Core shell: pwsh @@ -17,6 +14,7 @@ jobs: Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile "$env:temp\dotnet-install.ps1" & $env:temp\dotnet-install.ps1 -Version 3.0.100 -InstallDir "$env:ProgramFiles\dotnet" -Architecture x64 + # build.cmd needs to use msbuild since dotnet build doesn't support net35 - name: Install VS build tools shell: pwsh run: | @@ -28,9 +26,8 @@ jobs: - name: Build run: | - set path=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%path% - msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln - msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln + set PATH=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%PATH% + build.cmd - name: upload-artifact doesn't support wildcards run: | @@ -41,3 +38,10 @@ jobs: with: name: nupkg path: nuget_files + + - name: Upload to nuget.org if it's a new release + if: startsWith(github.ref, 'refs/tags/') + shell: pwsh + run: | + Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -UseBasicParsing -OutFile nuget.exe + Get-Item "src\bin\Release\dnlib.*.nupkg" | % { nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } diff --git a/appveyor.yml b/appveyor.yml index 0423694e7..b3beb4fbe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,27 +10,9 @@ install: start /wait vs_BuildTools.exe --quiet --wait --norestart --installPath "C:\vsbuildtools" --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools --add Microsoft.VisualStudio.Workload.NetCoreBuildTools build_script: - cmd: | - set path=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%path% - msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln - msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln + set PATH=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%PATH% + build.cmd test: off -before_package: -- cmd: | - set path=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%path% - msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln artifacts: - path: src\bin\Release\*.*nupkg name: dnlib NuGet Packages -notifications: -- provider: Email - to: - - de4dot@gmail.com - on_build_success: false - on_build_failure: true - on_build_status_changed: false -deploy: -- provider: NuGet - on: - APPVEYOR_REPO_TAG: true - api_key: - secure: 1oWvNqv/17WGGwHiBAuPEXRbFUqG5ZIX83m51TNF1u/jIqAkjt8Ec4LI+jB9N5zh diff --git a/build.cmd b/build.cmd new file mode 100644 index 000000000..145fb7fb5 --- /dev/null +++ b/build.cmd @@ -0,0 +1,10 @@ +@echo off +REM dotnet build isn't used because it can't build net35 tfms + +msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln || goto :error +msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln || goto :error + +goto :EOF + +:error +exit /b %errorlevel% From 87a0d19a9873efc7ee92d899e99ecf9a5878c9ff Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 26 Sep 2019 01:24:29 +0200 Subject: [PATCH 332/511] Remove appveyor --- README.md | 2 +- appveyor.yml | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 appveyor.yml diff --git a/README.md b/README.md index ea184f452..c57056038 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# dnlib [![Build status](https://ci.appveyor.com/api/projects/status/h7dqmfac6qjh4hap/branch/master?svg=true)](https://ci.appveyor.com/project/0xd4d/dnlib/branch/master) [![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) [![](https://github.com/0xd4d/dnlib/workflows/GitHub%20CI/badge.svg)](https://github.com/0xd4d/dnlib/actions) +# dnlib [![NuGet](https://img.shields.io/nuget/v/dnlib.svg)](https://www.nuget.org/packages/dnlib/) [![](https://github.com/0xd4d/dnlib/workflows/GitHub%20CI/badge.svg)](https://github.com/0xd4d/dnlib/actions) .NET module/assembly reader/writer library diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b3beb4fbe..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: x.x.{build} -image: Visual Studio 2019 -configuration: Release -install: -- cmd: | - appveyor DownloadFile https://dot.net/v1/dotnet-install.ps1 - powershell -NoLogo -NoProfile -File dotnet-install.ps1 -Version 3.0.100 -InstallDir "%ProgramFiles%\dotnet" -Architecture x64 - REM To get an updated EXE URL, go to https://visualstudio.microsoft.com/downloads/ -> Tools for VS -> Build Tools for VS - appveyor DownloadFile https://download.visualstudio.microsoft.com/download/pr/1d102ee6-9263-4353-8676-6430f0cc5998/c0457643c8a80b008250148151a51cb6cc0aa2ccb57316db496628faa9b9a84f/vs_BuildTools.exe - start /wait vs_BuildTools.exe --quiet --wait --norestart --installPath "C:\vsbuildtools" --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools --add Microsoft.VisualStudio.Workload.NetCoreBuildTools -build_script: -- cmd: | - set PATH=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%PATH% - build.cmd -test: off -artifacts: -- path: src\bin\Release\*.*nupkg - name: dnlib NuGet Packages From 37e6de63b31092f6e380664fc8f44e3b069679ac Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 27 Sep 2019 18:40:29 +0200 Subject: [PATCH 333/511] Update build files --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2061a54e..22fed3c39 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,4 +44,4 @@ jobs: shell: pwsh run: | Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -UseBasicParsing -OutFile nuget.exe - Get-Item "src\bin\Release\dnlib.*.nupkg" | % { nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } + Get-Item "src\bin\Release\dnlib.*.nupkg" | % { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } From eed0e7c821987cc89b573ba364159ec6ee0fcde8 Mon Sep 17 00:00:00 2001 From: Bastian Schmidt Date: Sat, 28 Sep 2019 19:20:14 +0200 Subject: [PATCH 334/511] Allow overwriting of the dll name which should be imported (#281) * Allowing overwriting of the dll name which should be imported * Fixing length calculation issue * Allow users to overwrite EntryPointName * Adding hint about ijwhost on .NET Core to readme --- README.md | 1 + src/DotNet/Writer/ImportDirectory.cs | 34 ++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c57056038..711d3e9a2 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,7 @@ Exporting managed methods (DllExport) ------------------------------------- dnlib supports exporting managed methods so the managed DLL file can be loaded by native code and then executed. .NET Framework supports this feature, but there's no guarantee that other CLRs (eg. .NET Core or Mono/Unity) support this feature. +In case of .NET Core please be aware that `ijwhost.dll` has to be loaded prior to calling your exported method and that ijwhost currently (as of .NET Core 3.0) does not work if the calling app is self-contained. The `MethodDef` class has an `ExportInfo` property. If it gets initialized, the method gets exported when saving the module. At most 65536 (2^16) methods can be exported. This is a PE file limitation, not a dnlib limitation. diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index 63dbdbf95..db8a6eaf8 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -16,8 +16,10 @@ public sealed class ImportDirectory : IChunk { uint length; RVA importLookupTableRVA; RVA corXxxMainRVA; - RVA mscoreeDllRVA; + RVA dllToImportRVA; int stringsPadding; + string dllToImport; + string entryPointName; /// /// Gets/sets the @@ -50,7 +52,25 @@ public bool IsExeFile { internal bool Enable { get; set; } + /// + /// Gets/sets the name of the dll which should be imported. + /// + public string DllToImport { + get => dllToImport ?? "mscoree.dll"; + set => dllToImport = value; + } + + /// + /// Gets/sets the name of the entry point of the imported dll. + /// + public string EntryPointName { + get => entryPointName ?? (IsExeFile ? "_CorExeMain" : "_CorDllMain"); + set => entryPointName = value; + } + const uint STRINGS_ALIGNMENT = 16; + const uint ZERO_STRING_TERMINATION = 1; + const uint TWO_BYTE_PADDING = 2; /// /// Constructor @@ -70,9 +90,9 @@ public void SetOffset(FileOffset offset, RVA rva) { stringsPadding = (int)(rva.AlignUp(STRINGS_ALIGNMENT) - rva); length += (uint)stringsPadding; corXxxMainRVA = rva + length; - length += 0xE; - mscoreeDllRVA = rva + length; - length += 0xC; + length += (uint)EntryPointName.Length + ZERO_STRING_TERMINATION + TWO_BYTE_PADDING; + dllToImportRVA = rva + length; + length += (uint)DllToImport.Length + ZERO_STRING_TERMINATION; length++; } @@ -93,7 +113,7 @@ public void WriteTo(DataWriter writer) { writer.WriteUInt32((uint)importLookupTableRVA); writer.WriteInt32(0); // DateTimeStamp writer.WriteInt32(0); // ForwarderChain - writer.WriteUInt32((uint)mscoreeDllRVA); // Name + writer.WriteUInt32((uint)dllToImportRVA); // Name writer.WriteUInt32((uint)ImportAddressTable.RVA); writer.WriteUInt64(0); writer.WriteUInt64(0); @@ -111,8 +131,8 @@ public void WriteTo(DataWriter writer) { writer.WriteZeroes(stringsPadding); writer.WriteUInt16(0); - writer.WriteBytes(Encoding.UTF8.GetBytes(IsExeFile ? "_CorExeMain\0" : "_CorDllMain\0")); - writer.WriteBytes(Encoding.UTF8.GetBytes("mscoree.dll\0")); + writer.WriteBytes(Encoding.UTF8.GetBytes($"{EntryPointName}\0")); + writer.WriteBytes(Encoding.UTF8.GetBytes($"{DllToImport}\0")); writer.WriteByte(0); } From 2fe4dda1a41600e05f99e593909f10bdbff37bf7 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 28 Sep 2019 19:20:43 +0200 Subject: [PATCH 335/511] Remvoe consts --- src/DotNet/Writer/ImportDirectory.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index db8a6eaf8..c871aed8f 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -69,8 +69,6 @@ public string EntryPointName { } const uint STRINGS_ALIGNMENT = 16; - const uint ZERO_STRING_TERMINATION = 1; - const uint TWO_BYTE_PADDING = 2; /// /// Constructor @@ -90,9 +88,9 @@ public void SetOffset(FileOffset offset, RVA rva) { stringsPadding = (int)(rva.AlignUp(STRINGS_ALIGNMENT) - rva); length += (uint)stringsPadding; corXxxMainRVA = rva + length; - length += (uint)EntryPointName.Length + ZERO_STRING_TERMINATION + TWO_BYTE_PADDING; + length += 2 + (uint)EntryPointName.Length + 1; dllToImportRVA = rva + length; - length += (uint)DllToImport.Length + ZERO_STRING_TERMINATION; + length += (uint)DllToImport.Length + 1; length++; } @@ -131,8 +129,8 @@ public void WriteTo(DataWriter writer) { writer.WriteZeroes(stringsPadding); writer.WriteUInt16(0); - writer.WriteBytes(Encoding.UTF8.GetBytes($"{EntryPointName}\0")); - writer.WriteBytes(Encoding.UTF8.GetBytes($"{DllToImport}\0")); + writer.WriteBytes(Encoding.UTF8.GetBytes(EntryPointName + "\0")); + writer.WriteBytes(Encoding.UTF8.GetBytes(DllToImport + "\0")); writer.WriteByte(0); } From 777c6f9818956f67b6e3ea03e26a3112048f1f54 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 29 Sep 2019 22:09:36 +0200 Subject: [PATCH 336/511] Update build files --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22fed3c39..e1b9e967e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,4 +44,4 @@ jobs: shell: pwsh run: | Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -UseBasicParsing -OutFile nuget.exe - Get-Item "src\bin\Release\dnlib.*.nupkg" | % { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } + Get-Item "src\bin\Release\dnlib.*.nupkg" | ForEach-Object { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } From 0e0a442f4f1cc000371ca0d7851175a16b3d2426 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 3 Oct 2019 18:01:33 +0200 Subject: [PATCH 337/511] Update build files --- .github/workflows/build.yml | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e1b9e967e..dd377709d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,28 +5,13 @@ jobs: build: name: Build runs-on: windows-latest + steps: - uses: actions/checkout@v1 - - name: Install .NET Core - shell: pwsh - run: | - Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile "$env:temp\dotnet-install.ps1" - & $env:temp\dotnet-install.ps1 -Version 3.0.100 -InstallDir "$env:ProgramFiles\dotnet" -Architecture x64 - - # build.cmd needs to use msbuild since dotnet build doesn't support net35 - - name: Install VS build tools - shell: pwsh - run: | - # To get an updated EXE URL, go to https://visualstudio.microsoft.com/downloads/ -> Tools for VS -> Build Tools for VS - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/1d102ee6-9263-4353-8676-6430f0cc5998/c0457643c8a80b008250148151a51cb6cc0aa2ccb57316db496628faa9b9a84f/vs_BuildTools.exe' -UseBasicParsing -OutFile "$env:temp\vs_BuildTools.exe" - # List of ids: https://docs.microsoft.com/visualstudio/install/workload-component-id-vs-build-tools?vs-2019&view=vs-2019 - & "$env:TEMP\vs_BuildTools.exe" --quiet --wait --norestart --installPath "C:\vsbuildtools" --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools --add Microsoft.VisualStudio.Workload.NetCoreBuildTools - Wait-Process vs_BuildTools - - name: Build run: | - set PATH=C:\vsbuildtools\MSBuild\Current\Bin\amd64;%PATH% + set PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64;%PATH% build.cmd - name: upload-artifact doesn't support wildcards @@ -44,4 +29,4 @@ jobs: shell: pwsh run: | Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -UseBasicParsing -OutFile nuget.exe - Get-Item "src\bin\Release\dnlib.*.nupkg" | ForEach-Object { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } + Get-ChildItem src\bin\Release\dnlib.*.nupkg | ForEach-Object { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } From 8a233b083e0bc169d3c136fa8d67bb9a7a3dffe5 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 4 Oct 2019 01:05:10 +0200 Subject: [PATCH 338/511] Update build files --- .github/workflows/build.yml | 10 ++++++---- build.cmd | 10 ---------- build.ps1 | 10 ++++++++++ 3 files changed, 16 insertions(+), 14 deletions(-) delete mode 100644 build.cmd create mode 100644 build.ps1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd377709d..cab0e25cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,14 +10,16 @@ jobs: - uses: actions/checkout@v1 - name: Build + shell: pwsh run: | - set PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64;%PATH% - build.cmd + $env:PATH = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64;' + $env:PATH + .\build.ps1 - name: upload-artifact doesn't support wildcards + shell: pwsh run: | - mkdir nuget_files - copy "src\bin\Release\*.*nupkg" nuget_files + New-Item -ItemType Directory nuget_files > $null + Copy-Item src\bin\Release\*.*nupkg nuget_files - uses: actions/upload-artifact@v1 with: diff --git a/build.cmd b/build.cmd deleted file mode 100644 index 145fb7fb5..000000000 --- a/build.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -REM dotnet build isn't used because it can't build net35 tfms - -msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln || goto :error -msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln || goto :error - -goto :EOF - -:error -exit /b %errorlevel% diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 000000000..3eba44577 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,10 @@ +$ErrorActionPreference = 'Stop' + +# +# dotnet build isn't used because it can't build net35 tfms +# + +msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln +if ($LASTEXITCODE) { exit $LASTEXITCODE } +msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln +if ($LASTEXITCODE) { exit $LASTEXITCODE } From c3d660c67315cadd8f23529cb662fe073d792e59 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sun, 6 Oct 2019 21:01:11 +0200 Subject: [PATCH 339/511] Update build files --- .github/workflows/build.yml | 16 +++++++++++++-- Examples/Examples.csproj | 10 ++++++++-- build.ps1 | 39 +++++++++++++++++++++++++++++++++---- src/dnlib.csproj | 7 +++++-- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cab0e25cc..abba139d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,8 +2,8 @@ name: GitHub CI on: push jobs: - build: - name: Build + build-windows: + name: Build (Windows) runs-on: windows-latest steps: @@ -32,3 +32,15 @@ jobs: run: | Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -UseBasicParsing -OutFile nuget.exe Get-ChildItem src\bin\Release\dnlib.*.nupkg | ForEach-Object { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } + + # Make sure it builds on Linux too + build-ubuntu: + name: Build (Ubuntu) + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + + - name: Build + shell: pwsh + run: ./build.ps1 diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index f46f204e1..83a6f4c67 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,8 +1,7 @@  - netcoreapp2.1 - $(TargetFrameworks);net45 + netcoreapp2.1;net45 Exe false @@ -11,4 +10,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + diff --git a/build.ps1 b/build.ps1 index 3eba44577..f3a4d8164 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,10 +1,41 @@ +param([switch]$NoMsbuild) + $ErrorActionPreference = 'Stop' +$configuration = 'Release' + # # dotnet build isn't used because it can't build net35 tfms # -msbuild -v:m -restore -t:Build -p:Configuration=Release dnlib.sln -if ($LASTEXITCODE) { exit $LASTEXITCODE } -msbuild -v:m -t:Pack -p:Configuration=Release dnlib.sln -if ($LASTEXITCODE) { exit $LASTEXITCODE } +$env:NoTargetFrameworkNet35 = '' + +if ($IsWindows) { + $useMsbuild = $true +} +else { + $useMsbuild = $false +} +if ($NoMsbuild) { + $useMsbuild = $false +} + +if (!$useMsbuild) { + # There are currently no net35 reference assemblies on nuget + $env:NoTargetFrameworkNet35 = 'true' +} + +if ($useMsbuild) { + msbuild -v:m -restore -t:Build -p:Configuration=$configuration + if ($LASTEXITCODE) { exit $LASTEXITCODE } + msbuild -v:m -t:Pack -p:Configuration=$configuration + if ($LASTEXITCODE) { exit $LASTEXITCODE } +} +else { + dotnet build -v:m -c $configuration + if ($LASTEXITCODE) { exit $LASTEXITCODE } + dotnet pack -v:m -c $configuration src/dnlib.csproj + if ($LASTEXITCODE) { exit $LASTEXITCODE } +} + +$env:NoTargetFrameworkNet35 = '' diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 898ddaed3..c046002b9 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -5,8 +5,7 @@ $(DefineConstants);$(MoreDefineConstants) $(DefineConstants);THREAD_SAFE - netstandard2.0 - $(TargetFrameworks);net45 + netstandard2.0;net45 true @@ -53,6 +52,10 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + From dedbdce613b79263f66dd64d881654aa1eacbcfd Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sun, 6 Oct 2019 22:21:58 +0200 Subject: [PATCH 340/511] Remove .gitattributes --- .gitattributes | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 03177af52..000000000 --- a/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -* text=auto -*.cs text diff=csharp -*.sln text eol=crlf -*.csproj text eol=crlf From d643694dff97d51134eee71a5a318f06a0853a91 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 7 Oct 2019 18:39:01 +0200 Subject: [PATCH 341/511] Update build and csproj files --- .github/workflows/build.yml | 5 +++-- Examples/Examples.csproj | 5 +---- build.ps1 | 2 +- src/dnlib.csproj | 7 ++----- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index abba139d1..8acdf01c3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,8 @@ jobs: - name: Build shell: pwsh run: | - $env:PATH = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64;' + $env:PATH + $msbuildPath = Join-Path (Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft Visual Studio" | Where-Object { $_.Name -match '^\d{4}$' -and $_.PSIsContainer } | Sort-Object Name -Descending)[0] 'Enterprise\MSBuild\Current\Bin\amd64' + $env:PATH = $msbuildPath + ';' + $env:PATH .\build.ps1 - name: upload-artifact doesn't support wildcards @@ -30,7 +31,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/') shell: pwsh run: | - Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -UseBasicParsing -OutFile nuget.exe + Invoke-WebRequest -Uri https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -UseBasicParsing -OutFile nuget.exe Get-ChildItem src\bin\Release\dnlib.*.nupkg | ForEach-Object { .\nuget.exe push $_.FullName -ApiKey ${{secrets.NUGET_APIKEY}} -NonInteractive -Source https://api.nuget.org/v3/index.json } # Make sure it builds on Linux too diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 83a6f4c67..6b6e88c24 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -11,10 +11,7 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + diff --git a/build.ps1 b/build.ps1 index f3a4d8164..7dad36c82 100644 --- a/build.ps1 +++ b/build.ps1 @@ -28,7 +28,7 @@ if (!$useMsbuild) { if ($useMsbuild) { msbuild -v:m -restore -t:Build -p:Configuration=$configuration if ($LASTEXITCODE) { exit $LASTEXITCODE } - msbuild -v:m -t:Pack -p:Configuration=$configuration + msbuild -v:m -t:Pack -p:Configuration=$configuration src/dnlib.csproj if ($LASTEXITCODE) { exit $LASTEXITCODE } } else { diff --git a/src/dnlib.csproj b/src/dnlib.csproj index c046002b9..3e25ff975 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -52,11 +52,8 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + From 3f4014db5f8a640a38d2a1275ec01e2d47b0850e Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 9 Oct 2019 18:37:46 +0200 Subject: [PATCH 342/511] Update build files --- build.ps1 | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/build.ps1 b/build.ps1 index 7dad36c82..11e20bc0b 100644 --- a/build.ps1 +++ b/build.ps1 @@ -10,12 +10,7 @@ $configuration = 'Release' $env:NoTargetFrameworkNet35 = '' -if ($IsWindows) { - $useMsbuild = $true -} -else { - $useMsbuild = $false -} +$useMsbuild = $IsWindows -or $IsWindows -eq $null if ($NoMsbuild) { $useMsbuild = $false } From 1457fa14f9e39ec2ca15e5ef9e8d97ec09f825db Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 12 Oct 2019 13:02:29 +0200 Subject: [PATCH 343/511] Remove BOM --- Examples/Examples.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 6b6e88c24..a401dde40 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1;net45 From 66e67690a9c33018cfe1a5ac98b18c19962083be Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Tue, 15 Oct 2019 20:44:12 +0200 Subject: [PATCH 344/511] Use vswhere to locate msbuild --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8acdf01c3..86e4282a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: - name: Build shell: pwsh run: | - $msbuildPath = Join-Path (Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft Visual Studio" | Where-Object { $_.Name -match '^\d{4}$' -and $_.PSIsContainer } | Sort-Object Name -Descending)[0] 'Enterprise\MSBuild\Current\Bin\amd64' + $msbuildPath = Split-Path (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.Component.MSBuild -find MSBuild\Current\Bin\amd64\MSBuild.exe | Select-Object -First 1) -Parent $env:PATH = $msbuildPath + ';' + $env:PATH .\build.ps1 From 427c4fda6f5df12ee39932bf1234d6375e81c170 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 19 Oct 2019 15:17:11 +0200 Subject: [PATCH 345/511] Update CA type resolver, make sure the type is an original type in the module --- src/DotNet/CustomAttributeReader.cs | 4 +++- src/DotNet/TypeDef.cs | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index b1bdc3896..98a5f1917 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -25,7 +25,9 @@ public AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { var modAsm = module.Assembly; if (!(modAsm is null)) { var type = modAsm.Find(nonNestedTypeRef); - if (!(type is null)) + // If the user added a new type with the same name as a corelib type, don't return it, + // only return the type if it is this module's original type. + if (type is TypeDefMD td && td.ReaderModule == module) return module.UpdateRowId(new AssemblyRefUser(modAsm)); } else if (!(module.Find(nonNestedTypeRef) is null)) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 2b39d9d82..1381f4347 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -1951,6 +1951,8 @@ sealed class TypeDefMD : TypeDef, IMDTokenProviderMD { /// The module where this instance is located readonly ModuleDefMD readerModule; + internal ModuleDefMD ReaderModule => readerModule; + readonly uint origRid; readonly uint extendsCodedToken; Dictionary> methodRidToOverrides; From 857b3134253724ad498ea3e9a37ab522154733a5 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 19 Oct 2019 15:17:20 +0200 Subject: [PATCH 346/511] Add an option to enable optimized CA serialized type strings --- src/DotNet/Writer/DeclSecurityWriter.cs | 25 +++++++++++++++---- src/DotNet/Writer/MarshalBlobWriter.cs | 24 +++++++++++++++--- src/DotNet/Writer/Metadata.cs | 33 ++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index c7ac959b4..f0f48e910 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -13,6 +13,7 @@ namespace dnlib.DotNet.Writer { readonly ModuleDef module; readonly IWriterError helper; readonly DataWriterContext context; + readonly bool optimizeCustomAttributeSerializedTypeNames; /// /// Creates a DeclSecurity blob from @@ -22,15 +23,28 @@ namespace dnlib.DotNet.Writer { /// Helps this class /// A DeclSecurity blob public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper) => - new DeclSecurityWriter(module, helper, null).Write(secAttrs); + Write(module, secAttrs, helper, false); - internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, DataWriterContext context) => - new DeclSecurityWriter(module, helper, context).Write(secAttrs); + /// + /// Creates a DeclSecurity blob from + /// + /// Owner module + /// List of s + /// Helps this class + /// Optimize serialized type strings in custom attributes. + /// For more info, see + /// A DeclSecurity blob + public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, bool optimizeCustomAttributeSerializedTypeNames) => + new DeclSecurityWriter(module, helper, optimizeCustomAttributeSerializedTypeNames, null).Write(secAttrs); + + internal static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper, bool optimizeCustomAttributeSerializedTypeNames, DataWriterContext context) => + new DeclSecurityWriter(module, helper, optimizeCustomAttributeSerializedTypeNames, context).Write(secAttrs); - DeclSecurityWriter(ModuleDef module, IWriterError helper, DataWriterContext context) { + DeclSecurityWriter(ModuleDef module, IWriterError helper, bool optimizeCustomAttributeSerializedTypeNames, DataWriterContext context) { this.module = module; this.helper = helper; this.context = context; + this.optimizeCustomAttributeSerializedTypeNames = optimizeCustomAttributeSerializedTypeNames; } byte[] Write(IList secAttrs) { @@ -88,6 +102,7 @@ byte[] WriteFormat2(IList secAttrs) { uint WriteCompressedUInt32(DataWriter writer, uint value) => writer.WriteCompressedUInt32(helper, value); void Write(DataWriter writer, UTF8String s) => writer.Write(helper, s); void IWriterError.Error(string message) => helper.Error(message); - bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type); + bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => + !optimizeCustomAttributeSerializedTypeNames || FullNameFactory.MustUseAssemblyName(module, type); } } diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 623037013..75617a09f 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -12,6 +12,7 @@ namespace dnlib.DotNet.Writer { readonly MemoryStream outStream; readonly DataWriter writer; readonly IWriterError helper; + readonly bool optimizeCustomAttributeSerializedTypeNames; /// /// Creates a field marshal blob from @@ -21,16 +22,30 @@ namespace dnlib.DotNet.Writer { /// Helps this class /// A field marshal blob or null if is /// null - public static byte[] Write(ModuleDef module, MarshalType marshalType, IWriterError helper) { - using (var writer = new MarshalBlobWriter(module, helper)) + public static byte[] Write(ModuleDef module, MarshalType marshalType, IWriterError helper) => + Write(module, marshalType, helper, false); + + /// + /// Creates a field marshal blob from + /// + /// Owner module + /// Marshal type + /// Helps this class + /// Optimize serialized type strings in custom attributes. + /// For more info, see + /// A field marshal blob or null if is + /// null + public static byte[] Write(ModuleDef module, MarshalType marshalType, IWriterError helper, bool optimizeCustomAttributeSerializedTypeNames) { + using (var writer = new MarshalBlobWriter(module, helper, optimizeCustomAttributeSerializedTypeNames)) return writer.Write(marshalType); } - MarshalBlobWriter(ModuleDef module, IWriterError helper) { + MarshalBlobWriter(ModuleDef module, IWriterError helper, bool optimizeCustomAttributeSerializedTypeNames) { this.module = module; outStream = new MemoryStream(); writer = new DataWriter(outStream); this.helper = helper; + this.optimizeCustomAttributeSerializedTypeNames = optimizeCustomAttributeSerializedTypeNames; } byte[] Write(MarshalType marshalType) { @@ -130,6 +145,7 @@ bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { /// public void Dispose() => outStream?.Dispose(); - bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type); + bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => + !optimizeCustomAttributeSerializedTypeNames || FullNameFactory.MustUseAssemblyName(module, type); } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 0f0264773..110b5b87f 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -177,6 +177,19 @@ public enum MetadataFlags : uint { /// Don't write field data /// NoFieldData = 0x800000, + + /// + /// Serialized type names stored in custom attributes are optimized if the types + /// exist in the current module or in the core library (eg. mscorlib/System.Private.CoreLib). + /// Instead of storing type-name + assembly-name, only type-name is stored. This results in + /// slightly smaller assemblies. + ///
+ ///
+ /// This is disabled by default. It's safe to enable if the reference core assembly + /// is the same as the runtime core assembly (eg. it's mscorlib.dll and .NET Framework, + /// but not .NET Core). + ///
+ OptimizeCustomAttributeSerializedTypeNames = 0x1000000, } /// @@ -885,6 +898,19 @@ public bool NoFieldData { } } + /// + /// Gets/sets the bit + /// + public bool OptimizeCustomAttributeSerializedTypeNames { + get => (options.Flags & MetadataFlags.OptimizeCustomAttributeSerializedTypeNames) != 0; + set { + if (value) + options.Flags |= MetadataFlags.OptimizeCustomAttributeSerializedTypeNames; + else + options.Flags &= ~MetadataFlags.OptimizeCustomAttributeSerializedTypeNames; + } + } + /// /// If true, use the original Field RVAs. If it has no RVA, assume it's a new /// field value and create a new Field RVA. @@ -2631,7 +2657,7 @@ protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { encodedParent = 0; } var row = new RawFieldMarshalRow(encodedParent, - blobHeap.Add(MarshalBlobWriter.Write(module, fieldMarshal, this))); + blobHeap.Add(MarshalBlobWriter.Write(module, fieldMarshal, this, OptimizeCustomAttributeSerializedTypeNames))); fieldMarshalInfos.Add(hfm, row); } @@ -2805,7 +2831,7 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit continue; var row = new RawDeclSecurityRow((short)decl.Action, encodedParent, - blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this, bwctx))); + blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this, OptimizeCustomAttributeSerializedTypeNames, bwctx))); declSecurityInfos.Add(decl, row); } Free(ref bwctx); @@ -3534,7 +3560,8 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdb void IWriterError.Error(string message) => Error(message); /// - bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type); + bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => + !OptimizeCustomAttributeSerializedTypeNames || FullNameFactory.MustUseAssemblyName(module, type); /// /// Called before any other methods From bebfe2e5ae94f98d60b60b1e9723f7af35d987f5 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 19 Oct 2019 15:17:29 +0200 Subject: [PATCH 347/511] Initialize asmResolver.DefaultModuleContext in CreateModuleContext() --- src/DotNet/ModuleDef.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 1b19b3a79..684a1ae29 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -1251,6 +1251,7 @@ public static ModuleContext CreateModuleContext() { var res = new Resolver(asmRes); ctx.AssemblyResolver = asmRes; ctx.Resolver = res; + asmRes.DefaultModuleContext = ctx; return ctx; } From 5fbb3b3d93c1f7cd1b5f9757cdf866ed6342dd7e Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 19 Oct 2019 15:17:37 +0200 Subject: [PATCH 348/511] Update README --- README.md | 72 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 711d3e9a2..270352909 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ First of all, the important namespaces are `dnlib.DotNet` and read/write method bodies. All the examples below assume you have the appropriate using statements at the top of each source file: -```csharp +```C# using dnlib.DotNet; using dnlib.DotNet.Emit; ``` @@ -79,28 +79,36 @@ several `Load()` methods that will create a ModuleDefMD instance. If it's not a Read a .NET module from a file: -```csharp - ModuleDefMD module = ModuleDefMD.Load(@"C:\path\to\file.exe"); +```C# + // Create a default assembly resolver and type resolver and pass it to Load(). + // If it's a .NET Core assembly, you'll need to disable GAC loading and add + // .NET Core reference assembly search paths. + ModuleContext modCtx = ModuleDef.CreateModuleContext(); + ModuleDefMD module = ModuleDefMD.Load(@"C:\path\to\file.exe", modCtx); ``` Read a .NET module from a byte array: -```csharp +```C# byte[] data = System.IO.File.ReadAllBytes(@"C:\path\of\file.dll"); - ModuleDefMD module = ModuleDefMD.Load(data); + // See comment above about the assembly resolver + ModuleContext modCtx = ModuleDef.CreateModuleContext(); + ModuleDefMD module = ModuleDefMD.Load(data, modCtx); ``` You can also pass in a Stream instance, an address in memory (HINSTANCE) or even a System.Reflection.Module instance: -```csharp +```C# System.Reflection.Module reflectionModule = typeof(void).Module; // Get mscorlib.dll's module - ModuleDefMD module = ModuleDefMD.Load(reflectionModule); + // See comment above about the assembly resolver + ModuleContext modCtx = ModuleDef.CreateModuleContext(); + ModuleDefMD module = ModuleDefMD.Load(reflectionModule, modCtx); ``` To get the assembly, use its Assembly property: -```csharp +```C# AssemblyDef asm = module.Assembly; Console.WriteLine("Assembly: {0}", asm); ``` @@ -114,19 +122,19 @@ Saving a .NET assembly/module Use `module.Write()`. It can save the assembly to a file or a Stream. -```csharp +```C# module.Write(@"C:\saved-assembly.dll"); ``` If it's a C++/CLI assembly, you should use `NativeWrite()` -```csharp +```C# module.NativeWrite(@"C:\saved-assembly.dll"); ``` To detect it at runtime, use this code: -```csharp +```C# if (module.IsILOnly) { // This assembly has only IL code, and no native code (eg. it's a C# or VB assembly) module.Write(@"C:\saved-assembly.dll"); @@ -152,8 +160,10 @@ name to `PdbFileName` or writing your own stream to `PdbStream`. If `PdbStream` is initialized, `PdbFileName` should also be initialized because the name of the PDB file will be written to the PE file. -```csharp - var mod = ModuleDefMD.Load(@"C:\myfile.dll"); +```C# + // Create a default assembly resolver and type resolver + ModuleContext modCtx = ModuleDef.CreateModuleContext(); + var mod = ModuleDefMD.Load(@"C:\myfile.dll", modCtx); // ... var wopts = new dnlib.DotNet.Writer.ModuleWriterOptions(mod); wopts.WritePdb = true; @@ -179,7 +189,7 @@ Strong name signing an assembly Use the following code to strong name sign the assembly when saving it: -```csharp +```C# using dnlib.DotNet.Writer; ... // Open or create an assembly @@ -206,7 +216,7 @@ for info on enhanced strong naming. Enhanced strong name signing without key migration: -```csharp +```C# using dnlib.DotNet.Writer; ... // Open or create an assembly @@ -228,7 +238,7 @@ Enhanced strong name signing without key migration: Enhanced strong name signing with key migration: -```csharp +```C# using dnlib.DotNet.Writer; ... // Open or create an assembly @@ -343,7 +353,7 @@ is a `SZArraySig`, and *not* an `ArraySig`. Some examples if you're not used to the way type signatures are represented in metadata: -```csharp +```C# ModuleDef mod = ....; // Create a byte[] @@ -367,7 +377,7 @@ in metadata: Sometimes you must convert an `ITypeDefOrRef` (`TypeRef`, `TypeDef`, or `TypeSpec`) to/from a `TypeSig`. There's extension methods you can use: -```csharp +```C# // array5 is defined above ITypeDefOrRef type1 = array5.ToTypeDefOrRef(); TypeSig type2 = type1.ToTypeSig(); @@ -457,7 +467,7 @@ The `SigComparer` class can also compare types with `System.Type`, methods with It has many options you can set, see `SigComparerOptions`. The default options is usually good enough, though. -```csharp +```C# // Compare two types TypeRef type1 = ...; TypeDef type2 = ...; @@ -512,17 +522,17 @@ Resolving references `module.Context.Resolver` to resolve the type, field or method. The custom attribute parser code may also resolve type references. -If you call Resolve() or read custom attributes, you should initialize +If you call `Resolve()` or read custom attributes, you should initialize module.Context to a `ModuleContext`. It should normally be shared between all modules you open. -```csharp - AssemblyResolver asmResolver = new AssemblyResolver(); - ModuleContext modCtx = new ModuleContext(asmResolver); - - // All resolved assemblies will also get this same modCtx - asmResolver.DefaultModuleContext = modCtx; - +```C# + // You should pass this context to ModuleDefMD.Load(), but you can also write + // it to `module.Context` + ModuleContext modCtx = ModuleDef.CreateModuleContext(); + // It creates the default assembly resolver + AssemblyResolver asmResolver = (AssemblyResolver)modCtx.AssemblyResolver; + // Enable the TypeDef cache for all assemblies that are loaded // by the assembly resolver. Only enable it if all auto-loaded // assemblies are read-only. @@ -532,7 +542,7 @@ modules you open. All assemblies that you yourself open should be added to the assembly resolver cache. -```csharp +```C# ModuleDefMD mod = ModuleDefMD.Load(...); mod.Context = modCtx; // Use the previously created (and shared) context // This code assumes you're using the default assembly resolver @@ -552,7 +562,7 @@ Every module has a `CorLibTypes` property. It has references to a few of the simplest types such as all integer types, floating point types, Object, String, etc. If you need a type that's not there, you must create it yourself, eg.: -```csharp +```C# TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef); ``` @@ -562,7 +572,7 @@ Importing runtime types, methods, fields To import a `System.Type`, `System.Reflection.MethodInfo`, `System.Reflection.FieldInfo`, etc into a module, use the `Importer` class. -```csharp +```C# Importer importer = new Importer(mod); ITypeDefOrRef consoleRef = importer.Import(typeof(System.Console)); IMethod writeLine = importer.Import(typeof(System.Console).GetMethod("WriteLine")); @@ -601,7 +611,7 @@ The `Metadata` property gives you full access to the metadata. To get a list of all valid TypeDef rids (row IDs), use this code: -```csharp +```C# using dnlib.DotNet.MD; // ... ModuleDefMD mod = ModuleDefMD.Load(...); From 05f1fd1d6c3ac857d155b343ce8dfe54fdd455d2 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sun, 20 Oct 2019 13:36:16 +0200 Subject: [PATCH 349/511] Update README.md --- README.md | 172 ++++++++++++++---------------------------------------- 1 file changed, 44 insertions(+), 128 deletions(-) diff --git a/README.md b/README.md index 270352909..b43830481 100644 --- a/README.md +++ b/README.md @@ -55,27 +55,21 @@ v3.0 breaking changes Examples -------- -All examples use C#, but since it's a .NET library, you can use any .NET -language (eg. VB.NET). +All examples use C#, but since it's a .NET library, you can use any .NET language (eg. VB.NET). See the Examples project for several examples. Opening a .NET assembly/module ------------------------------ -First of all, the important namespaces are `dnlib.DotNet` and -`dnlib.DotNet.Emit`. `dnlib.DotNet.Emit` is only needed if you intend to -read/write method bodies. All the examples below assume you have the -appropriate using statements at the top of each source file: +First of all, the important namespaces are `dnlib.DotNet` and `dnlib.DotNet.Emit`. `dnlib.DotNet.Emit` is only needed if you intend to read/write method bodies. All the examples below assume you have the appropriate using statements at the top of each source file: ```C# using dnlib.DotNet; using dnlib.DotNet.Emit; ``` -ModuleDefMD is the class that is created when you open a .NET module. It has -several `Load()` methods that will create a ModuleDefMD instance. If it's not a -.NET module/assembly, a `BadImageFormatException` will be thrown. +ModuleDefMD is the class that is created when you open a .NET module. It has several `Load()` methods that will create a ModuleDefMD instance. If it's not a .NET module/assembly, a `BadImageFormatException` will be thrown. Read a .NET module from a file: @@ -96,8 +90,7 @@ Read a .NET module from a byte array: ModuleDefMD module = ModuleDefMD.Load(data, modCtx); ``` -You can also pass in a Stream instance, an address in memory (HINSTANCE) or -even a System.Reflection.Module instance: +You can also pass in a Stream instance, an address in memory (HINSTANCE) or even a System.Reflection.Module instance: ```C# System.Reflection.Module reflectionModule = typeof(void).Module; // Get mscorlib.dll's module @@ -113,9 +106,7 @@ To get the assembly, use its Assembly property: Console.WriteLine("Assembly: {0}", asm); ``` -If it's an obfuscated Unity/Mono assembly, you need to create a `ModuleCreationOptions` -and write `CLRRuntimeReaderKind.Mono` to `ModuleCreationOptions.Runtime` and pass in -this `ModuleCreationOptions` instance to one of the `ModuleDefMD.Load(...)` methods. +If it's an obfuscated Unity/Mono assembly, you need to create a `ModuleCreationOptions` instance and write `CLRRuntimeReaderKind.Mono` to `ModuleCreationOptions.Runtime` and pass in this `ModuleCreationOptions` instance to one of the `ModuleDefMD.Load(...)` methods. Saving a .NET assembly/module ----------------------------- @@ -148,17 +139,9 @@ To detect it at runtime, use this code: PDB files --------- -PDB files are read from disk by default. You can change this behaviour by -creating a `ModuleCreationOptions` and passing it in to the code that creates -a module. +PDB files are read from disk by default. You can change this behaviour by creating a `ModuleCreationOptions` and passing it in to the code that creates a module. -To save a PDB file, create a `ModuleWriterOptions` / -`NativeModuleWriterOptions` and set its `WritePdb` property to `true`. By -default, it will create a PDB file with the same name as the output assembly -but with a `.pdb` extension. You can override this by writing the PDB file -name to `PdbFileName` or writing your own stream to `PdbStream`. If -`PdbStream` is initialized, `PdbFileName` should also be initialized because -the name of the PDB file will be written to the PE file. +To save a PDB file, create a `ModuleWriterOptions` / `NativeModuleWriterOptions` and set its `WritePdb` property to `true`. By default, it will create a PDB file with the same name as the output assembly but with a `.pdb` extension. You can override this by writing the PDB file name to `PdbFileName` or writing your own stream to `PdbStream`. If `PdbStream` is initialized, `PdbFileName` should also be initialized because the name of the PDB file will be written to the PE file. ```C# // Create a default assembly resolver and type resolver @@ -211,8 +194,7 @@ Use the following code to strong name sign the assembly when saving it: Enhanced strong name signing an assembly ---------------------------------------- -See this [MSDN article](http://msdn.microsoft.com/en-us/library/hh415055.aspx) -for info on enhanced strong naming. +See this [MSDN article](http://msdn.microsoft.com/en-us/library/hh415055.aspx) for info on enhanced strong naming. Enhanced strong name signing without key migration: @@ -304,54 +286,41 @@ See the following issues: [#271](https://github.com/0xd4d/dnlib/issues/271), [#1 Type classes ------------ -The metadata has three type tables: `TypeRef`, `TypeDef`, and `TypeSpec`. The -classes dnlib use are called the same. These three classes all implement -`ITypeDefOrRef`. +The metadata has three type tables: `TypeRef`, `TypeDef`, and `TypeSpec`. The classes dnlib use are called the same. These three classes all implement `ITypeDefOrRef`. -There's also type signature classes. The base class is `TypeSig`. You'll find -`TypeSig`s in method signatures (return type and parameter types) and locals. -The `TypeSpec` class also has a `TypeSig` property. +There's also type signature classes. The base class is `TypeSig`. You'll find `TypeSig`s in method signatures (return type and parameter types) and locals. The `TypeSpec` class also has a `TypeSig` property. All of these types implement `IType`. `TypeRef` is a reference to a type in (usually) another assembly. -`TypeDef` is a type definition and it's a type defined in some module. This -class does *not* derive from `TypeRef`. :) +`TypeDef` is a type definition and it's a type defined in some module. This class does *not* derive from `TypeRef`. :) `TypeSpec` can be a generic type, an array type, etc. -`TypeSig` is the base class of all type signatures (found in method sigs and -locals). It has a `Next` property that points to the next `TypeSig`. Eg. a -Byte[] would first contain a `SZArraySig`, and its `Next` property would point -to Byte signature. +`TypeSig` is the base class of all type signatures (found in method sigs and locals). It has a `Next` property that points to the next `TypeSig`. Eg. a Byte[] would first contain a `SZArraySig`, and its `Next` property would point to Byte signature. -`CorLibTypeSig` is a simple corlib type. You don't create these directly. Use -eg. `module.CorLibTypes.Int32` to get a System.Int32 type signature. +`CorLibTypeSig` is a simple corlib type. You don't create these directly. Use eg. `module.CorLibTypes.Int32` to get a System.Int32 type signature. `ValueTypeSig` is used when the next class is a value type. `ClassSig` is used when the next class is a reference type. -`GenericInstSig` is a generic instance type. It has a reference to the generic -type (a `TypeDef` or a `TypeRef`) and the generic arguments. +`GenericInstSig` is a generic instance type. It has a reference to the generic type (a `TypeDef` or a `TypeRef`) and the generic arguments. `PtrSig` is a pointer sig. `ByRefSig` is a by reference type. -`ArraySig` is a multi-dimensional array type. Most likely when you create an -array, you should use `SZArraySig`, and *not* `ArraySig`. +`ArraySig` is a multi-dimensional array type. Most likely when you create an array, you should use `SZArraySig`, and *not* `ArraySig`. -`SZArraySig` is a single dimension, zero lower bound array. In C#, a `byte[]` -is a `SZArraySig`, and *not* an `ArraySig`. +`SZArraySig` is a single dimension, zero lower bound array. In C#, a `byte[]` is a `SZArraySig`, and *not* an `ArraySig`. `GenericVar` is a generic type variable. `GenericMVar` is a generic method variable. -Some examples if you're not used to the way type signatures are represented -in metadata: +Some examples if you're not used to the way type signatures are represented in metadata: ```C# ModuleDef mod = ....; @@ -374,8 +343,7 @@ in metadata: SZArraySig array5 = new SZArraySig(new ClassSig(stream)); ``` -Sometimes you must convert an `ITypeDefOrRef` (`TypeRef`, `TypeDef`, or -`TypeSpec`) to/from a `TypeSig`. There's extension methods you can use: +Sometimes you must convert an `ITypeDefOrRef` (`TypeRef`, `TypeDef`, or `TypeSpec`) to/from a `TypeSig`. There's extension methods you can use: ```C# // array5 is defined above @@ -386,22 +354,9 @@ Sometimes you must convert an `ITypeDefOrRef` (`TypeRef`, `TypeDef`, or Naming conventions of metadata table classes -------------------------------------------- -For most tables in the metadata, there's a corresponding dnlib class with the -exact same or a similar name. Eg. the metadata has a `TypeDef` table, and dnlib -has a `TypeDef` class. Some tables don't have a class because they're -referenced by other classes, and that information is part of some other class. -Eg. the `TypeDef` class contains all its properties and events, even though the -`TypeDef` table has no property or event column. - -For each of these table classes, there's an abstract base class, and two sub -classes. These sub classes are named the same as the base class but ends in -either `MD` (for classes created from the metadata) or `User` (for classes -created by the user). Eg. `TypeDef` is the base class, and it has two sub -classes `TypeDefMD` which is auto-created from metadata, and `TypeRefUser` -which is created by the user when adding user types. Most of the XyzMD classes -are internal and can't be referenced directly by the user. They're created by -`ModuleDefMD` (which is the only public `MD` class). All XyzUser classes are -public. +For most tables in the metadata, there's a corresponding dnlib class with the exact same or a similar name. Eg. the metadata has a `TypeDef` table, and dnlib has a `TypeDef` class. Some tables don't have a class because they're referenced by other classes, and that information is part of some other class. Eg. the `TypeDef` class contains all its properties and events, even though the `TypeDef` table has no property or event column. + +For each of these table classes, there's an abstract base class, and two sub classes. These sub classes are named the same as the base class but ends in either `MD` (for classes created from the metadata) or `User` (for classes created by the user). Eg. `TypeDef` is the base class, and it has two sub classes `TypeDefMD` which is auto-created from metadata, and `TypeRefUser` which is created by the user when adding user types. Most of the XyzMD classes are internal and can't be referenced directly by the user. They're created by `ModuleDefMD` (which is the only public `MD` class). All XyzUser classes are public. Metadata table classes ---------------------- @@ -418,23 +373,19 @@ Here's a list of the most common metadata table classes `GenericParam` is a generic parameter (owned by a `MethodDef` or a `TypeDef`) -`MemberRef` is what you create if you need a field reference or a method -reference. +`MemberRef` is what you create if you need a field reference or a method reference. -`MethodDef` is a method definition. It usually has a `CilBody` with CIL -instructions. Owned by a `TypeDef`. +`MethodDef` is a method definition. It usually has a `CilBody` with CIL instructions. Owned by a `TypeDef`. `MethodSpec` is a instantiated generic method. -`ModuleDef` is the base module class. When you read an existing module, a -`ModuleDefMD` is created. +`ModuleDef` is the base module class. When you read an existing module, a `ModuleDefMD` is created. `ModuleRef` is a module reference. `PropertyDef` is a property definition. Owned by a `TypeDef`. -`TypeDef` is a type definition. It contains a lot of interesting stuff, -including methods, fields, properties, etc. +`TypeDef` is a type definition. It contains a lot of interesting stuff, including methods, fields, properties, etc. `TypeRef` is a type reference. Usually to a type in another assembly. @@ -443,29 +394,21 @@ including methods, fields, properties, etc. Method classes -------------- -The following are the method classes: `MethodDef`, `MemberRef` (method ref) and -`MethodSpec`. They all implement `IMethod`. +The following are the method classes: `MethodDef`, `MemberRef` (method ref) and `MethodSpec`. They all implement `IMethod`. Field classes ------------- -The following are the field classes: `FieldDef` and `MemberRef` (field ref). -They both implement `IField`. +The following are the field classes: `FieldDef` and `MemberRef` (field ref). They both implement `IField`. Comparing types, methods, fields, etc ------------------------------------- -dnlib has a `SigComparer` class that can compare any type with any other type. -Any method with any other method, etc. It also has several pre-created -`IEqualityComparer` classes (eg. `TypeEqualityComparer`, -`FieldEqualityComparer`, etc) which you can use if you intend to eg. use a type -as a key in a `Dictionary`. +dnlib has a `SigComparer` class that can compare any type with any other type. Any method with any other method, etc. It also has several pre-created `IEqualityComparer` classes (eg. `TypeEqualityComparer`, `FieldEqualityComparer`, etc) which you can use if you intend to eg. use a type as a key in a `Dictionary`. -The `SigComparer` class can also compare types with `System.Type`, methods with -`System.Reflection.MethodBase`, etc. +The `SigComparer` class can also compare types with `System.Type`, methods with `System.Reflection.MethodBase`, etc. -It has many options you can set, see `SigComparerOptions`. The default options -is usually good enough, though. +It has many options you can set, see `SigComparerOptions`. The default options is usually good enough, though. ```C# // Compare two types @@ -490,12 +433,9 @@ It has many `Equals()` and `GetHashCode()` overloads. .NET Resources -------------- -There's three types of .NET resource, and they all derive from the common base -class `Resource`. `ModuleDef.Resources` is a list of all resources the module -owns. +There's three types of .NET resource, and they all derive from the common base class `Resource`. `ModuleDef.Resources` is a list of all resources the module owns. -`EmbeddedResource` is a resource that has data embedded in the owner module. -This is the most common type of resource and it's probably what you want. +`EmbeddedResource` is a resource that has data embedded in the owner module. This is the most common type of resource and it's probably what you want. `AssemblyLinkedResource` is a reference to a resource in another assembly. @@ -504,27 +444,19 @@ This is the most common type of resource and it's probably what you want. Win32 resources --------------- -`ModuleDef.Win32Resources` can be null or a `Win32Resources` instance. You can -add/remove any Win32 resource blob. dnlib doesn't try to parse these blobs. +`ModuleDef.Win32Resources` can be null or a `Win32Resources` instance. You can add/remove any Win32 resource blob. dnlib doesn't try to parse these blobs. Parsing method bodies --------------------- -This is usually only needed if you have decrypted a method body. If it's a -standard method body, you can use `MethodBodyReader.Create()`. If it's similar -to a standard method body, you can derive a class from `MethodBodyReaderBase` -and override the necessary methods. +This is usually only needed if you have decrypted a method body. If it's a standard method body, you can use `MethodBodyReader.Create()`. If it's similar to a standard method body, you can derive a class from `MethodBodyReaderBase` and override the necessary methods. Resolving references -------------------- -`TypeRef.Resolve()` and `MemberRef.Resolve()` both use -`module.Context.Resolver` to resolve the type, field or method. The custom -attribute parser code may also resolve type references. +`TypeRef.Resolve()` and `MemberRef.Resolve()` both use `module.Context.Resolver` to resolve the type, field or method. The custom attribute parser code may also resolve type references. -If you call `Resolve()` or read custom attributes, you should initialize -module.Context to a `ModuleContext`. It should normally be shared between all -modules you open. +If you call `Resolve()` or read custom attributes, you should initialize module.Context to a `ModuleContext`. It should normally be shared between all modules you open. ```C# // You should pass this context to ModuleDefMD.Load(), but you can also write @@ -539,8 +471,7 @@ modules you open. asmResolver.EnableTypeDefCache = true; ``` -All assemblies that you yourself open should be added to the assembly resolver -cache. +All assemblies that you yourself open should be added to the assembly resolver cache. ```C# ModuleDefMD mod = ModuleDefMD.Load(...); @@ -552,15 +483,12 @@ cache. Resolving types, methods, etc from metadata tokens -------------------------------------------------- -`ModuleDefMD` has several `ResolveXXX()` methods, eg. `ResolveTypeDef()`, -`ResolveMethod()`, etc. +`ModuleDefMD` has several `ResolveXXX()` methods, eg. `ResolveTypeDef()`, `ResolveMethod()`, etc. Creating mscorlib type references --------------------------------- -Every module has a `CorLibTypes` property. It has references to a few of the -simplest types such as all integer types, floating point types, Object, String, -etc. If you need a type that's not there, you must create it yourself, eg.: +Every module has a `CorLibTypes` property. It has references to a few of the simplest types such as all integer types, floating point types, Object, String, etc. If you need a type that's not there, you must create it yourself, eg.: ```C# TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef); @@ -569,8 +497,7 @@ etc. If you need a type that's not there, you must create it yourself, eg.: Importing runtime types, methods, fields ---------------------------------------- -To import a `System.Type`, `System.Reflection.MethodInfo`, -`System.Reflection.FieldInfo`, etc into a module, use the `Importer` class. +To import a `System.Type`, `System.Reflection.MethodInfo`, `System.Reflection.FieldInfo`, etc into a module, use the `Importer` class. ```C# Importer importer = new Importer(mod); @@ -580,32 +507,21 @@ To import a `System.Type`, `System.Reflection.MethodInfo`, You can also use it to import types, methods etc from another `ModuleDef`. -All imported types, methods etc will be references to the original assembly. -I.e., it won't add the imported `TypeDef` to the target module. It will just -create a `TypeRef` to it. +All imported types, methods etc will be references to the original assembly. I.e., it won't add the imported `TypeDef` to the target module. It will just create a `TypeRef` to it. Using decrypted methods ----------------------- -If `ModuleDefMD.MethodDecrypter` is initialized, `ModuleDefMD` will call it and -check whether the method has been decrypted. If it has, it calls -`IMethodDecrypter.GetMethodBody()` which you should implement. Return the new -`MethodBody`. `GetMethodBody()` should usually call `MethodBodyReader.Create()` -which does the actual parsing of the CIL code. +If `ModuleDefMD.MethodDecrypter` is initialized, `ModuleDefMD` will call it and check whether the method has been decrypted. If it has, it calls `IMethodDecrypter.GetMethodBody()` which you should implement. Return the new `MethodBody`. `GetMethodBody()` should usually call `MethodBodyReader.Create()` which does the actual parsing of the CIL code. -It's also possible to override `ModuleDefMD.ReadUserString()`. This method is -called by the CIL parser when it finds a `Ldstr` instruction. If -`ModuleDefMD.StringDecrypter` is not null, its `ReadUserString()` method is -called with the string token. Return the decrypted string or null if it should -be read from the `#US` heap. +It's also possible to override `ModuleDefMD.ReadUserString()`. This method is called by the CIL parser when it finds a `Ldstr` instruction. If `ModuleDefMD.StringDecrypter` is not null, its `ReadUserString()` method is called with the string token. Return the decrypted string or null if it should be read from the `#US` heap. Low level access to the metadata -------------------------------- The low level classes are in the `dnlib.DotNet.MD` namespace. -Open an existing .NET module/assembly and you get a ModuleDefMD. It has several -properties, eg. `StringsStream` is the #Strings stream. +Open an existing .NET module/assembly and you get a ModuleDefMD. It has several properties, eg. `StringsStream` is the #Strings stream. The `Metadata` property gives you full access to the metadata. From b398460076ef931da3c722d1523ce025156f9fb3 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sun, 20 Oct 2019 13:37:31 +0200 Subject: [PATCH 350/511] Update XML doc comment --- src/DotNet/Writer/Metadata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 110b5b87f..222cbf30f 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -187,7 +187,7 @@ public enum MetadataFlags : uint { ///
/// This is disabled by default. It's safe to enable if the reference core assembly /// is the same as the runtime core assembly (eg. it's mscorlib.dll and .NET Framework, - /// but not .NET Core). + /// but not .NET Core / .NET Standard). ///
OptimizeCustomAttributeSerializedTypeNames = 0x1000000, } From 5b870f6b5e064943b9db6914c909fd2a7bf67e38 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 21 Oct 2019 17:46:40 +0200 Subject: [PATCH 351/511] Remove duplicate (case insensitive comparison) enum value (PowerShell issue) --- src/DotNet/MethodAttributes.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DotNet/MethodAttributes.cs b/src/DotNet/MethodAttributes.cs index abd7a3c8f..3c66de82e 100644 --- a/src/DotNet/MethodAttributes.cs +++ b/src/DotNet/MethodAttributes.cs @@ -52,8 +52,6 @@ public enum MethodAttributes : ushort { /// Implementation is forwarded through pinvoke. PinvokeImpl = 0x2000, - /// Implementation is forwarded through pinvoke. - PInvokeImpl = PinvokeImpl, /// Managed method exported via thunk to unmanaged code. UnmanagedExport = 0x0008, From ff449af663f5f14865e2cb50e530bfc49520a014 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Tue, 22 Oct 2019 02:50:48 +0200 Subject: [PATCH 352/511] Update corlib ref detection --- src/DotNet/ModuleDefMD.cs | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 18e99c734..6eed7a779 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -560,6 +560,12 @@ void Initialize() { { "mscorlib, Version=3.5.0.0, Culture=neutral, PublicKeyToken=969db8053d3322ac", 60 }, { "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=969db8053d3322ac", 50 }, }; + static readonly string[] corlibs = new string[] { + "System.Private.CoreLib", + "System.Runtime", + "netstandard", + "mscorlib", + }; /// /// Finds a mscorlib @@ -582,25 +588,17 @@ AssemblyRef FindCorLibAssemblyRef() { if (!(corLibAsmRef is null)) return corLibAsmRef; - for (uint i = 1; i <= numAsmRefs; i++) { - var asmRef = ResolveAssemblyRef(i); - if (!UTF8String.ToSystemStringOrEmpty(asmRef.Name).Equals("netstandard", StringComparison.OrdinalIgnoreCase)) - continue; - if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) - corLibAsmRef = asmRef; - } - if (!(corLibAsmRef is null)) - return corLibAsmRef; - - for (uint i = 1; i <= numAsmRefs; i++) { - var asmRef = ResolveAssemblyRef(i); - if (!UTF8String.ToSystemStringOrEmpty(asmRef.Name).Equals("mscorlib", StringComparison.OrdinalIgnoreCase)) - continue; - if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) - corLibAsmRef = asmRef; + foreach (var corlib in corlibs) { + for (uint i = 1; i <= numAsmRefs; i++) { + var asmRef = ResolveAssemblyRef(i); + if (!UTF8String.ToSystemStringOrEmpty(asmRef.Name).Equals(corlib, StringComparison.OrdinalIgnoreCase)) + continue; + if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) + corLibAsmRef = asmRef; + } + if (!(corLibAsmRef is null)) + return corLibAsmRef; } - if (!(corLibAsmRef is null)) - return corLibAsmRef; // If we've loaded mscorlib itself, it won't have any AssemblyRefs to itself. var asm = Assembly; From a0b58a65c8d21ca14c79a8f6bf06b478e324e19c Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 25 Oct 2019 18:28:56 +0200 Subject: [PATCH 353/511] Resolve the token using the module, closes #316 --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index a0bfd7143..ee7c28dde 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -489,12 +489,11 @@ object Resolve(uint index) { ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) return null; - uint rid = MDToken.ToRID(token); switch (MDToken.ToTable(token)) { case Table.TypeDef: case Table.TypeRef: case Table.TypeSpec: - return ImportType(rid); + return module.ResolveToken(token) as ITypeDefOrRef; } return null; } From ec315263da87db182a84a4ccce900fed0812552a Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Tue, 29 Oct 2019 22:40:07 +0100 Subject: [PATCH 354/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 3e25ff975..74d862295 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.2.0 + 3.3.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From b8205cc3dafa914fda3976a81f4cfc4c4ea90c86 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 4 Nov 2019 18:50:50 +0100 Subject: [PATCH 355/511] Add FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..13baf3933 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [0xd4d] From a6a84f3e16814c6e14c554448852a6020d60c119 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 13 Nov 2019 17:17:10 +0100 Subject: [PATCH 356/511] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 13baf3933..2ef0ceb55 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: [0xd4d] +github: "0xd4d" From bc68fbb09a478a7148b68ee4a8c8c794c55b7afe Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 30 Nov 2019 02:34:11 +0100 Subject: [PATCH 357/511] Update sourcelink --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 74d862295..cfd1e1097 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -53,7 +53,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + From 6564f90dba594a52a2a0cfec1b799e8aa2d52ec8 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Tue, 3 Dec 2019 20:32:02 +0100 Subject: [PATCH 358/511] Update package refs --- src/dnlib.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index cfd1e1097..d2086d89e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -52,13 +52,13 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - + - - + + From ebd05857387bd1f754b8e07c5e0ee16dc50a72b6 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Fri, 6 Dec 2019 23:02:55 +0800 Subject: [PATCH 359/511] Add more extension methods (#328) --- src/DotNet/ICodedToken.cs | 22 ++++++++++++++++++++++ src/DotNet/TypeSig.cs | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index 621ce6fb8..cbe8cf75e 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -585,6 +585,28 @@ static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { return null; } + + /// + /// Gets the normal visible parameters, doesn't include the hidden 'this' parameter + /// + /// this + /// The normal visible parameters + public static IList GetParams(this IMethod method) => method?.MethodSig.GetParams(); + + /// + /// Gets the normal visible parameter count, doesn't include the hidden 'this' parameter + /// + /// this + /// Normal visible parameter count + public static int GetParamCount(this IMethod method) => method?.MethodSig.GetParamCount() ?? 0; + + /// + /// Gets a normal visible parameter, doesn't include the hidden 'this' parameter + /// + /// this + /// Normal visible parameter index + /// + public static TypeSig GetParam(this IMethod method, int index) => method?.MethodSig?.Params?[index]; } /// diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index e91da4587..d83af1569 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -436,6 +436,13 @@ public static TypeSig RemovePinnedAndModifiers(this TypeSig a) { /// Namespace of the type public static string GetNamespace(this TypeSig a) => a is null ? string.Empty : a.Namespace; + /// + /// Returns the if it is a . + /// + /// this + /// A or null if none found + public static ITypeDefOrRef TryGetTypeDefOrRef(this TypeSig a) => (a.RemovePinnedAndModifiers() as TypeDefOrRefSig)?.TypeDefOrRef; + /// /// Returns the if it is a . /// From b5b4ef40bdbd6f22096182456eb85a896704fffb Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 6 Dec 2019 16:04:20 +0100 Subject: [PATCH 360/511] Remove ? --- src/DotNet/ICodedToken.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index cbe8cf75e..c6868430c 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -606,7 +606,7 @@ static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { /// this /// Normal visible parameter index /// - public static TypeSig GetParam(this IMethod method, int index) => method?.MethodSig?.Params?[index]; + public static TypeSig GetParam(this IMethod method, int index) => method?.MethodSig?.Params[index]; } /// From 8ea0a5672f29fcb79831981dddcd8fa7d3e27ef2 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 25 Dec 2019 13:09:27 +0100 Subject: [PATCH 361/511] Prevent a TypeSpec ref loop, closes #331 --- src/DotNet/GenericParamConstraint.cs | 4 +++- src/DotNet/IType.cs | 3 +++ src/DotNet/InterfaceImpl.cs | 4 +++- src/DotNet/MemberRef.cs | 4 +++- src/DotNet/MethodSpec.cs | 4 +++- src/DotNet/SignatureReader.cs | 19 +++++++++---------- src/DotNet/StandAloneSig.cs | 2 +- src/DotNet/TypeHelper.cs | 1 - src/DotNet/TypeSpec.cs | 4 +++- src/Utils/SimpleLazyList.cs | 2 +- 10 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/DotNet/GenericParamConstraint.cs b/src/DotNet/GenericParamConstraint.cs index 9b340cb14..1611a4bf1 100644 --- a/src/DotNet/GenericParamConstraint.cs +++ b/src/DotNet/GenericParamConstraint.cs @@ -113,7 +113,7 @@ public GenericParamConstraintUser() { /// /// Created from a row in the GenericParamConstraint table /// - sealed class GenericParamConstraintMD : GenericParamConstraint, IMDTokenProviderMD { + sealed class GenericParamConstraintMD : GenericParamConstraint, IMDTokenProviderMD, IContainsGenericParameter2 { /// The module where this instance is located readonly ModuleDefMD readerModule; @@ -123,6 +123,8 @@ sealed class GenericParamConstraintMD : GenericParamConstraint, IMDTokenProvider /// public uint OrigRid => origRid; + bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); + /// protected override void InitializeCustomAttributes() { var list = readerModule.Metadata.GetCustomAttributeRidList(Table.GenericParamConstraint, origRid); diff --git a/src/DotNet/IType.cs b/src/DotNet/IType.cs index 5f81b50a3..7a1dda756 100644 --- a/src/DotNet/IType.cs +++ b/src/DotNet/IType.cs @@ -80,6 +80,9 @@ public interface IContainsGenericParameter { /// bool ContainsGenericParameter { get; } } + interface IContainsGenericParameter2 { + bool ContainsGenericParameter { get; } + } public static partial class Extensions { /// diff --git a/src/DotNet/InterfaceImpl.cs b/src/DotNet/InterfaceImpl.cs index 3ab5af660..a326c7a9c 100644 --- a/src/DotNet/InterfaceImpl.cs +++ b/src/DotNet/InterfaceImpl.cs @@ -104,7 +104,7 @@ public InterfaceImplUser() { /// /// Created from a row in the InterfaceImpl table /// - sealed class InterfaceImplMD : InterfaceImpl, IMDTokenProviderMD { + sealed class InterfaceImplMD : InterfaceImpl, IMDTokenProviderMD, IContainsGenericParameter2 { /// The module where this instance is located readonly ModuleDefMD readerModule; @@ -114,6 +114,8 @@ sealed class InterfaceImplMD : InterfaceImpl, IMDTokenProviderMD { /// public uint OrigRid => origRid; + bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); + /// protected override void InitializeCustomAttributes() { var list = readerModule.Metadata.GetCustomAttributeRidList(Table.InterfaceImpl, origRid); diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index d21eccc57..159d7d414 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -440,7 +440,7 @@ public MemberRefUser(ModuleDef module, UTF8String name, MethodSig sig, IMemberRe /// /// Created from a row in the MemberRef table /// - sealed class MemberRefMD : MemberRef, IMDTokenProviderMD { + sealed class MemberRefMD : MemberRef, IMDTokenProviderMD, IContainsGenericParameter2 { /// The module where this instance is located readonly ModuleDefMD readerModule; @@ -450,6 +450,8 @@ sealed class MemberRefMD : MemberRef, IMDTokenProviderMD { /// public uint OrigRid => origRid; + bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); + /// protected override void InitializeCustomAttributes() { var list = readerModule.Metadata.GetCustomAttributeRidList(Table.MemberRef, origRid); diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index 0f612ba54..a064e9636 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -204,7 +204,7 @@ public MethodSpecUser(IMethodDefOrRef method, GenericInstMethodSig sig) { /// /// Created from a row in the MethodSpec table /// - sealed class MethodSpecMD : MethodSpec, IMDTokenProviderMD { + sealed class MethodSpecMD : MethodSpec, IMDTokenProviderMD, IContainsGenericParameter2 { /// The module where this instance is located readonly ModuleDefMD readerModule; @@ -214,6 +214,8 @@ sealed class MethodSpecMD : MethodSpec, IMDTokenProviderMD { /// public uint OrigRid => origRid; + bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); + /// protected override void InitializeCustomAttributes() { var list = readerModule.Metadata.GetCustomAttributeRidList(Table.MethodSpec, origRid); diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 358123908..b6e4b9f2e 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using dnlib.DotNet.MD; using dnlib.IO; namespace dnlib.DotNet { @@ -568,12 +569,12 @@ TypeSig ReadType() { case ElementType.Ptr: result = new PtrSig(ReadType()); break; case ElementType.ByRef: result = new ByRefSig(ReadType()); break; - case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break; - case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break; + case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef(false)); break; + case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef(false)); break; case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break; case ElementType.SZArray: result = new SZArraySig(ReadType()); break; - case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break; - case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break; + case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(true), ReadType()); break; + case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(true), ReadType()); break; case ElementType.Sentinel: result = new SentinelSig(); break; case ElementType.Pinned: result = new PinnedSig(ReadType()); break; @@ -667,14 +668,12 @@ TypeSig ReadType() { return result; } - /// - /// Reads a TypeDefOrRef - /// - /// A instance - ITypeDefOrRef ReadTypeDefOrRef() { + ITypeDefOrRef ReadTypeDefOrRef(bool allowTypeSpec) { if (!reader.TryReadCompressedUInt32(out uint codedToken)) return null; - return helper.ResolveTypeDefOrRef(codedToken, gpContext); + if (!allowTypeSpec && CodedToken.TypeDefOrRef.Decode2(codedToken).Table == Table.TypeSpec) + return null; + return helper.ResolveTypeDefOrRef(codedToken, default); } } } diff --git a/src/DotNet/StandAloneSig.cs b/src/DotNet/StandAloneSig.cs index f733cffc3..84c362577 100644 --- a/src/DotNet/StandAloneSig.cs +++ b/src/DotNet/StandAloneSig.cs @@ -126,7 +126,7 @@ public StandAloneSigUser() { /// /// Created from a row in the StandAloneSig table /// - sealed class StandAloneSigMD : StandAloneSig, IMDTokenProviderMD { + sealed class StandAloneSigMD : StandAloneSig, IMDTokenProviderMD, IContainsGenericParameter2 { /// The module where this instance is located readonly ModuleDefMD readerModule; diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index 04de27173..f520050d4 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -255,7 +255,6 @@ bool ContainsGenericParameterInternal(TypeSig type) { ContainsGenericParameterInternal((type as NonLeafSig).Next); break; - case ElementType.End: case ElementType.R: case ElementType.Internal: diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index 8465edd03..1156d471e 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -277,7 +277,7 @@ public TypeSpecUser(TypeSig typeSig) { /// /// Created from a row in the TypeSpec table /// - sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD { + sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD, IContainsGenericParameter2 { /// The module where this instance is located readonly ModuleDefMD readerModule; @@ -310,6 +310,8 @@ protected override void InitializeCustomDebugInfos() { Interlocked.CompareExchange(ref customDebugInfos, list, null); } + bool IContainsGenericParameter2.ContainsGenericParameter => !gpContext.IsEmpty && ContainsGenericParameter; + /// /// Constructor /// diff --git a/src/Utils/SimpleLazyList.cs b/src/Utils/SimpleLazyList.cs index a71a59d0e..592aaffa9 100644 --- a/src/Utils/SimpleLazyList.cs +++ b/src/Utils/SimpleLazyList.cs @@ -58,7 +58,7 @@ public SimpleLazyList(uint length, Func readElementByRID) { /// /// Any class type [DebuggerDisplay("Count = {Length}")] - sealed class SimpleLazyList2 where T : class, IContainsGenericParameter { + sealed class SimpleLazyList2 where T : class, IContainsGenericParameter2 { [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] readonly T[] elements; [DebuggerBrowsable(DebuggerBrowsableState.Never)] From 4dc2865bdba91d8daca63f5ab724ca160ef9733f Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 25 Dec 2019 13:10:37 +0100 Subject: [PATCH 362/511] Update README --- README.md | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/README.md b/README.md index b43830481..d4976df26 100644 --- a/README.md +++ b/README.md @@ -9,56 +9,6 @@ v3.0 requires VS2019 or later to build it. .NET Core SDK 2.1 or later is also re An [older v2.1 branch](https://github.com/0xd4d/dnlib/tree/v2.1_VS2010) can be used to build with older VS versions. This branch won't get any new updates. -v3.0 breaking changes ---------------------- -- VS2019 is required to compile it -- It targets .NET Framework 3.5 or later and netstandard 2.0 or later (.NET Framework 2.0 and 3.0 aren't supported) -- `*MetaData*` -> `*Metadata*` -- `IMetaData` interface is an abstract class `Metadata` -- `_32Bit*` -> `Bit32*` -- `IAssemblyResolver` only has a `Resolve` method. The other methods are still implemented by the default assembly resolver (`AssemblyResolver`) -- Raw table rows, eg. `RawMethodRow` - - They are immutable structs and the methods to read them have been renamed from eg. `ReadMethodRow` -> `TryReadMethodRow` - - An indexer replaces their `Read()` method - - The `IRawRow` interface has been removed -- The `Constant` table info (`TableInfo`) has an extra padding byte column -- `ModuleWriterOptionsBase.Listener` is obsolete, use the new event `ModuleWriterOptionsBase.WriterEvent` instead -- Module writer events related to the current progress have been removed. Use the new event `ModuleWriterOptionsBase.ProgressUpdated` instead -- `StrongNameKey`, `PublicKey`, `PublicKeyToken` are immutable classes -- `RidList` is a struct -- `IBinaryReader`, `IImageStream` have been removed and replaced with new classes - - `MemoryImageStream` -> `ByteArrayDataReaderFactory` - - It has two static factory methods, `Create` and `CreateReader` - - `BinaryReaderChunk` -> `DataReaderChunk` - - To get a reader, call `CreateReader` on `IPEImage`, `DataReaderFactory`, or #Blob stream - - The reader is a struct called `DataReader` and it's not disposable - - The reader has `Slice` methods to get another reader (replaces the older `Create` methods) - - Since the reader is a struct, pass it by reference to methods if its position should be updated when the method returns - - `DataReader.Position` is now a `uint` and not a `long` so expressions that were `long` could now be `uint` and possibly overflow/underflow - - `reader.Position + 0xFFFFFFFF` - - `reader.Position + someRandomValue` - - `var pos = reader.Position;` <-- `pos` is a `uint` and not a `long` - - `DataReader.Position` only accepts valid values and will throw (an `IOException`) if you set it to an invalid position -- `FileOffset` is `uint`, used to be `long` -- `MethodBodyWriterBase` uses `ArrayWriter` instead of `BinaryWriter` (all virtual methods) -- `ModuleWriter` and `NativeModuleWriter` use `DataWriter` instead of `BinaryWriter` -- The native module writer now tries to fit the new metadata, method bodies, resources and other data in the old locations. This results in smaller files. It can be disabled by creating your own `NativeModuleWriterOptions` -- `MetadataOptions`' `OtherHeaps` and `OtherHeapsEnd` have been removed. Use `CustomHeaps`, `MetadataHeapsAdded` and `PreserveHeapOrder()` instead. -- `Instruction.GetLocal()` returns a local if the instruction is a `ldloca` or `ldloca.s` instruction (it used to return null) -- `ModuleCreationOptions.PdbImplementation` has been removed and replaced with `PdbOptions` -- Renamed - - `ITokenCreator` -> `ITokenProvider` - - `MetadataCreator` -> `MetadataFactory` - - `ResourceDataCreator` -> `ResourceDataFactory` - - `FullNameCreator` -> `FullNameFactory` - -Examples --------- - -All examples use C#, but since it's a .NET library, you can use any .NET language (eg. VB.NET). - -See the Examples project for several examples. - Opening a .NET assembly/module ------------------------------ From 38df36da09832ff870647e9bb451dbc51e97e9b4 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Thu, 26 Dec 2019 13:36:47 +0100 Subject: [PATCH 363/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index d2086d89e..3d30382a9 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.3.0 + 3.3.1 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 0a3c99c2cc873b0178773584a45525e45670161f Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 00:23:53 +0100 Subject: [PATCH 364/511] Format default case --- src/DotNet/Constant.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Constant.cs b/src/DotNet/Constant.cs index 833be0ce7..df67b7d54 100644 --- a/src/DotNet/Constant.cs +++ b/src/DotNet/Constant.cs @@ -91,7 +91,7 @@ static ElementType GetElementType(object value) { case TypeCode.Single: return ElementType.R4; case TypeCode.Double: return ElementType.R8; case TypeCode.String: return ElementType.String; - default: return ElementType.Void; + default: return ElementType.Void; } } } From 7be39093fd46667cccc177747298dbe48de065d9 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 00:24:02 +0100 Subject: [PATCH 365/511] Can't get array lbounds/sizes, assume each dim is 0.., closes #346 --- src/DotNet/Importer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 2fc54e578..bd5cf1109 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -218,8 +218,11 @@ TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { return module.CorLibTypes.IntPtr; case ElementType.Array: - FixSignature = true; // We don't know sizes and lower bounds - return new ArraySig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst), (uint)type.GetArrayRank()); + // We don't know sizes and lower bounds. Assume it's `0..` + var lowerBounds = new int[type.GetArrayRank()]; + var sizes = Array2.Empty(); + FixSignature = true; + return new ArraySig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst), (uint)type.GetArrayRank(), sizes, lowerBounds); case ElementType.GenericInst: var typeGenArgs = type.GetGenericArguments(); From 48f42fc025ae4d0b50cb357589021f920ed71861 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 00:24:09 +0100 Subject: [PATCH 366/511] Update new file offset calculation, #345 --- src/DotNet/Writer/MethodBodyChunks.cs | 6 +++--- src/DotNet/Writer/NativeModuleWriter.cs | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index 3b5c177dc..ef08416c3 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -17,7 +17,7 @@ public sealed class MethodBodyChunks : IChunk { readonly List tinyMethods; readonly List fatMethods; readonly List reusedMethods; - Dictionary rvaToReusedMethod; + readonly Dictionary rvaToReusedMethod; readonly bool shareBodies; FileOffset offset; RVA rva; @@ -116,9 +116,9 @@ public bool Remove(MethodBody methodBody) { return list.Remove(methodBody); } - internal void InitializeReusedMethodBodies(IPEImage peImage, uint fileOffsetDelta) { + internal void InitializeReusedMethodBodies(Func getNewFileOffset) { foreach (var info in reusedMethods) { - var offset = peImage.ToFileOffset(info.RVA) + fileOffsetDelta; + var offset = getNewFileOffset(info.RVA); info.MethodBody.SetOffset(offset, info.RVA); } } diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index 969ed2e01..b0820b073 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -359,6 +359,15 @@ void ReuseIfPossible(PESection section, IReuseChunk chunk, RVA origRva, uint ori reusedChunks.Add(new ReusedChunkInfo(chunk, origRva)); } + FileOffset GetNewFileOffset(RVA rva) { + foreach (var sect in origSections) { + var section = sect.PESection; + if (section.VirtualAddress <= rva && rva < section.VirtualAddress + Math.Max(section.VirtualSize, section.SizeOfRawData)) + return sect.Chunk.FileOffset + (rva - section.VirtualAddress); + } + return (FileOffset)rva; + } + long WriteFile() { bool entryPointIsManagedOrNoEntryPoint = GetEntryPoint(out uint entryPointToken); @@ -435,22 +444,14 @@ long WriteFile() { if (!(extraData is null)) chunks.Add(extraData); + CalculateRvasAndFileOffsets(chunks, 0, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { - uint newSizeOfHeaders = SectionSizes.GetSizeOfHeaders(peImage.ImageNTHeaders.OptionalHeader.FileAlignment, headerLen); - uint oldSizeOfHeaders = peImage.ImageNTHeaders.OptionalHeader.SizeOfHeaders; - if (newSizeOfHeaders < oldSizeOfHeaders) - throw new InvalidOperationException(); - uint fileOffsetDelta = newSizeOfHeaders - oldSizeOfHeaders; - methodBodies.InitializeReusedMethodBodies(peImage, fileOffsetDelta); + methodBodies.InitializeReusedMethodBodies(GetNewFileOffset); foreach (var info in reusedChunks) { - if (fileOffsetDelta == 0 && (info.Chunk == metadata || info.Chunk == win32Resources)) - continue; - var offset = peImage.ToFileOffset(info.RVA) + fileOffsetDelta; + var offset = GetNewFileOffset(info.RVA); info.Chunk.SetOffset(offset, info.RVA); } - metadata.UpdateMethodAndFieldRvas(); } - CalculateRvasAndFileOffsets(chunks, 0, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); metadata.UpdateMethodAndFieldRvas(); foreach (var section in origSections) { if (section.Chunk.RVA != section.PESection.VirtualAddress) From f652a91c019ff1c4d9d53a81fb6f52492e3af0e8 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 09:53:16 +0100 Subject: [PATCH 367/511] Update README.md --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index d4976df26..6c6452df8 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,6 @@ .NET module/assembly reader/writer library -Compiling ---------- - -v3.0 requires VS2019 or later to build it. .NET Core SDK 2.1 or later is also required. See below for breaking changes going from 2.1 to 3.0 - -An [older v2.1 branch](https://github.com/0xd4d/dnlib/tree/v2.1_VS2010) can be used to build with older VS versions. This branch won't get any new updates. - Opening a .NET assembly/module ------------------------------ From b8d5e0b7790cbf65415648ab5c79b49f6a436a6d Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Wed, 11 Mar 2020 21:28:59 +0800 Subject: [PATCH 368/511] Improve IsPinvokeMethod --- src/DotNet/ICodedToken.cs | 7 +++++++ src/DotNet/ImplMap.cs | 28 +++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index c6868430c..036f4e986 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -600,6 +600,13 @@ static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { /// Normal visible parameter count public static int GetParamCount(this IMethod method) => method?.MethodSig.GetParamCount() ?? 0; + /// + /// Checks whether any normal visible parameter exists, doesn't include the hidden 'this' parameter + /// + /// this + /// true if there's at least one normal visible parameter + public static bool HasParams(this IMethod method) => method.GetParamCount() > 0; + /// /// Gets a normal visible parameter, doesn't include the hidden 'this' parameter /// diff --git a/src/DotNet/ImplMap.cs b/src/DotNet/ImplMap.cs index 215f5c830..b49673744 100644 --- a/src/DotNet/ImplMap.cs +++ b/src/DotNet/ImplMap.cs @@ -2,6 +2,8 @@ using System; using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; using dnlib.DotNet.MD; namespace dnlib.DotNet { @@ -205,20 +207,40 @@ public PInvokeAttributes CallConv { /// Name of the DLL /// Name of the function within the DLL /// true if it's the specified P/Invoke method, else false - public bool IsPinvokeMethod(string dllName, string funcName) { + public bool IsPinvokeMethod(string dllName, string funcName) => IsPinvokeMethod(dllName, funcName, IsWindows()); + + /// + /// Checks whether this is a certain P/Invoke method + /// + /// Name of the DLL + /// Name of the function within the DLL + /// Treat as Windows + /// true if it's the specified P/Invoke method, else false + public bool IsPinvokeMethod(string dllName, string funcName, bool treatAsWindows) { if (name != funcName) return false; var mod = module; if (mod is null) return false; - return GetDllName(dllName).Equals(GetDllName(mod.Name), StringComparison.OrdinalIgnoreCase); + return GetDllName(dllName, treatAsWindows).Equals(GetDllName(mod.Name, treatAsWindows), StringComparison.OrdinalIgnoreCase); } - static string GetDllName(string dllName) { + static string GetDllName(string dllName, bool treatAsWindows) { + if (treatAsWindows) + dllName = dllName.TrimEnd(trimChars); if (dllName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) return dllName.Substring(0, dllName.Length - 4); return dllName; } + + static bool IsWindows() => +#if NETSTANDARD + RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#else + Path.DirectorySeparatorChar == '\\' || Path.AltDirectorySeparatorChar == '\\'; +#endif + + static readonly char[] trimChars = { ' ' }; } /// From bc691c41950f1c63975b91bcd2491fdefb80806e Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 16:30:26 +0100 Subject: [PATCH 369/511] Add readonly to DataReader.Slice() --- src/IO/DataReader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 4058c96a3..c6f0bd99a 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -118,7 +118,7 @@ readonly void VerifyState() { /// Start position relative to /// Length of data /// - public DataReader Slice(uint start, uint length) { + public readonly DataReader Slice(uint start, uint length) { if ((ulong)start + length > Length) ThrowInvalidArgument(nameof(length)); return new DataReader(stream, startOffset + start, length); @@ -129,7 +129,7 @@ public DataReader Slice(uint start, uint length) { /// /// Start position relative to /// - public DataReader Slice(uint start) { + public readonly DataReader Slice(uint start) { if (start > Length) ThrowInvalidArgument(nameof(start)); return Slice(start, Length - start); @@ -141,7 +141,7 @@ public DataReader Slice(uint start) { /// Start position relative to /// Length of data /// - public DataReader Slice(int start, int length) { + public readonly DataReader Slice(int start, int length) { if (start < 0) ThrowInvalidArgument(nameof(start)); if (length < 0) @@ -154,7 +154,7 @@ public DataReader Slice(int start, int length) { /// /// Start position relative to /// - public DataReader Slice(int start) { + public readonly DataReader Slice(int start) { if (start < 0) ThrowInvalidArgument(nameof(start)); if ((uint)start > Length) From 807986161063800480790c4c719c0b24c3172217 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 16:30:37 +0100 Subject: [PATCH 370/511] Don't include asm type names in attrs by default if the types exist in the current module --- src/DotNet/FullNameFactory.cs | 30 +++++++++++++++++++------ src/DotNet/Writer/DeclSecurityWriter.cs | 2 +- src/DotNet/Writer/MarshalBlobWriter.cs | 2 +- src/DotNet/Writer/Metadata.cs | 7 ++++-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index 6cbd9f698..d7b30afaf 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -42,7 +42,19 @@ public struct FullNameFactory { /// The type (TypeDef, TypeRef or ExportedType) /// or null /// true if the assembly name must be included, false otherwise - public static bool MustUseAssemblyName(ModuleDef module, IType type) { + public static bool MustUseAssemblyName(ModuleDef module, IType type) => MustUseAssemblyName(module, type, true); + + /// + /// Checks whether the assembly name should be included when printing the full name. + /// See for more info. + /// + /// Owner module + /// The type (TypeDef, TypeRef or ExportedType) + /// or null + /// If false, don't add an assembly name if it's a type in , + /// if true, don't add an assembly name if it's a type in or the corlib. + /// true if the assembly name must be included, false otherwise + public static bool MustUseAssemblyName(ModuleDef module, IType type, bool allowCorlib) { if (type is TypeDef td) return td.Module != module; @@ -51,11 +63,15 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type) { return true; if (tr.ResolutionScope == AssemblyRef.CurrentAssembly) return false; - if (!tr.DefinitionAssembly.IsCorLib()) + if (allowCorlib) { + if (!tr.DefinitionAssembly.IsCorLib()) + return true; + // If it's present in this module, but it's a corlib type, then we will need the + // assembly name. + return !(module.Find(tr) is null); + } + else return true; - // If it's present in this module, but it's a corlib type, then we will need the - // assembly name. - return !(module.Find(tr) is null); } /// @@ -1317,8 +1333,8 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { if (!isReflection) { const int NO_LOWER = int.MinValue; const uint NO_SIZE = uint.MaxValue; - int lower = i < arraySig.LowerBounds.Count ? arraySig.LowerBounds[i] : NO_LOWER; - uint size = i < arraySig.Sizes.Count ? arraySig.Sizes[i] : NO_SIZE; + int lower = i < arraySig.LowerBounds.Count ? arraySig.LowerBounds[i] : NO_LOWER; + uint size = i < arraySig.Sizes.Count ? arraySig.Sizes[i] : NO_SIZE; if (lower != NO_LOWER) { sb.Append(lower); sb.Append(".."); diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index f0f48e910..56b978e42 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -103,6 +103,6 @@ byte[] WriteFormat2(IList secAttrs) { void Write(DataWriter writer, UTF8String s) => writer.Write(helper, s); void IWriterError.Error(string message) => helper.Error(message); bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => - !optimizeCustomAttributeSerializedTypeNames || FullNameFactory.MustUseAssemblyName(module, type); + FullNameFactory.MustUseAssemblyName(module, type, optimizeCustomAttributeSerializedTypeNames); } } diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 75617a09f..9ad8caa8d 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -146,6 +146,6 @@ bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { public void Dispose() => outStream?.Dispose(); bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => - !optimizeCustomAttributeSerializedTypeNames || FullNameFactory.MustUseAssemblyName(module, type); + FullNameFactory.MustUseAssemblyName(module, type, optimizeCustomAttributeSerializedTypeNames); } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 222cbf30f..23ec72a5b 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -180,11 +180,14 @@ public enum MetadataFlags : uint { /// /// Serialized type names stored in custom attributes are optimized if the types - /// exist in the current module or in the core library (eg. mscorlib/System.Private.CoreLib). + /// exist in the core library (eg. mscorlib/System.Private.CoreLib). /// Instead of storing type-name + assembly-name, only type-name is stored. This results in /// slightly smaller assemblies. ///
///
+ /// If it's a type in the current module, the type name is optimized and no assembly name is stored in the custom attribute. + ///
+ ///
/// This is disabled by default. It's safe to enable if the reference core assembly /// is the same as the runtime core assembly (eg. it's mscorlib.dll and .NET Framework, /// but not .NET Core / .NET Standard). @@ -3561,7 +3564,7 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdb /// bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => - !OptimizeCustomAttributeSerializedTypeNames || FullNameFactory.MustUseAssemblyName(module, type); + FullNameFactory.MustUseAssemblyName(module, type, OptimizeCustomAttributeSerializedTypeNames); /// /// Called before any other methods From ce7a762916805721639c2ce1a2629ebd221df3ba Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 16:30:48 +0100 Subject: [PATCH 371/511] Use switch expressions --- src/DotNet/AssemblyHash.cs | 40 +- src/DotNet/AssemblyHashAlgorithm.cs | 33 +- src/DotNet/Constant.cs | 32 +- src/DotNet/CustomAttributeReader.cs | 53 +- src/DotNet/Emit/Instruction.cs | 34 +- src/DotNet/Emit/MethodBodyReaderBase.cs | 45 +- src/DotNet/ICorLibTypes.cs | 42 +- src/DotNet/MD/ColumnInfo.cs | 15 +- src/DotNet/MD/DotNetTableSizes.cs | 35 +- src/DotNet/MD/MetadataFactory.cs | 34 +- src/DotNet/MD/RawTableRows.cs | 895 +++++++++------------ src/DotNet/ModuleDefMD.cs | 256 +++--- src/DotNet/WinMDHelpers.cs | 46 +- src/DotNet/Writer/CustomAttributeWriter.cs | 30 +- src/DotNet/Writer/Hasher.cs | 34 +- src/PE/ImageNTHeaders.cs | 10 +- src/PE/PEImage.cs | 13 +- 17 files changed, 716 insertions(+), 931 deletions(-) diff --git a/src/DotNet/AssemblyHash.cs b/src/DotNet/AssemblyHash.cs index 6a926fd5c..af89ba0b0 100644 --- a/src/DotNet/AssemblyHash.cs +++ b/src/DotNet/AssemblyHash.cs @@ -17,38 +17,14 @@ namespace dnlib.DotNet { /// If is an unsupported hash algorithm, then /// will be used as the hash algorithm. /// The algorithm to use - public AssemblyHash(AssemblyHashAlgorithm hashAlgo) { - switch (hashAlgo) { - case AssemblyHashAlgorithm.MD5: - hasher = MD5.Create(); - break; - - case AssemblyHashAlgorithm.None: - case AssemblyHashAlgorithm.MD2: - case AssemblyHashAlgorithm.MD4: - case AssemblyHashAlgorithm.SHA1: - case AssemblyHashAlgorithm.MAC: - case AssemblyHashAlgorithm.SSL3_SHAMD5: - case AssemblyHashAlgorithm.HMAC: - case AssemblyHashAlgorithm.TLS1PRF: - case AssemblyHashAlgorithm.HASH_REPLACE_OWF: - default: - hasher = SHA1.Create(); - break; - - case AssemblyHashAlgorithm.SHA_256: - hasher = SHA256.Create(); - break; - - case AssemblyHashAlgorithm.SHA_384: - hasher = SHA384.Create(); - break; - - case AssemblyHashAlgorithm.SHA_512: - hasher = SHA512.Create(); - break; - } - } + public AssemblyHash(AssemblyHashAlgorithm hashAlgo) => + hasher = hashAlgo switch { + AssemblyHashAlgorithm.MD5 => MD5.Create(), + AssemblyHashAlgorithm.SHA_256 => SHA256.Create(), + AssemblyHashAlgorithm.SHA_384 => SHA384.Create(), + AssemblyHashAlgorithm.SHA_512 => SHA512.Create(), + _ => SHA1.Create(), + }; /// public void Dispose() { diff --git a/src/DotNet/AssemblyHashAlgorithm.cs b/src/DotNet/AssemblyHashAlgorithm.cs index d30217d83..8c5913cc5 100644 --- a/src/DotNet/AssemblyHashAlgorithm.cs +++ b/src/DotNet/AssemblyHashAlgorithm.cs @@ -34,22 +34,21 @@ public enum AssemblyHashAlgorithm : uint { } public static partial class Extensions { - internal static string GetName(this AssemblyHashAlgorithm hashAlg) { - switch (hashAlg) { - case AssemblyHashAlgorithm.MD2: return null; - case AssemblyHashAlgorithm.MD4: return null; - case AssemblyHashAlgorithm.MD5: return "MD5"; - case AssemblyHashAlgorithm.SHA1: return "SHA1"; - case AssemblyHashAlgorithm.MAC: return null; - case AssemblyHashAlgorithm.SSL3_SHAMD5: return null; - case AssemblyHashAlgorithm.HMAC: return null; - case AssemblyHashAlgorithm.TLS1PRF: return null; - case AssemblyHashAlgorithm.HASH_REPLACE_OWF: return null; - case AssemblyHashAlgorithm.SHA_256: return "SHA256"; - case AssemblyHashAlgorithm.SHA_384: return "SHA384"; - case AssemblyHashAlgorithm.SHA_512: return "SHA512"; - default: return null; - } - } + internal static string GetName(this AssemblyHashAlgorithm hashAlg) => + hashAlg switch { + AssemblyHashAlgorithm.MD2 => null, + AssemblyHashAlgorithm.MD4 => null, + AssemblyHashAlgorithm.MD5 => "MD5", + AssemblyHashAlgorithm.SHA1 => "SHA1", + AssemblyHashAlgorithm.MAC => null, + AssemblyHashAlgorithm.SSL3_SHAMD5 => null, + AssemblyHashAlgorithm.HMAC => null, + AssemblyHashAlgorithm.TLS1PRF => null, + AssemblyHashAlgorithm.HASH_REPLACE_OWF => null, + AssemblyHashAlgorithm.SHA_256 => "SHA256", + AssemblyHashAlgorithm.SHA_384 => "SHA384", + AssemblyHashAlgorithm.SHA_512 => "SHA512", + _ => null, + }; } } diff --git a/src/DotNet/Constant.cs b/src/DotNet/Constant.cs index df67b7d54..9d100067d 100644 --- a/src/DotNet/Constant.cs +++ b/src/DotNet/Constant.cs @@ -77,22 +77,22 @@ public ConstantUser(object value, ElementType type) { static ElementType GetElementType(object value) { if (value is null) return ElementType.Class; - switch (System.Type.GetTypeCode(value.GetType())) { - case TypeCode.Boolean: return ElementType.Boolean; - case TypeCode.Char: return ElementType.Char; - case TypeCode.SByte: return ElementType.I1; - case TypeCode.Byte: return ElementType.U1; - case TypeCode.Int16: return ElementType.I2; - case TypeCode.UInt16: return ElementType.U2; - case TypeCode.Int32: return ElementType.I4; - case TypeCode.UInt32: return ElementType.U4; - case TypeCode.Int64: return ElementType.I8; - case TypeCode.UInt64: return ElementType.U8; - case TypeCode.Single: return ElementType.R4; - case TypeCode.Double: return ElementType.R8; - case TypeCode.String: return ElementType.String; - default: return ElementType.Void; - } + return System.Type.GetTypeCode(value.GetType()) switch { + TypeCode.Boolean => ElementType.Boolean, + TypeCode.Char => ElementType.Char, + TypeCode.SByte => ElementType.I1, + TypeCode.Byte => ElementType.U1, + TypeCode.Int16 => ElementType.I2, + TypeCode.UInt16 => ElementType.U2, + TypeCode.Int32 => ElementType.I4, + TypeCode.UInt32 => ElementType.U4, + TypeCode.Int64 => ElementType.I8, + TypeCode.UInt64 => ElementType.U8, + TypeCode.Single => ElementType.R4, + TypeCode.Double => ElementType.R8, + TypeCode.String => ElementType.String, + _ => ElementType.Void, + }; } } diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 98a5f1917..21a56a417 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -542,13 +542,11 @@ CAArgument ReadArrayArgument(SZArraySig arrayType) { } CANamedArgument ReadNamedArgument() { - bool isField; - switch ((SerializationType)reader.ReadByte()) { - case SerializationType.Property:isField = false; break; - case SerializationType.Field: isField = true; break; - default: throw new CABlobParserException("Named argument is not a field/property"); - } - + var isField = (SerializationType)reader.ReadByte() switch { + SerializationType.Property => false, + SerializationType.Field => true, + _ => throw new CABlobParserException("Named argument is not a field/property"), + }; var fieldPropType = ReadFieldOrPropType(); var name = ReadUTF8String(); var argument = ReadFixedArg(fieldPropType); @@ -559,27 +557,26 @@ CANamedArgument ReadNamedArgument() { TypeSig ReadFieldOrPropType() { if (!recursionCounter.Increment()) throw new CABlobParserException("Too much recursion"); - TypeSig result; - switch ((SerializationType)reader.ReadByte()) { - case SerializationType.Boolean: result = module.CorLibTypes.Boolean; break; - case SerializationType.Char: result = module.CorLibTypes.Char; break; - case SerializationType.I1: result = module.CorLibTypes.SByte; break; - case SerializationType.U1: result = module.CorLibTypes.Byte; break; - case SerializationType.I2: result = module.CorLibTypes.Int16; break; - case SerializationType.U2: result = module.CorLibTypes.UInt16; break; - case SerializationType.I4: result = module.CorLibTypes.Int32; break; - case SerializationType.U4: result = module.CorLibTypes.UInt32; break; - case SerializationType.I8: result = module.CorLibTypes.Int64; break; - case SerializationType.U8: result = module.CorLibTypes.UInt64; break; - case SerializationType.R4: result = module.CorLibTypes.Single; break; - case SerializationType.R8: result = module.CorLibTypes.Double; break; - case SerializationType.String: result = module.CorLibTypes.String; break; - case SerializationType.SZArray: result = new SZArraySig(ReadFieldOrPropType()); break; - case SerializationType.Type: result = new ClassSig(module.CorLibTypes.GetTypeRef("System", "Type")); break; - case SerializationType.TaggedObject: result = module.CorLibTypes.Object; break; - case SerializationType.Enum: result = ReadType(false); break; - default: throw new CABlobParserException("Invalid type"); - } + var result = (SerializationType)reader.ReadByte() switch { + SerializationType.Boolean => module.CorLibTypes.Boolean, + SerializationType.Char => module.CorLibTypes.Char, + SerializationType.I1 => module.CorLibTypes.SByte, + SerializationType.U1 => module.CorLibTypes.Byte, + SerializationType.I2 => module.CorLibTypes.Int16, + SerializationType.U2 => module.CorLibTypes.UInt16, + SerializationType.I4 => module.CorLibTypes.Int32, + SerializationType.U4 => module.CorLibTypes.UInt32, + SerializationType.I8 => module.CorLibTypes.Int64, + SerializationType.U8 => module.CorLibTypes.UInt64, + SerializationType.R4 => module.CorLibTypes.Single, + SerializationType.R8 => module.CorLibTypes.Double, + SerializationType.String => module.CorLibTypes.String, + SerializationType.SZArray => new SZArraySig(ReadFieldOrPropType()), + SerializationType.Type => new ClassSig(module.CorLibTypes.GetTypeRef("System", "Type")), + SerializationType.TaggedObject => module.CorLibTypes.Object, + SerializationType.Enum => ReadType(false), + _ => throw new CABlobParserException("Invalid type"), + }; recursionCounter.Decrement(); return result; } diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index af9a56b7f..da35f889e 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -572,24 +572,22 @@ public bool IsLdcI4() { /// The integer value /// isn't one of the /// ldc.i4 opcodes - public int GetLdcI4Value() { - switch (OpCode.Code) { - case Code.Ldc_I4_M1:return -1; - case Code.Ldc_I4_0: return 0; - case Code.Ldc_I4_1: return 1; - case Code.Ldc_I4_2: return 2; - case Code.Ldc_I4_3: return 3; - case Code.Ldc_I4_4: return 4; - case Code.Ldc_I4_5: return 5; - case Code.Ldc_I4_6: return 6; - case Code.Ldc_I4_7: return 7; - case Code.Ldc_I4_8: return 8; - case Code.Ldc_I4_S: return (sbyte)Operand; - case Code.Ldc_I4: return (int)Operand; - default: - throw new InvalidOperationException($"Not a ldc.i4 instruction: {this}"); - } - } + public int GetLdcI4Value() => + OpCode.Code switch { + Code.Ldc_I4_M1 => -1, + Code.Ldc_I4_0 => 0, + Code.Ldc_I4_1 => 1, + Code.Ldc_I4_2 => 2, + Code.Ldc_I4_3 => 3, + Code.Ldc_I4_4 => 4, + Code.Ldc_I4_5 => 5, + Code.Ldc_I4_6 => 6, + Code.Ldc_I4_7 => 7, + Code.Ldc_I4_8 => 8, + Code.Ldc_I4_S => (sbyte)Operand, + Code.Ldc_I4 => (int)Operand, + _ => throw new InvalidOperationException($"Not a ldc.i4 instruction: {this}"), + }; /// /// Checks whether it's one of the ldarg instructions, but does not check diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index 406747130..157f25e8b 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -227,29 +227,28 @@ OpCode ReadOpCode() { /// Reads the instruction operand (if any) /// /// The instruction - object ReadOperand(Instruction instr) { - switch (instr.OpCode.OperandType) { - case OperandType.InlineBrTarget: return ReadInlineBrTarget(instr); - case OperandType.InlineField: return ReadInlineField(instr); - case OperandType.InlineI: return ReadInlineI(instr); - case OperandType.InlineI8: return ReadInlineI8(instr); - case OperandType.InlineMethod: return ReadInlineMethod(instr); - case OperandType.InlineNone: return ReadInlineNone(instr); - case OperandType.InlinePhi: return ReadInlinePhi(instr); - case OperandType.InlineR: return ReadInlineR(instr); - case OperandType.InlineSig: return ReadInlineSig(instr); - case OperandType.InlineString: return ReadInlineString(instr); - case OperandType.InlineSwitch: return ReadInlineSwitch(instr); - case OperandType.InlineTok: return ReadInlineTok(instr); - case OperandType.InlineType: return ReadInlineType(instr); - case OperandType.InlineVar: return ReadInlineVar(instr); - case OperandType.ShortInlineBrTarget: return ReadShortInlineBrTarget(instr); - case OperandType.ShortInlineI: return ReadShortInlineI(instr); - case OperandType.ShortInlineR: return ReadShortInlineR(instr); - case OperandType.ShortInlineVar: return ReadShortInlineVar(instr); - default: throw new InvalidOperationException("Invalid OpCode.OperandType"); - } - } + object ReadOperand(Instruction instr) => + instr.OpCode.OperandType switch { + OperandType.InlineBrTarget => ReadInlineBrTarget(instr), + OperandType.InlineField => ReadInlineField(instr), + OperandType.InlineI => ReadInlineI(instr), + OperandType.InlineI8 => ReadInlineI8(instr), + OperandType.InlineMethod => ReadInlineMethod(instr), + OperandType.InlineNone => ReadInlineNone(instr), + OperandType.InlinePhi => ReadInlinePhi(instr), + OperandType.InlineR => ReadInlineR(instr), + OperandType.InlineSig => ReadInlineSig(instr), + OperandType.InlineString => ReadInlineString(instr), + OperandType.InlineSwitch => ReadInlineSwitch(instr), + OperandType.InlineTok => ReadInlineTok(instr), + OperandType.InlineType => ReadInlineType(instr), + OperandType.InlineVar => ReadInlineVar(instr), + OperandType.ShortInlineBrTarget => ReadShortInlineBrTarget(instr), + OperandType.ShortInlineI => ReadShortInlineI(instr), + OperandType.ShortInlineR => ReadShortInlineR(instr), + OperandType.ShortInlineVar => ReadShortInlineVar(instr), + _ => throw new InvalidOperationException("Invalid OpCode.OperandType"), + }; /// /// Reads a operand diff --git a/src/DotNet/ICorLibTypes.cs b/src/DotNet/ICorLibTypes.cs index 13b4b9ec3..25f7dae31 100644 --- a/src/DotNet/ICorLibTypes.cs +++ b/src/DotNet/ICorLibTypes.cs @@ -160,27 +160,27 @@ public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, string @nam return null; if (defAsm is null || !defAsm.IsCorLib()) return null; - switch (name) { - case "Void": return self.Void; - case "Boolean": return self.Boolean; - case "Char": return self.Char; - case "SByte": return self.SByte; - case "Byte": return self.Byte; - case "Int16": return self.Int16; - case "UInt16": return self.UInt16; - case "Int32": return self.Int32; - case "UInt32": return self.UInt32; - case "Int64": return self.Int64; - case "UInt64": return self.UInt64; - case "Single": return self.Single; - case "Double": return self.Double; - case "String": return self.String; - case "TypedReference": return self.TypedReference; - case "IntPtr": return self.IntPtr; - case "UIntPtr": return self.UIntPtr; - case "Object": return self.Object; - } - return null; + return name switch { + "Void" => self.Void, + "Boolean" => self.Boolean, + "Char" => self.Char, + "SByte" => self.SByte, + "Byte" => self.Byte, + "Int16" => self.Int16, + "UInt16" => self.UInt16, + "Int32" => self.Int32, + "UInt32" => self.UInt32, + "Int64" => self.Int64, + "UInt64" => self.UInt64, + "Single" => self.Single, + "Double" => self.Double, + "String" => self.String, + "TypedReference" => self.TypedReference, + "IntPtr" => self.IntPtr, + "UIntPtr" => self.UIntPtr, + "Object" => self.Object, + _ => null, + }; } } } diff --git a/src/DotNet/MD/ColumnInfo.cs b/src/DotNet/MD/ColumnInfo.cs index 5de5ec797..02c7b6bf4 100644 --- a/src/DotNet/MD/ColumnInfo.cs +++ b/src/DotNet/MD/ColumnInfo.cs @@ -81,14 +81,13 @@ public ColumnInfo(byte index, string name, ColumnSize columnSize, byte offset, b /// /// A reader positioned on this column /// The column value - public uint Read(ref DataReader reader) { - switch (size) { - case 1: return reader.ReadByte(); - case 2: return reader.ReadUInt16(); - case 4: return reader.ReadUInt32(); - default: throw new InvalidOperationException("Invalid column size"); - } - } + public uint Read(ref DataReader reader) => + size switch { + 1 => reader.ReadByte(), + 2 => reader.ReadUInt16(), + 4 => reader.ReadUInt32(), + _ => throw new InvalidOperationException("Invalid column size"), + }; internal uint Unsafe_Read24(ref DataReader reader) { Debug.Assert(size == 2 || size == 4); diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index cea936786..562451079 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -47,24 +47,23 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { return count > 0xFFFF ? 4 : 2; } else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.HasCustomDebugInformation) { - CodedToken info; - switch (columnSize) { - case ColumnSize.TypeDefOrRef: info = CodedToken.TypeDefOrRef; break; - case ColumnSize.HasConstant: info = CodedToken.HasConstant; break; - case ColumnSize.HasCustomAttribute: info = CodedToken.HasCustomAttribute; break; - case ColumnSize.HasFieldMarshal: info = CodedToken.HasFieldMarshal; break; - case ColumnSize.HasDeclSecurity: info = CodedToken.HasDeclSecurity; break; - case ColumnSize.MemberRefParent: info = CodedToken.MemberRefParent; break; - case ColumnSize.HasSemantic: info = CodedToken.HasSemantic; break; - case ColumnSize.MethodDefOrRef: info = CodedToken.MethodDefOrRef; break; - case ColumnSize.MemberForwarded: info = CodedToken.MemberForwarded; break; - case ColumnSize.Implementation: info = CodedToken.Implementation; break; - case ColumnSize.CustomAttributeType:info = CodedToken.CustomAttributeType; break; - case ColumnSize.ResolutionScope: info = CodedToken.ResolutionScope; break; - case ColumnSize.TypeOrMethodDef: info = CodedToken.TypeOrMethodDef; break; - case ColumnSize.HasCustomDebugInformation:info = CodedToken.HasCustomDebugInformation; break; - default: throw new InvalidOperationException($"Invalid ColumnSize: {columnSize}"); - } + var info = columnSize switch { + ColumnSize.TypeDefOrRef => CodedToken.TypeDefOrRef, + ColumnSize.HasConstant => CodedToken.HasConstant, + ColumnSize.HasCustomAttribute => CodedToken.HasCustomAttribute, + ColumnSize.HasFieldMarshal => CodedToken.HasFieldMarshal, + ColumnSize.HasDeclSecurity => CodedToken.HasDeclSecurity, + ColumnSize.MemberRefParent => CodedToken.MemberRefParent, + ColumnSize.HasSemantic => CodedToken.HasSemantic, + ColumnSize.MethodDefOrRef => CodedToken.MethodDefOrRef, + ColumnSize.MemberForwarded => CodedToken.MemberForwarded, + ColumnSize.Implementation => CodedToken.Implementation, + ColumnSize.CustomAttributeType => CodedToken.CustomAttributeType, + ColumnSize.ResolutionScope => CodedToken.ResolutionScope, + ColumnSize.TypeOrMethodDef => CodedToken.TypeOrMethodDef, + ColumnSize.HasCustomDebugInformation => CodedToken.HasCustomDebugInformation, + _ => throw new InvalidOperationException($"Invalid ColumnSize: {columnSize}"), + }; uint maxRows = 0; foreach (var tableType in info.TableTypes) { int index = (int)tableType; diff --git a/src/DotNet/MD/MetadataFactory.cs b/src/DotNet/MD/MetadataFactory.cs index 7f276b2b9..a0820108f 100644 --- a/src/DotNet/MD/MetadataFactory.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -138,18 +138,11 @@ static MetadataBase Create(IPEImage peImage, CLRRuntimeReaderKind runtime, bool } } - switch (GetMetadataType(mdHeader.StreamHeaders, runtime)) { - case MetadataType.Compressed: - md = new CompressedMetadata(peImage, cor20Header, mdHeader, runtime); - break; - - case MetadataType.ENC: - md = new ENCMetadata(peImage, cor20Header, mdHeader, runtime); - break; - - default: - throw new BadImageFormatException("No #~ or #- stream found"); - } + md = GetMetadataType(mdHeader.StreamHeaders, runtime) switch { + MetadataType.Compressed => new CompressedMetadata(peImage, cor20Header, mdHeader, runtime), + MetadataType.ENC => new ENCMetadata(peImage, cor20Header, mdHeader, runtime), + _ => throw new BadImageFormatException("No #~ or #- stream found"), + }; md.Initialize(null); return md; @@ -180,18 +173,11 @@ internal static MetadataBase CreateStandalonePortablePDB(DataReaderFactory mdRea } } - switch (GetMetadataType(mdHeader.StreamHeaders, runtime)) { - case MetadataType.Compressed: - md = new CompressedMetadata(mdHeader, true, runtime); - break; - - case MetadataType.ENC: - md = new ENCMetadata(mdHeader, true, runtime); - break; - - default: - throw new BadImageFormatException("No #~ or #- stream found"); - } + md = GetMetadataType(mdHeader.StreamHeaders, runtime) switch { + MetadataType.Compressed => new CompressedMetadata(mdHeader, true, runtime), + MetadataType.ENC => new ENCMetadata(mdHeader, true, runtime), + _ => throw new BadImageFormatException("No #~ or #- stream found"), + }; md.Initialize(mdReaderFactory); return md; diff --git a/src/DotNet/MD/RawTableRows.cs b/src/DotNet/MD/RawTableRows.cs index fb3f32466..609245723 100644 --- a/src/DotNet/MD/RawTableRows.cs +++ b/src/DotNet/MD/RawTableRows.cs @@ -25,18 +25,15 @@ public RawModuleRow(ushort Generation, uint Name, uint Mvid, uint EncId, uint En /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Generation; - case 1: return Name; - case 2: return Mvid; - case 3: return EncId; - case 4: return EncBaseId; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Generation, + 1 => Name, + 2 => Mvid, + 3 => EncId, + 4 => EncBaseId, + _ => 0, + }; } /// @@ -58,16 +55,13 @@ public RawTypeRefRow(uint ResolutionScope, uint Name, uint Namespace) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return ResolutionScope; - case 1: return Name; - case 2: return Namespace; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => ResolutionScope, + 1 => Name, + 2 => Namespace, + _ => 0, + }; } /// @@ -95,19 +89,16 @@ public RawTypeDefRow(uint Flags, uint Name, uint Namespace, uint Extends, uint F /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Flags; - case 1: return Name; - case 2: return Namespace; - case 3: return Extends; - case 4: return FieldList; - case 5: return MethodList; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Flags, + 1 => Name, + 2 => Namespace, + 3 => Extends, + 4 => FieldList, + 5 => MethodList, + _ => 0, + }; } /// @@ -123,14 +114,11 @@ public readonly struct RawFieldPtrRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Field; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Field, + _ => 0, + }; } /// @@ -152,16 +140,13 @@ public RawFieldRow(ushort Flags, uint Name, uint Signature) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Flags; - case 1: return Name; - case 2: return Signature; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Flags, + 1 => Name, + 2 => Signature, + _ => 0, + }; } /// @@ -177,14 +162,11 @@ public readonly struct RawMethodPtrRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Method; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Method, + _ => 0, + }; } /// @@ -212,19 +194,16 @@ public RawMethodRow(uint RVA, ushort ImplFlags, ushort Flags, uint Name, uint Si /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return RVA; - case 1: return ImplFlags; - case 2: return Flags; - case 3: return Name; - case 4: return Signature; - case 5: return ParamList; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => RVA, + 1 => ImplFlags, + 2 => Flags, + 3 => Name, + 4 => Signature, + 5 => ParamList, + _ => 0, + }; } /// @@ -240,14 +219,11 @@ public readonly struct RawParamPtrRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Param; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Param, + _ => 0, + }; } /// @@ -269,16 +245,13 @@ public RawParamRow(ushort Flags, ushort Sequence, uint Name) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Flags; - case 1: return Sequence; - case 2: return Name; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Flags, + 1 => Sequence, + 2 => Name, + _ => 0, + }; } /// @@ -298,15 +271,12 @@ public RawInterfaceImplRow(uint Class, uint Interface) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Class; - case 1: return Interface; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Class, + 1 => Interface, + _ => 0, + }; } /// @@ -328,16 +298,13 @@ public RawMemberRefRow(uint Class, uint Name, uint Signature) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Class; - case 1: return Name; - case 2: return Signature; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Class, + 1 => Name, + 2 => Signature, + _ => 0, + }; } /// @@ -361,17 +328,14 @@ public RawConstantRow(byte Type, byte Padding, uint Parent, uint Value) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Type; - case 1: return Padding; - case 2: return Parent; - case 3: return Value; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Type, + 1 => Padding, + 2 => Parent, + 3 => Value, + _ => 0, + }; } /// @@ -393,16 +357,13 @@ public RawCustomAttributeRow(uint Parent, uint Type, uint Value) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Parent; - case 1: return Type; - case 2: return Value; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Parent, + 1 => Type, + 2 => Value, + _ => 0, + }; } /// @@ -422,15 +383,12 @@ public RawFieldMarshalRow(uint Parent, uint NativeType) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Parent; - case 1: return NativeType; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Parent, + 1 => NativeType, + _ => 0, + }; } /// @@ -452,16 +410,13 @@ public RawDeclSecurityRow(short Action, uint Parent, uint PermissionSet) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return (uint)(int)Action; - case 1: return Parent; - case 2: return PermissionSet; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => (uint)(int)Action, + 1 => Parent, + 2 => PermissionSet, + _ => 0, + }; } /// @@ -483,16 +438,13 @@ public RawClassLayoutRow(ushort PackingSize, uint ClassSize, uint Parent) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return PackingSize; - case 1: return ClassSize; - case 2: return Parent; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => PackingSize, + 1 => ClassSize, + 2 => Parent, + _ => 0, + }; } /// @@ -512,15 +464,12 @@ public RawFieldLayoutRow(uint OffSet, uint Field) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return OffSet; - case 1: return Field; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => OffSet, + 1 => Field, + _ => 0, + }; } /// @@ -536,14 +485,11 @@ public readonly struct RawStandAloneSigRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Signature; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Signature, + _ => 0, + }; } /// @@ -563,15 +509,12 @@ public RawEventMapRow(uint Parent, uint EventList) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Parent; - case 1: return EventList; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Parent, + 1 => EventList, + _ => 0, + }; } /// @@ -587,14 +530,11 @@ public readonly struct RawEventPtrRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Event; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Event, + _ => 0, + }; } /// @@ -616,16 +556,13 @@ public RawEventRow(ushort EventFlags, uint Name, uint EventType) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return EventFlags; - case 1: return Name; - case 2: return EventType; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => EventFlags, + 1 => Name, + 2 => EventType, + _ => 0, + }; } /// @@ -645,15 +582,12 @@ public RawPropertyMapRow(uint Parent, uint PropertyList) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Parent; - case 1: return PropertyList; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Parent, + 1 => PropertyList, + _ => 0, + }; } /// @@ -669,14 +603,11 @@ public readonly struct RawPropertyPtrRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Property; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Property, + _ => 0, + }; } /// @@ -698,16 +629,13 @@ public RawPropertyRow(ushort PropFlags, uint Name, uint Type) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return PropFlags; - case 1: return Name; - case 2: return Type; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => PropFlags, + 1 => Name, + 2 => Type, + _ => 0, + }; } /// @@ -729,16 +657,13 @@ public RawMethodSemanticsRow(ushort Semantic, uint Method, uint Association) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Semantic; - case 1: return Method; - case 2: return Association; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Semantic, + 1 => Method, + 2 => Association, + _ => 0, + }; } /// @@ -760,16 +685,13 @@ public RawMethodImplRow(uint Class, uint MethodBody, uint MethodDeclaration) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Class; - case 1: return MethodBody; - case 2: return MethodDeclaration; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Class, + 1 => MethodBody, + 2 => MethodDeclaration, + _ => 0, + }; } /// @@ -785,14 +707,11 @@ public readonly struct RawModuleRefRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Name; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Name, + _ => 0, + }; } /// @@ -808,14 +727,11 @@ public readonly struct RawTypeSpecRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Signature; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Signature, + _ => 0, + }; } /// @@ -839,17 +755,14 @@ public RawImplMapRow(ushort MappingFlags, uint MemberForwarded, uint ImportName, /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return MappingFlags; - case 1: return MemberForwarded; - case 2: return ImportName; - case 3: return ImportScope; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => MappingFlags, + 1 => MemberForwarded, + 2 => ImportName, + 3 => ImportScope, + _ => 0, + }; } /// @@ -869,15 +782,12 @@ public RawFieldRVARow(uint RVA, uint Field) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return RVA; - case 1: return Field; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => RVA, + 1 => Field, + _ => 0, + }; } /// @@ -897,15 +807,12 @@ public RawENCLogRow(uint Token, uint FuncCode) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Token; - case 1: return FuncCode; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Token, + 1 => FuncCode, + _ => 0, + }; } /// @@ -921,14 +828,11 @@ public readonly struct RawENCMapRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Token; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Token, + _ => 0, + }; } /// @@ -962,22 +866,19 @@ public RawAssemblyRow(uint HashAlgId, ushort MajorVersion, ushort MinorVersion, /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return HashAlgId; - case 1: return MajorVersion; - case 2: return MinorVersion; - case 3: return BuildNumber; - case 4: return RevisionNumber; - case 5: return Flags; - case 6: return PublicKey; - case 7: return Name; - case 8: return Locale; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => HashAlgId, + 1 => MajorVersion, + 2 => MinorVersion, + 3 => BuildNumber, + 4 => RevisionNumber, + 5 => Flags, + 6 => PublicKey, + 7 => Name, + 8 => Locale, + _ => 0, + }; } /// @@ -993,14 +894,11 @@ public readonly struct RawAssemblyProcessorRow { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Processor; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Processor, + _ => 0, + }; } /// @@ -1022,16 +920,13 @@ public RawAssemblyOSRow(uint OSPlatformId, uint OSMajorVersion, uint OSMinorVers /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return OSPlatformId; - case 1: return OSMajorVersion; - case 2: return OSMinorVersion; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => OSPlatformId, + 1 => OSMajorVersion, + 2 => OSMinorVersion, + _ => 0, + }; } /// @@ -1065,22 +960,19 @@ public RawAssemblyRefRow(ushort MajorVersion, ushort MinorVersion, ushort BuildN /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return MajorVersion; - case 1: return MinorVersion; - case 2: return BuildNumber; - case 3: return RevisionNumber; - case 4: return Flags; - case 5: return PublicKeyOrToken; - case 6: return Name; - case 7: return Locale; - case 8: return HashValue; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => MajorVersion, + 1 => MinorVersion, + 2 => BuildNumber, + 3 => RevisionNumber, + 4 => Flags, + 5 => PublicKeyOrToken, + 6 => Name, + 7 => Locale, + 8 => HashValue, + _ => 0, + }; } /// @@ -1100,15 +992,12 @@ public RawAssemblyRefProcessorRow(uint Processor, uint AssemblyRef) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Processor; - case 1: return AssemblyRef; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Processor, + 1 => AssemblyRef, + _ => 0, + }; } /// @@ -1132,17 +1021,14 @@ public RawAssemblyRefOSRow(uint OSPlatformId, uint OSMajorVersion, uint OSMinorV /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return OSPlatformId; - case 1: return OSMajorVersion; - case 2: return OSMinorVersion; - case 3: return AssemblyRef; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => OSPlatformId, + 1 => OSMajorVersion, + 2 => OSMinorVersion, + 3 => AssemblyRef, + _ => 0, + }; } /// @@ -1164,16 +1050,13 @@ public RawFileRow(uint Flags, uint Name, uint HashValue) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Flags; - case 1: return Name; - case 2: return HashValue; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Flags, + 1 => Name, + 2 => HashValue, + _ => 0, + }; } /// @@ -1199,18 +1082,15 @@ public RawExportedTypeRow(uint Flags, uint TypeDefId, uint TypeName, uint TypeNa /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Flags; - case 1: return TypeDefId; - case 2: return TypeName; - case 3: return TypeNamespace; - case 4: return Implementation; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Flags, + 1 => TypeDefId, + 2 => TypeName, + 3 => TypeNamespace, + 4 => Implementation, + _ => 0, + }; } /// @@ -1234,17 +1114,14 @@ public RawManifestResourceRow(uint Offset, uint Flags, uint Name, uint Implement /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Offset; - case 1: return Flags; - case 2: return Name; - case 3: return Implementation; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Offset, + 1 => Flags, + 2 => Name, + 3 => Implementation, + _ => 0, + }; } /// @@ -1264,15 +1141,12 @@ public RawNestedClassRow(uint NestedClass, uint EnclosingClass) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return NestedClass; - case 1: return EnclosingClass; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => NestedClass, + 1 => EnclosingClass, + _ => 0, + }; } /// @@ -1306,18 +1180,15 @@ public RawGenericParamRow(ushort Number, ushort Flags, uint Owner, uint Name) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Number; - case 1: return Flags; - case 2: return Owner; - case 3: return Name; - case 4: return Kind; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Number, + 1 => Flags, + 2 => Owner, + 3 => Name, + 4 => Kind, + _ => 0, + }; } /// @@ -1337,15 +1208,12 @@ public RawMethodSpecRow(uint Method, uint Instantiation) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Method; - case 1: return Instantiation; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Method, + 1 => Instantiation, + _ => 0, + }; } /// @@ -1365,15 +1233,12 @@ public RawGenericParamConstraintRow(uint Owner, uint Constraint) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Owner; - case 1: return Constraint; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Owner, + 1 => Constraint, + _ => 0, + }; } /// @@ -1397,17 +1262,14 @@ public RawDocumentRow(uint Name, uint HashAlgorithm, uint Hash, uint Language) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Name; - case 1: return HashAlgorithm; - case 2: return Hash; - case 3: return Language; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Name, + 1 => HashAlgorithm, + 2 => Hash, + 3 => Language, + _ => 0, + }; } /// @@ -1427,15 +1289,12 @@ public RawMethodDebugInformationRow(uint Document, uint SequencePoints) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Document; - case 1: return SequencePoints; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Document, + 1 => SequencePoints, + _ => 0, + }; } /// @@ -1463,19 +1322,16 @@ public RawLocalScopeRow(uint Method, uint ImportScope, uint VariableList, uint C /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Method; - case 1: return ImportScope; - case 2: return VariableList; - case 3: return ConstantList; - case 4: return StartOffset; - case 5: return Length; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Method, + 1 => ImportScope, + 2 => VariableList, + 3 => ConstantList, + 4 => StartOffset, + 5 => Length, + _ => 0, + }; } /// @@ -1497,16 +1353,13 @@ public RawLocalVariableRow(ushort Attributes, ushort Index, uint Name) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Attributes; - case 1: return Index; - case 2: return Name; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Attributes, + 1 => Index, + 2 => Name, + _ => 0, + }; } /// @@ -1526,15 +1379,12 @@ public RawLocalConstantRow(uint Name, uint Signature) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Name; - case 1: return Signature; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Name, + 1 => Signature, + _ => 0, + }; } /// @@ -1554,15 +1404,12 @@ public RawImportScopeRow(uint Parent, uint Imports) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Parent; - case 1: return Imports; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Parent, + 1 => Imports, + _ => 0, + }; } /// @@ -1582,15 +1429,12 @@ public RawStateMachineMethodRow(uint MoveNextMethod, uint KickoffMethod) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return MoveNextMethod; - case 1: return KickoffMethod; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => MoveNextMethod, + 1 => KickoffMethod, + _ => 0, + }; } /// @@ -1612,16 +1456,13 @@ public RawCustomDebugInformationRow(uint Parent, uint Kind, uint Value) { /// /// Index of column /// - public uint this[int index] { - get { - switch (index) { - case 0: return Parent; - case 1: return Kind; - case 2: return Value; - default: return 0; - } - } - } + public uint this[int index] => + index switch { + 0 => Parent, + 1 => Kind, + 2 => Value, + _ => 0, + }; } #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 6eed7a779..a35cca3fe 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -497,14 +497,10 @@ ModuleKind GetKind() { if ((peImage.ImageNTHeaders.FileHeader.Characteristics & Characteristics.Dll) != 0) return ModuleKind.Dll; - switch (peImage.ImageNTHeaders.OptionalHeader.Subsystem) { - default: - case Subsystem.WindowsGui: - return ModuleKind.Windows; - - case Subsystem.WindowsCui: - return ModuleKind.Console; - } + return peImage.ImageNTHeaders.OptionalHeader.Subsystem switch { + Subsystem.WindowsCui => ModuleKind.Console, + _ => ModuleKind.Windows, + }; } void Initialize() { @@ -675,34 +671,34 @@ protected override void Dispose(bool disposing) { /// A or null if is invalid public override IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext) { uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Module: return ResolveModule(rid); - case Table.TypeRef: return ResolveTypeRef(rid); - case Table.TypeDef: return ResolveTypeDef(rid); - case Table.Field: return ResolveField(rid); - case Table.Method: return ResolveMethod(rid); - case Table.Param: return ResolveParam(rid); - case Table.InterfaceImpl: return ResolveInterfaceImpl(rid, gpContext); - case Table.MemberRef: return ResolveMemberRef(rid, gpContext); - case Table.Constant: return ResolveConstant(rid); - case Table.DeclSecurity: return ResolveDeclSecurity(rid); - case Table.ClassLayout: return ResolveClassLayout(rid); - case Table.StandAloneSig: return ResolveStandAloneSig(rid, gpContext); - case Table.Event: return ResolveEvent(rid); - case Table.Property: return ResolveProperty(rid); - case Table.ModuleRef: return ResolveModuleRef(rid); - case Table.TypeSpec: return ResolveTypeSpec(rid, gpContext); - case Table.ImplMap: return ResolveImplMap(rid); - case Table.Assembly: return ResolveAssembly(rid); - case Table.AssemblyRef: return ResolveAssemblyRef(rid); - case Table.File: return ResolveFile(rid); - case Table.ExportedType: return ResolveExportedType(rid); - case Table.ManifestResource:return ResolveManifestResource(rid); - case Table.GenericParam: return ResolveGenericParam(rid); - case Table.MethodSpec: return ResolveMethodSpec(rid, gpContext); - case Table.GenericParamConstraint: return ResolveGenericParamConstraint(rid, gpContext); - } - return null; + return MDToken.ToTable(token) switch { + Table.Module => ResolveModule(rid), + Table.TypeRef => ResolveTypeRef(rid), + Table.TypeDef => ResolveTypeDef(rid), + Table.Field => ResolveField(rid), + Table.Method => ResolveMethod(rid), + Table.Param => ResolveParam(rid), + Table.InterfaceImpl => ResolveInterfaceImpl(rid, gpContext), + Table.MemberRef => ResolveMemberRef(rid, gpContext), + Table.Constant => ResolveConstant(rid), + Table.DeclSecurity => ResolveDeclSecurity(rid), + Table.ClassLayout => ResolveClassLayout(rid), + Table.StandAloneSig => ResolveStandAloneSig(rid, gpContext), + Table.Event => ResolveEvent(rid), + Table.Property => ResolveProperty(rid), + Table.ModuleRef => ResolveModuleRef(rid), + Table.TypeSpec => ResolveTypeSpec(rid, gpContext), + Table.ImplMap => ResolveImplMap(rid), + Table.Assembly => ResolveAssembly(rid), + Table.AssemblyRef => ResolveAssemblyRef(rid), + Table.File => ResolveFile(rid), + Table.ExportedType => ResolveExportedType(rid), + Table.ManifestResource => ResolveManifestResource(rid), + Table.GenericParam => ResolveGenericParam(rid), + Table.MethodSpec => ResolveMethodSpec(rid, gpContext), + Table.GenericParamConstraint => ResolveGenericParamConstraint(rid, gpContext), + _ => null, + }; } /// @@ -945,12 +941,12 @@ public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken, GenericParamContext gp if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.TypeDef: return ResolveTypeDef(rid); - case Table.TypeRef: return ResolveTypeRef(rid); - case Table.TypeSpec: return ResolveTypeSpec(rid, gpContext); - } - return null; + return MDToken.ToTable(token) switch { + Table.TypeDef => ResolveTypeDef(rid), + Table.TypeRef => ResolveTypeRef(rid), + Table.TypeSpec => ResolveTypeSpec(rid, gpContext), + _ => null, + }; } /// @@ -962,12 +958,12 @@ public IHasConstant ResolveHasConstant(uint codedToken) { if (!CodedToken.HasConstant.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Field: return ResolveField(rid); - case Table.Param: return ResolveParam(rid); - case Table.Property:return ResolveProperty(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.Field => ResolveField(rid), + Table.Param => ResolveParam(rid), + Table.Property => ResolveProperty(rid), + _ => null, + }; } /// @@ -987,31 +983,31 @@ public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken, GenericPar if (!CodedToken.HasCustomAttribute.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Method: return ResolveMethod(rid); - case Table.Field: return ResolveField(rid); - case Table.TypeRef: return ResolveTypeRef(rid); - case Table.TypeDef: return ResolveTypeDef(rid); - case Table.Param: return ResolveParam(rid); - case Table.InterfaceImpl: return ResolveInterfaceImpl(rid, gpContext); - case Table.MemberRef: return ResolveMemberRef(rid, gpContext); - case Table.Module: return ResolveModule(rid); - case Table.DeclSecurity:return ResolveDeclSecurity(rid); - case Table.Property: return ResolveProperty(rid); - case Table.Event: return ResolveEvent(rid); - case Table.StandAloneSig: return ResolveStandAloneSig(rid, gpContext); - case Table.ModuleRef: return ResolveModuleRef(rid); - case Table.TypeSpec: return ResolveTypeSpec(rid, gpContext); - case Table.Assembly: return ResolveAssembly(rid); - case Table.AssemblyRef: return ResolveAssemblyRef(rid); - case Table.File: return ResolveFile(rid); - case Table.ExportedType:return ResolveExportedType(rid); - case Table.ManifestResource: return ResolveManifestResource(rid); - case Table.GenericParam:return ResolveGenericParam(rid); - case Table.MethodSpec: return ResolveMethodSpec(rid, gpContext); - case Table.GenericParamConstraint: return ResolveGenericParamConstraint(rid, gpContext); - } - return null; + return MDToken.ToTable(token) switch { + Table.Method => ResolveMethod(rid), + Table.Field => ResolveField(rid), + Table.TypeRef => ResolveTypeRef(rid), + Table.TypeDef => ResolveTypeDef(rid), + Table.Param => ResolveParam(rid), + Table.InterfaceImpl => ResolveInterfaceImpl(rid, gpContext), + Table.MemberRef => ResolveMemberRef(rid, gpContext), + Table.Module => ResolveModule(rid), + Table.DeclSecurity => ResolveDeclSecurity(rid), + Table.Property => ResolveProperty(rid), + Table.Event => ResolveEvent(rid), + Table.StandAloneSig => ResolveStandAloneSig(rid, gpContext), + Table.ModuleRef => ResolveModuleRef(rid), + Table.TypeSpec => ResolveTypeSpec(rid, gpContext), + Table.Assembly => ResolveAssembly(rid), + Table.AssemblyRef => ResolveAssemblyRef(rid), + Table.File => ResolveFile(rid), + Table.ExportedType => ResolveExportedType(rid), + Table.ManifestResource => ResolveManifestResource(rid), + Table.GenericParam => ResolveGenericParam(rid), + Table.MethodSpec => ResolveMethodSpec(rid, gpContext), + Table.GenericParamConstraint => ResolveGenericParamConstraint(rid, gpContext), + _ => null, + }; } /// @@ -1023,11 +1019,11 @@ public IHasFieldMarshal ResolveHasFieldMarshal(uint codedToken) { if (!CodedToken.HasFieldMarshal.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Field: return ResolveField(rid); - case Table.Param: return ResolveParam(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.Field => ResolveField(rid), + Table.Param => ResolveParam(rid), + _ => null, + }; } /// @@ -1039,12 +1035,12 @@ public IHasDeclSecurity ResolveHasDeclSecurity(uint codedToken) { if (!CodedToken.HasDeclSecurity.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.TypeDef: return ResolveTypeDef(rid); - case Table.Method: return ResolveMethod(rid); - case Table.Assembly: return ResolveAssembly(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.TypeDef => ResolveTypeDef(rid), + Table.Method => ResolveMethod(rid), + Table.Assembly => ResolveAssembly(rid), + _ => null, + }; } /// @@ -1064,14 +1060,14 @@ public IMemberRefParent ResolveMemberRefParent(uint codedToken, GenericParamCont if (!CodedToken.MemberRefParent.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.TypeDef: return ResolveTypeDef(rid); - case Table.TypeRef: return ResolveTypeRef(rid); - case Table.ModuleRef: return ResolveModuleRef(rid); - case Table.Method: return ResolveMethod(rid); - case Table.TypeSpec: return ResolveTypeSpec(rid, gpContext); - } - return null; + return MDToken.ToTable(token) switch { + Table.TypeDef => ResolveTypeDef(rid), + Table.TypeRef => ResolveTypeRef(rid), + Table.ModuleRef => ResolveModuleRef(rid), + Table.Method => ResolveMethod(rid), + Table.TypeSpec => ResolveTypeSpec(rid, gpContext), + _ => null, + }; } /// @@ -1083,11 +1079,11 @@ public IHasSemantic ResolveHasSemantic(uint codedToken) { if (!CodedToken.HasSemantic.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Event: return ResolveEvent(rid); - case Table.Property: return ResolveProperty(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.Event => ResolveEvent(rid), + Table.Property => ResolveProperty(rid), + _ => null, + }; } /// @@ -1107,11 +1103,11 @@ public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken, GenericParamContex if (!CodedToken.MethodDefOrRef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Method: return ResolveMethod(rid); - case Table.MemberRef: return ResolveMemberRef(rid, gpContext); - } - return null; + return MDToken.ToTable(token) switch { + Table.Method => ResolveMethod(rid), + Table.MemberRef => ResolveMemberRef(rid, gpContext), + _ => null, + }; } /// @@ -1123,11 +1119,11 @@ public IMemberForwarded ResolveMemberForwarded(uint codedToken) { if (!CodedToken.MemberForwarded.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Field: return ResolveField(rid); - case Table.Method: return ResolveMethod(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.Field => ResolveField(rid), + Table.Method => ResolveMethod(rid), + _ => null, + }; } /// @@ -1139,12 +1135,12 @@ public IImplementation ResolveImplementation(uint codedToken) { if (!CodedToken.Implementation.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.File: return ResolveFile(rid); - case Table.AssemblyRef: return ResolveAssemblyRef(rid); - case Table.ExportedType: return ResolveExportedType(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.File => ResolveFile(rid), + Table.AssemblyRef => ResolveAssemblyRef(rid), + Table.ExportedType => ResolveExportedType(rid), + _ => null, + }; } /// @@ -1164,11 +1160,11 @@ public ICustomAttributeType ResolveCustomAttributeType(uint codedToken, GenericP if (!CodedToken.CustomAttributeType.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Method: return ResolveMethod(rid); - case Table.MemberRef: return ResolveMemberRef(rid, gpContext); - } - return null; + return MDToken.ToTable(token) switch { + Table.Method => ResolveMethod(rid), + Table.MemberRef => ResolveMemberRef(rid, gpContext), + _ => null, + }; } /// @@ -1180,13 +1176,13 @@ public IResolutionScope ResolveResolutionScope(uint codedToken) { if (!CodedToken.ResolutionScope.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Module: return ResolveModule(rid); - case Table.ModuleRef: return ResolveModuleRef(rid); - case Table.AssemblyRef: return ResolveAssemblyRef(rid); - case Table.TypeRef: return ResolveTypeRef(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.Module => ResolveModule(rid), + Table.ModuleRef => ResolveModuleRef(rid), + Table.AssemblyRef => ResolveAssemblyRef(rid), + Table.TypeRef => ResolveTypeRef(rid), + _ => null, + }; } /// @@ -1198,11 +1194,11 @@ public ITypeOrMethodDef ResolveTypeOrMethodDef(uint codedToken) { if (!CodedToken.TypeOrMethodDef.Decode(codedToken, out uint token)) return null; uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.TypeDef: return ResolveTypeDef(rid); - case Table.Method: return ResolveMethod(rid); - } - return null; + return MDToken.ToTable(token) switch { + Table.TypeDef => ResolveTypeDef(rid), + Table.Method => ResolveMethod(rid), + _ => null, + }; } /// diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index 6b06b4993..24b820e7e 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -203,18 +203,17 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { // Silverlight uses 5.0.5.0 static bool IsValidMscorlibVersion(Version version) => !(version is null) && (uint)version.Major <= 5; - static UTF8String GetName(ClrAssembly clrAsm) { - switch (clrAsm) { - case ClrAssembly.Mscorlib: return clrAsmName_Mscorlib; - case ClrAssembly.SystemNumericsVectors: return clrAsmName_SystemNumericsVectors; - case ClrAssembly.SystemObjectModel: return clrAsmName_SystemObjectModel; - case ClrAssembly.SystemRuntime: return clrAsmName_SystemRuntime; - case ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime: return clrAsmName_SystemRuntimeInteropServicesWindowsRuntime; - case ClrAssembly.SystemRuntimeWindowsRuntime: return clrAsmName_SystemRuntimeWindowsRuntime; - case ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml: return clrAsmName_SystemRuntimeWindowsRuntimeUIXaml; - default: throw new InvalidOperationException(); - } - } + static UTF8String GetName(ClrAssembly clrAsm) => + clrAsm switch { + ClrAssembly.Mscorlib => clrAsmName_Mscorlib, + ClrAssembly.SystemNumericsVectors => clrAsmName_SystemNumericsVectors, + ClrAssembly.SystemObjectModel => clrAsmName_SystemObjectModel, + ClrAssembly.SystemRuntime => clrAsmName_SystemRuntime, + ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime => clrAsmName_SystemRuntimeInteropServicesWindowsRuntime, + ClrAssembly.SystemRuntimeWindowsRuntime => clrAsmName_SystemRuntimeWindowsRuntime, + ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml => clrAsmName_SystemRuntimeWindowsRuntimeUIXaml, + _ => throw new InvalidOperationException(), + }; static readonly UTF8String clrAsmName_Mscorlib = new UTF8String("mscorlib"); static readonly UTF8String clrAsmName_SystemNumericsVectors = new UTF8String("System.Numerics.Vectors"); static readonly UTF8String clrAsmName_SystemObjectModel = new UTF8String("System.ObjectModel"); @@ -223,18 +222,17 @@ static UTF8String GetName(ClrAssembly clrAsm) { static readonly UTF8String clrAsmName_SystemRuntimeWindowsRuntime = new UTF8String("System.Runtime.WindowsRuntime"); static readonly UTF8String clrAsmName_SystemRuntimeWindowsRuntimeUIXaml = new UTF8String("System.Runtime.WindowsRuntime.UI.Xaml"); - static byte[] GetPublicKeyToken(ClrAssembly clrAsm) { - switch (clrAsm) { - case ClrAssembly.Mscorlib: return neutralPublicKey; - case ClrAssembly.SystemNumericsVectors: return contractPublicKeyToken; - case ClrAssembly.SystemObjectModel: return contractPublicKeyToken; - case ClrAssembly.SystemRuntime: return contractPublicKeyToken; - case ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime: return contractPublicKeyToken; - case ClrAssembly.SystemRuntimeWindowsRuntime: return neutralPublicKey; - case ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml: return neutralPublicKey; - default: throw new InvalidOperationException(); - } - } + static byte[] GetPublicKeyToken(ClrAssembly clrAsm) => + clrAsm switch { + ClrAssembly.Mscorlib => neutralPublicKey, + ClrAssembly.SystemNumericsVectors => contractPublicKeyToken, + ClrAssembly.SystemObjectModel => contractPublicKeyToken, + ClrAssembly.SystemRuntime => contractPublicKeyToken, + ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime => contractPublicKeyToken, + ClrAssembly.SystemRuntimeWindowsRuntime => neutralPublicKey, + ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml => neutralPublicKey, + _ => throw new InvalidOperationException(), + }; static readonly byte[] contractPublicKeyToken = new byte[] { 0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A }; static readonly byte[] neutralPublicKey = new byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }; diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index e8e61cb2f..2a6cd2a75 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -220,21 +220,21 @@ static bool VerifyValue(object o, ElementType etype) { if (o is null) return false; - switch (Type.GetTypeCode(o.GetType())) { - case TypeCode.Boolean: return etype == ElementType.Boolean; - case TypeCode.Char: return etype == ElementType.Char; - case TypeCode.SByte: return etype == ElementType.I1; - case TypeCode.Byte: return etype == ElementType.U1; - case TypeCode.Int16: return etype == ElementType.I2; - case TypeCode.UInt16: return etype == ElementType.U2; - case TypeCode.Int32: return etype == ElementType.I4; - case TypeCode.UInt32: return etype == ElementType.U4; - case TypeCode.Int64: return etype == ElementType.I8; - case TypeCode.UInt64: return etype == ElementType.U8; - case TypeCode.Single: return etype == ElementType.R4; - case TypeCode.Double: return etype == ElementType.R8; - default: return false; - } + return Type.GetTypeCode(o.GetType()) switch { + TypeCode.Boolean => etype == ElementType.Boolean, + TypeCode.Char => etype == ElementType.Char, + TypeCode.SByte => etype == ElementType.I1, + TypeCode.Byte => etype == ElementType.U1, + TypeCode.Int16 => etype == ElementType.I2, + TypeCode.UInt16 => etype == ElementType.U2, + TypeCode.Int32 => etype == ElementType.I4, + TypeCode.UInt32 => etype == ElementType.U4, + TypeCode.Int64 => etype == ElementType.I8, + TypeCode.UInt64 => etype == ElementType.U8, + TypeCode.Single => etype == ElementType.R4, + TypeCode.Double => etype == ElementType.R8, + _ => false, + }; } static ulong ToUInt64(object o) { diff --git a/src/DotNet/Writer/Hasher.cs b/src/DotNet/Writer/Hasher.cs index 2c472e369..ddef9290b 100644 --- a/src/DotNet/Writer/Hasher.cs +++ b/src/DotNet/Writer/Hasher.cs @@ -6,26 +6,24 @@ namespace dnlib.DotNet.Writer { static class Hasher { - static HashAlgorithm CreateHasher(ChecksumAlgorithm checksumAlgorithm) { - switch (checksumAlgorithm) { - case ChecksumAlgorithm.SHA1: return SHA1.Create(); - case ChecksumAlgorithm.SHA256: return SHA256.Create(); - case ChecksumAlgorithm.SHA384: return SHA384.Create(); - case ChecksumAlgorithm.SHA512: return SHA512.Create(); - default: throw new ArgumentOutOfRangeException(nameof(checksumAlgorithm)); - } - } + static HashAlgorithm CreateHasher(ChecksumAlgorithm checksumAlgorithm) => + checksumAlgorithm switch { + ChecksumAlgorithm.SHA1 => SHA1.Create(), + ChecksumAlgorithm.SHA256 => SHA256.Create(), + ChecksumAlgorithm.SHA384 => SHA384.Create(), + ChecksumAlgorithm.SHA512 => SHA512.Create(), + _ => throw new ArgumentOutOfRangeException(nameof(checksumAlgorithm)), + }; - public static string GetChecksumName(ChecksumAlgorithm checksumAlgorithm) { + public static string GetChecksumName(ChecksumAlgorithm checksumAlgorithm) => // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#pdb-checksum-debug-directory-entry-type-19 - switch (checksumAlgorithm) { - case ChecksumAlgorithm.SHA1: return "SHA1"; - case ChecksumAlgorithm.SHA256: return "SHA256"; - case ChecksumAlgorithm.SHA384: return "SHA384"; - case ChecksumAlgorithm.SHA512: return "SHA512"; - default: throw new ArgumentOutOfRangeException(nameof(checksumAlgorithm)); - } - } + checksumAlgorithm switch { + ChecksumAlgorithm.SHA1 => "SHA1", + ChecksumAlgorithm.SHA256 => "SHA256", + ChecksumAlgorithm.SHA384 => "SHA384", + ChecksumAlgorithm.SHA512 => "SHA512", + _ => throw new ArgumentOutOfRangeException(nameof(checksumAlgorithm)), + }; public static bool TryGetChecksumAlgorithm(string checksumName, out ChecksumAlgorithm pdbChecksumAlgorithm, out int checksumSize) { switch (checksumName) { diff --git a/src/PE/ImageNTHeaders.cs b/src/PE/ImageNTHeaders.cs index f397b2157..87404e5f1 100644 --- a/src/PE/ImageNTHeaders.cs +++ b/src/PE/ImageNTHeaders.cs @@ -54,11 +54,11 @@ public ImageNTHeaders(ref DataReader reader, bool verify) { IImageOptionalHeader CreateImageOptionalHeader(ref DataReader reader, bool verify) { ushort magic = reader.ReadUInt16(); reader.Position -= 2; - switch (magic) { - case 0x010B: return new ImageOptionalHeader32(ref reader, imageFileHeader.SizeOfOptionalHeader, verify); - case 0x020B: return new ImageOptionalHeader64(ref reader, imageFileHeader.SizeOfOptionalHeader, verify); - default: throw new BadImageFormatException("Invalid optional header magic"); - } + return magic switch { + 0x010B => new ImageOptionalHeader32(ref reader, imageFileHeader.SizeOfOptionalHeader, verify), + 0x020B => new ImageOptionalHeader64(ref reader, imageFileHeader.SizeOfOptionalHeader, verify), + _ => throw new BadImageFormatException("Invalid optional header magic"), + }; } } } diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index b09aa1a82..3a4048788 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -134,13 +134,12 @@ void Initialize() { #endif } - static IPEType ConvertImageLayout(ImageLayout imageLayout) { - switch (imageLayout) { - case ImageLayout.File: return FileLayout; - case ImageLayout.Memory: return MemoryLayout; - default: throw new ArgumentException("imageLayout"); - } - } + static IPEType ConvertImageLayout(ImageLayout imageLayout) => + imageLayout switch { + ImageLayout.File => FileLayout, + ImageLayout.Memory => MemoryLayout, + _ => throw new ArgumentException("imageLayout"), + }; /// /// Constructor From b97a464047e22985dab790b5f427fc7d88cee00f Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 18 Mar 2020 19:37:25 +0100 Subject: [PATCH 372/511] Update GetRidList() --- src/DotNet/MD/CompressedMetadata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index 97c020970..3bccb2764 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -134,7 +134,7 @@ RidList GetRidList(MDTable tableSource, uint tableSourceRid, int colIndex, MDTab uint lastRid = tableDest.Rows + 1; if (startRid == 0 || startRid >= lastRid) return RidList.Empty; - uint endRid = hasNext ? nextListRid : lastRid; + uint endRid = !hasNext || (nextListRid == 0 && tableSourceRid + 1 == tableSource.Rows && tableDest.Rows == 0xFFFF) ? lastRid : nextListRid; if (endRid < startRid) endRid = startRid; if (endRid > lastRid) From d84c7cc8976e927c5aac54849990cd45c976dfe7 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 20 Mar 2020 18:30:55 +0100 Subject: [PATCH 373/511] Fix Importer when importing FieldInfo/MethodInfo with generic owner, closes #317 --- src/DotNet/Importer.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index bd5cf1109..cc6e07d9b 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -161,12 +161,21 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g } /// - /// Imports a as a + /// Imports a as a . If it's a type that should be + /// the declaring type of a field/method reference, call instead. /// /// The type /// The imported type or null if is invalid public ITypeDefOrRef Import(Type type) => module.UpdateRowId(ImportAsTypeSig(type).ToTypeDefOrRef()); + /// + /// Imports a as a . Should be called if it's the + /// declaring type of a method/field reference. See also + /// + /// The type + /// + public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericTypeDefinition).ToTypeDefOrRef()); + /// /// Imports a as a /// @@ -444,7 +453,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { IMethodDefOrRef method; var origMethod = methodBase.Module.ResolveMethod(methodBase.MetadataToken); if (methodBase.DeclaringType.GetElementType2() == ElementType.GenericInst) - method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), Import(methodBase.DeclaringType))); + method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), ImportDeclaringType(methodBase.DeclaringType))); else method = ImportInternal(origMethod) as IMethodDefOrRef; @@ -464,7 +473,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { parent = GetModuleParent(methodBase.Module); } else - parent = Import(methodBase.DeclaringType); + parent = ImportDeclaringType(methodBase.DeclaringType); if (parent is null) return null; @@ -590,7 +599,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { parent = GetModuleParent(fieldInfo.Module); } else - parent = Import(fieldInfo.DeclaringType); + parent = ImportDeclaringType(fieldInfo.DeclaringType); if (parent is null) return null; From 46b38397167472bbfedce595cd2f232c602a033b Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 20 Mar 2020 18:31:03 +0100 Subject: [PATCH 374/511] Update FindMethod/Field to allow PrivateScope if ref is from same module --- src/DotNet/TypeDef.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 1381f4347..082130437 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -993,7 +993,7 @@ public MethodDef FindMethod(UTF8String name, MethodSig sig, SigComparerOptions o int count = methods.Count; for (int i = 0; i < count; i++) { var method = methods[i]; - if (!allowPrivateScope && method.IsPrivateScope) + if (!allowPrivateScope && method.IsPrivateScope && sourceModule != Module) continue; if (!UTF8String.Equals(method.Name, name)) continue; @@ -1156,7 +1156,7 @@ public FieldDef FindField(UTF8String name, FieldSig sig, SigComparerOptions opti int count = fields.Count; for (int i = 0; i < count; i++) { var field = fields[i]; - if (!allowPrivateScope && field.IsPrivateScope) + if (!allowPrivateScope && field.IsPrivateScope && sourceModule != Module) continue; if (!UTF8String.Equals(field.Name, name)) continue; From e41b5ca2fb152f5db546258df0470343911e5be6 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 20 Mar 2020 18:31:09 +0100 Subject: [PATCH 375/511] Update DynamicMethodBodyReader, closes #298 --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index ee7c28dde..eb22e8910 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -411,8 +411,11 @@ IMethod ImportMethod(uint rid) { if (obj is null) return null; - if (obj is RuntimeMethodHandle) - return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj)); + if (obj is RuntimeMethodHandle) { + // Sometimes it's a generic type but obj != `GenericMethodInfo`, so pass in 'default' and the + // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298 + return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj, default)); + } if (obj.GetType().ToString() == "System.Reflection.Emit.GenericMethodInfo") { var context = (RuntimeTypeHandle)gmiContextFieldInfo.Read(obj); @@ -452,8 +455,11 @@ IField ImportField(uint rid) { if (obj is null) return null; - if (obj is RuntimeFieldHandle) - return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj)); + if (obj is RuntimeFieldHandle) { + // Sometimes it's a generic type but obj != `GenericFieldInfo`, so pass in 'default' and the + // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298 + return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj, default)); + } if (obj.GetType().ToString() == "System.Reflection.Emit.GenericFieldInfo") { var context = (RuntimeTypeHandle)gfiContextFieldInfo.Read(obj); From 5a3927395c4ea7452d1844e74e7f4702dca8775e Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 21 Mar 2020 19:07:47 +0100 Subject: [PATCH 376/511] Add a new DynamicMethodBodyReader option --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 57 +++++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index eb22e8910..920ec824a 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -9,6 +9,24 @@ using dnlib.IO; namespace dnlib.DotNet.Emit { + /// + /// options + /// + [Flags] + public enum DynamicMethodBodyReaderOptions { + /// + /// No option is enabled + /// + None = 0, + + /// + /// Some fields/methods have an unknown declaring type and don't have a context with + /// that information. If this is enabled, the reader will try to guess it but it doesn't + /// always work. If you get an , try enabling this option. + /// + UnknownDeclaringType = 0x00000001, + } + /// /// Reads code from a DynamicMethod /// @@ -48,6 +66,7 @@ public class DynamicMethodBodyReader : MethodBodyReaderBase, ISignatureReaderHel readonly IList ehInfos; readonly byte[] ehHeader; readonly string methodName; + readonly DynamicMethodBodyReaderOptions options; class ReflectionFieldInfo { SR.FieldInfo fieldInfo; @@ -106,7 +125,7 @@ public DynamicMethodBodyReader(ModuleDef module, object obj) /// instance or a DynamicResolver instance. /// Generic parameter context public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext gpContext) - : this(module, obj, new Importer(module, ImporterOptions.TryToUseDefs, gpContext)) { + : this(module, obj, new Importer(module, ImporterOptions.TryToUseDefs, gpContext), DynamicMethodBodyReaderOptions.None) { } /// @@ -117,9 +136,23 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext /// created by DynamicMethod.CreateDelegate(), a DynamicMethod instance, a RTDynamicMethod /// instance or a DynamicResolver instance. /// Importer - public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer) { + public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer) + : this(module, obj, importer, DynamicMethodBodyReaderOptions.None) { + } + + /// + /// Constructor + /// + /// Module that will own the method body + /// This can be one of several supported types: the delegate instance + /// created by DynamicMethod.CreateDelegate(), a DynamicMethod instance, a RTDynamicMethod + /// instance or a DynamicResolver instance. + /// Importer + /// Options + public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, DynamicMethodBodyReaderOptions options) { this.module = module; this.importer = importer; + this.options = options; gpContext = importer.gpContext; methodName = null; @@ -412,9 +445,13 @@ IMethod ImportMethod(uint rid) { return null; if (obj is RuntimeMethodHandle) { - // Sometimes it's a generic type but obj != `GenericMethodInfo`, so pass in 'default' and the - // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298 - return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj, default)); + if ((options & DynamicMethodBodyReaderOptions.UnknownDeclaringType) != 0) { + // Sometimes it's a generic type but obj != `GenericMethodInfo`, so pass in 'default' and the + // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298 + return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj, default)); + } + else + return importer.Import(SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)obj)); } if (obj.GetType().ToString() == "System.Reflection.Emit.GenericMethodInfo") { @@ -456,9 +493,13 @@ IField ImportField(uint rid) { return null; if (obj is RuntimeFieldHandle) { - // Sometimes it's a generic type but obj != `GenericFieldInfo`, so pass in 'default' and the - // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298 - return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj, default)); + if ((options & DynamicMethodBodyReaderOptions.UnknownDeclaringType) != 0) { + // Sometimes it's a generic type but obj != `GenericFieldInfo`, so pass in 'default' and the + // runtime will try to figure out the declaring type. https://github.com/0xd4d/dnlib/issues/298 + return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj, default)); + } + else + return importer.Import(SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)obj)); } if (obj.GetType().ToString() == "System.Reflection.Emit.GenericFieldInfo") { From 2f8ce28ab3f8a3f90191ec0537c4aeb75837db14 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Thu, 16 Apr 2020 17:38:23 +0200 Subject: [PATCH 377/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 3d30382a9..c13d7bf76 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.3.1 + 3.3.2 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 1fbf08009626e14701224b75ba3d5a2181df6d8a Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Thu, 18 Jun 2020 10:21:28 +0200 Subject: [PATCH 378/511] Update docs --- src/DotNet/Writer/MetadataEvent.cs | 2 +- src/DotNet/Writer/ModuleWriterEvent.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/MetadataEvent.cs b/src/DotNet/Writer/MetadataEvent.cs index 63acdd72e..0e9068778 100644 --- a/src/DotNet/Writer/MetadataEvent.cs +++ b/src/DotNet/Writer/MetadataEvent.cs @@ -40,7 +40,7 @@ public enum MetadataEvent { /// /// Most of the tables that should be sorted have been sorted. The CustomAttribute - /// table is still unsorted since it's not been created yet. + /// table is still unsorted since it hasn't been created yet. /// MostTablesSorted, diff --git a/src/DotNet/Writer/ModuleWriterEvent.cs b/src/DotNet/Writer/ModuleWriterEvent.cs index 2845e8f88..ee4dca09f 100644 --- a/src/DotNet/Writer/ModuleWriterEvent.cs +++ b/src/DotNet/Writer/ModuleWriterEvent.cs @@ -67,7 +67,7 @@ public enum ModuleWriterEvent { /// /// Original event: . /// Most of the tables that should be sorted have been sorted. The CustomAttribute - /// table is still unsorted since it's not been created yet. + /// table is still unsorted since it hasn't been created yet. /// MDMostTablesSorted, From f895c9098a9d5f2387304f155bdd843dca062a10 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 20 Jun 2020 20:36:16 +0200 Subject: [PATCH 379/511] Update pkgref --- Examples/Examples.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index a401dde40..cdfb0601a 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -11,7 +11,7 @@ - + From 651e304a2b73aa99e0b4856514e6ac8bd2ef18c0 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 29 Jun 2020 18:49:20 +0200 Subject: [PATCH 380/511] Support Unmanaged call conv --- src/DotNet/CallingConvention.cs | 2 +- src/DotNet/SigComparer.cs | 4 ++-- src/DotNet/SignatureReader.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DotNet/CallingConvention.cs b/src/DotNet/CallingConvention.cs index 1ff69a423..da2d6557c 100644 --- a/src/DotNet/CallingConvention.cs +++ b/src/DotNet/CallingConvention.cs @@ -26,7 +26,7 @@ public enum CallingConvention : byte { LocalSig = 0x7, /// Property = 0x8, - /// + /// Unmanaged calling convention encoded as modopts Unmanaged = 0x9, /// generic method instantiation GenericInst = 0xA, diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 930dac664..7046f018e 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -2218,6 +2218,7 @@ public bool Equals(CallingConventionSig a, CallingConventionSig b) { case CallingConvention.VarArg: case CallingConvention.Property: case CallingConvention.NativeVarArg: + case CallingConvention.Unmanaged: MethodBaseSig ma = a as MethodBaseSig, mb = b as MethodBaseSig; result = !(ma is null) && !(mb is null) && Equals(ma, mb); break; @@ -2237,7 +2238,6 @@ public bool Equals(CallingConventionSig a, CallingConventionSig b) { result = !(ga is null) && !(gb is null) && Equals(ga, gb); break; - case CallingConvention.Unmanaged: default: result = false; break; @@ -2269,6 +2269,7 @@ public int GetHashCode(CallingConventionSig a) { case CallingConvention.VarArg: case CallingConvention.Property: case CallingConvention.NativeVarArg: + case CallingConvention.Unmanaged: var ma = a as MethodBaseSig; hash = ma is null ? 0 : GetHashCode(ma); break; @@ -2288,7 +2289,6 @@ public int GetHashCode(CallingConventionSig a) { hash = ga is null ? 0 : GetHashCode(ga); break; - case CallingConvention.Unmanaged: default: hash = GetHashCode_CallingConvention(a); break; diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index b6e4b9f2e..4928bb866 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -430,6 +430,7 @@ CallingConventionSig ReadSig() { case CallingConvention.FastCall: case CallingConvention.VarArg: case CallingConvention.NativeVarArg: + case CallingConvention.Unmanaged: result = ReadMethod(callingConvention); break; @@ -449,7 +450,6 @@ CallingConventionSig ReadSig() { result = ReadGenericInstMethod(callingConvention); break; - case CallingConvention.Unmanaged: default: result = null; break; From d4a708528f5ba25bfdfbbd115f3b7f9d379ea104 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Thu, 23 Jul 2020 01:22:49 +0800 Subject: [PATCH 381/511] Unescape Type.Name & Type.FullName, fix #370 (#382) * Unescape Type.Name & Type.FullName * Improve Unescape * Use IndexOf instead of Contains --- src/DotNet/Importer.cs | 2 +- src/DotNet/ReflectionExtensions.cs | 35 +++++++++++++++++++++++++++--- src/DotNet/SigComparer.cs | 8 +++---- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index cc6e07d9b..01d57b850 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -354,7 +354,7 @@ static bool Equals(IAssembly a, IAssembly b) { TypeRef CreateTypeRef2(Type type) { if (!type.IsNested) - return module.UpdateRowId(new TypeRefUser(module, type.Namespace ?? string.Empty, type.Name ?? string.Empty, CreateScopeReference(type))); + return module.UpdateRowId(new TypeRefUser(module, type.Namespace ?? string.Empty, ReflectionExtensions.Unescape(type.Name) ?? string.Empty, CreateScopeReference(type))); type.GetTypeNamespaceAndName_TypeDefOrRef(out var @namespace, out var name); return module.UpdateRowId(new TypeRefUser(module, @namespace ?? string.Empty, name ?? string.Empty, CreateTypeRef2(type.DeclaringType))); } diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index c1a148f5f..899c83e03 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.Reflection; +using System.Text; namespace dnlib.DotNet { /// @@ -11,12 +12,12 @@ namespace dnlib.DotNet { static class ReflectionExtensions { public static void GetTypeNamespaceAndName_TypeDefOrRef(this Type type, out string @namespace, out string name) { Debug.Assert(type.IsTypeDef()); - name = type.Name ?? string.Empty; + name = Unescape(type.Name) ?? string.Empty; if (!type.IsNested) @namespace = type.Namespace ?? string.Empty; else { - var declTypeFullName = type.DeclaringType.FullName; - var typeFullName = type.FullName; + var declTypeFullName = Unescape(type.DeclaringType.FullName); + var typeFullName = Unescape(type.FullName); if (declTypeFullName.Length + 1 + name.Length == typeFullName.Length) @namespace = string.Empty; else @@ -105,5 +106,33 @@ internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Typ /// this public static bool IsTypeDef(this Type type) => !(type is null) && !type.HasElementType && (!type.IsGenericType || type.IsGenericTypeDefinition); + + internal static string Unescape(string name) { + if (string.IsNullOrEmpty(name) || name.IndexOf('\\') < 0) + return name; + var sb = new StringBuilder(name.Length); + for (int i = 0; i < name.Length; i++) { + if (name[i] == '\\' && i < name.Length - 1 && IsReservedTypeNameChar(name[i + 1])) + sb.Append(name[++i]); + else + sb.Append(name[i]); + } + return sb.ToString(); + } + + static bool IsReservedTypeNameChar(char c) { + switch (c) { + case ',': + case '+': + case '&': + case '*': + case '[': + case ']': + case '\\': + return true; + default: + return false; + } + } } } diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 7046f018e..115f7e2ac 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -3160,7 +3160,7 @@ public bool Equals(TypeDef a, Type b) { } } result = !b.HasElementType && - Equals_TypeNames(a.Name, b.Name) && + Equals_TypeNames(a.Name, ReflectionExtensions.Unescape(b.Name)) && Equals_TypeNamespaces(a.Namespace, b) && EnclosingTypeEquals(a.DeclaringType, b.DeclaringType) && (DontCompareTypeScope || Equals(a.Module, b.Module)); @@ -3214,7 +3214,7 @@ public bool Equals(TypeRef a, Type b) { if (!b.IsTypeDef()) result = false; - else if (!Equals_TypeNames(a.Name, b.Name) || !Equals_TypeNamespaces(a.Namespace, b)) + else if (!Equals_TypeNames(a.Name, ReflectionExtensions.Unescape(b.Name)) || !Equals_TypeNamespaces(a.Namespace, b)) result = false; else if (!((dta = scope as TypeRef) is null)) // nested type result = Equals(dta, b.DeclaringType); // Compare enclosing types @@ -3492,7 +3492,7 @@ public bool Equals(ExportedType a, Type b) { if (!b.IsTypeDef()) result = false; - else if (!Equals_TypeNames(a.TypeName, b.Name) || !Equals_TypeNamespaces(a.TypeNamespace, b)) + else if (!Equals_TypeNames(a.TypeName, ReflectionExtensions.Unescape(b.Name)) || !Equals_TypeNamespaces(a.TypeNamespace, b)) result = false; else if (!((dta = scope as ExportedType) is null)) // nested type result = Equals(dta, b.DeclaringType); // Compare enclosing types @@ -3678,7 +3678,7 @@ public int GetHashCode_TypeDef(Type a) { if (a is null) return GetHashCodeGlobalType(); int hash; - hash = GetHashCode_TypeName(a.Name); + hash = GetHashCode_TypeName(ReflectionExtensions.Unescape(a.Name)); if (a.IsNested) hash += HASHCODE_MAGIC_NESTED_TYPE; else From 650017dd16bdfd7f2ccea2b3e6632960091494e7 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 12 Aug 2020 13:29:34 +0200 Subject: [PATCH 382/511] Delete FUNDING.yml --- .github/FUNDING.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 2ef0ceb55..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: "0xd4d" From 0a3bc8193107f05f3ddab0c67b9ec1e198ed5842 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Thu, 13 Aug 2020 22:14:30 +0200 Subject: [PATCH 383/511] Remove DefineConstants from csproj --- src/dnlib.csproj | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index c13d7bf76..556cdb675 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -61,11 +61,4 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - - $(DefineConstants);DEBUG;TRACE - - - $(DefineConstants);TRACE - - From a8429776a07c3d88544ebc217f65e7227d5a9e82 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Fri, 14 Aug 2020 17:12:02 +0200 Subject: [PATCH 384/511] Support new Roslyn CDIs, closes #386 --- src/DotNet/Pdb/CustomDebugInfoGuids.cs | 2 + src/DotNet/Pdb/PdbCustomDebugInfo.cs | 143 ++++++++++++++++++ .../PortablePdbCustomDebugInfoReader.cs | 53 +++++++ .../PortablePdbCustomDebugInfoWriter.cs | 48 ++++++ src/DotNet/Writer/Metadata.cs | 2 + 5 files changed, 248 insertions(+) diff --git a/src/DotNet/Pdb/CustomDebugInfoGuids.cs b/src/DotNet/Pdb/CustomDebugInfoGuids.cs index f4dcf06c3..95acf760b 100644 --- a/src/DotNet/Pdb/CustomDebugInfoGuids.cs +++ b/src/DotNet/Pdb/CustomDebugInfoGuids.cs @@ -18,6 +18,8 @@ public static class CustomDebugInfoGuids { public static readonly Guid SourceLink = new Guid("CC110556-A091-4D38-9FEC-25AB9A351A6A"); public static readonly Guid StateMachineHoistedLocalScopes = new Guid("6DA9A61E-F8C7-4874-BE62-68BC5630DF71"); public static readonly Guid TupleElementNames = new Guid("ED9FDF71-8879-4747-8ED3-FE5EDE3CE710"); + public static readonly Guid CompilationMetadataReferences = new Guid("7E4D4708-096E-4C5C-AEDA-CB10BA6A740D"); + public static readonly Guid CompilationOptions = new Guid("B5FEEC05-8CD0-4A83-96DA-466284BB4BD8"); #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index a64205171..0dd4c447d 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -101,6 +101,16 @@ public enum PdbCustomDebugInfoKind { /// /// IteratorMethod, + + /// + /// + /// + CompilationMetadataReferences, + + /// + /// + /// + CompilationOptions, } /// @@ -958,4 +968,137 @@ public PdbIteratorMethodCustomDebugInfo() { /// Kickoff method public PdbIteratorMethodCustomDebugInfo(MethodDef kickoffMethod) => KickoffMethod = kickoffMethod; } + + /// + /// Compilation metadata references + /// + public sealed class PdbCompilationMetadataReferencesCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.CompilationMetadataReferences; + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid => CustomDebugInfoGuids.CompilationMetadataReferences; + + /// + /// Gets all references + /// + public List References { get; } + + /// + /// Constructor + /// + public PdbCompilationMetadataReferencesCustomDebugInfo() => References = new List(); + } + + /// + /// Compilation metadata reference flags, see https://github.com/dotnet/roslyn/blob/master/docs/features/pdb-compilation-options.md + /// + [Flags] + public enum PdbCompilationMetadataReferenceFlags : byte { + /// + /// No bit is set + /// + None = 0, + + /// + /// Set if it's an assembly reference, clear if it's a module reference + /// + Assembly = 0x01, + + /// + /// EmbedInteropTypes was enabled + /// + EmbedInteropTypes = 0x02, + } + + /// + /// A compilation metadata reference + /// + public sealed class PdbCompilationMetadataReference { + /// + /// Name of the reference (eg. filename) + /// + public string Name { get; set; } + + /// + /// Aliases (or an empty string), separated with commas + /// + public string Aliases { get; set; } + + /// + /// Gets the flags + /// + public PdbCompilationMetadataReferenceFlags Flags { get; set; } + + /// + /// Gets the timestamp stored in the PE header + /// + public uint Timestamp { get; set; } + + /// + /// Gets SizeOfImage stored in the PE header + /// + public uint SizeOfImage { get; set; } + + /// + /// Gets the MVID stored in the .NET metadata + /// + public Guid Mvid { get; set; } + + /// + /// Constructor + /// + public PdbCompilationMetadataReference() { + Name = string.Empty; + Aliases = string.Empty; + } + + /// + /// Constructor + /// + /// Name of reference + /// Aliases (or an empty string), separated with commas + /// Reference flags + /// Timestamp in PE header + /// SizeOfImage in PE header + /// MVID stored in the .NET metadata + public PdbCompilationMetadataReference(string name, string aliases, PdbCompilationMetadataReferenceFlags flags, uint timestamp, uint sizeOfImage, Guid mvid) { + Name = name; + Aliases = aliases; + Flags = flags; + Timestamp = timestamp; + SizeOfImage = sizeOfImage; + Mvid = mvid; + } + } + + /// + /// Compilation options + /// + public sealed class PdbCompilationOptionsCustomDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.CompilationOptions; + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid => CustomDebugInfoGuids.CompilationOptions; + + /// + /// Gets all compilation options, see https://github.com/dotnet/roslyn/blob/master/docs/features/pdb-compilation-options.md . + /// Option names (key): see roslyn/src/Compilers/Core/Portable/PEWriter/CompilationOptionNames.cs + /// + public List> Options { get; } + + /// + /// Constructor + /// + public PdbCompilationOptionsCustomDebugInfo() => Options = new List>(); + } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index b0ae65488..0990daaee 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -3,6 +3,7 @@ // See Roslyn files: MethodDebugInfo.Portable.cs, MetadataWriter.PortablePdb.cs using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using dnlib.DotNet.Emit; @@ -60,6 +61,10 @@ PdbCustomDebugInfo Read(Guid kind) { return ReadStateMachineHoistedLocalScopes(); if (kind == CustomDebugInfoGuids.TupleElementNames) return ReadTupleElementNames(); + if (kind == CustomDebugInfoGuids.CompilationMetadataReferences) + return ReadCompilationMetadataReferences(); + if (kind == CustomDebugInfoGuids.CompilationOptions) + return ReadCompilationOptions(); Debug.Fail("Unknown custom debug info guid: " + kind.ToString()); return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); } @@ -175,6 +180,54 @@ string ReadUTF8Z(long recPosEnd) { return reader.TryReadZeroTerminatedUtf8String(); } + PdbCustomDebugInfo ReadCompilationMetadataReferences() { + var cdi = new PdbCompilationMetadataReferencesCustomDebugInfo(); + + while (reader.BytesLeft > 0) { + var name = reader.TryReadZeroTerminatedUtf8String(); + Debug.Assert(!(name is null)); + if (name is null) + break; + var aliases = reader.TryReadZeroTerminatedUtf8String(); + Debug.Assert(!(aliases is null)); + if (aliases is null) + break; + + const uint RequiredBytes = 1 + 4 + 4 + 16; + Debug.Assert(reader.BytesLeft >= RequiredBytes); + if (reader.BytesLeft < RequiredBytes) + break; + + var flags = (PdbCompilationMetadataReferenceFlags)reader.ReadByte(); + uint timestamp = reader.ReadUInt32(); + uint sizeOfImage = reader.ReadUInt32(); + var mvid = reader.ReadGuid(); + + var mdRef = new PdbCompilationMetadataReference(name, aliases, flags, timestamp, sizeOfImage, mvid); + cdi.References.Add(mdRef); + } + + return cdi; + } + + PdbCustomDebugInfo ReadCompilationOptions() { + var cdi = new PdbCompilationOptionsCustomDebugInfo(); + + while (reader.BytesLeft > 0) { + var key = reader.TryReadZeroTerminatedUtf8String(); + Debug.Assert(!(key is null)); + if (key is null) + break; + var value = reader.TryReadZeroTerminatedUtf8String(); + Debug.Assert(!(value is null)); + if (value is null) + break; + cdi.Options.Add(new KeyValuePair(key, value)); + } + + return cdi; + } + Instruction GetInstruction(uint offset) { var instructions = bodyOpt.Instructions; int lo = 0, hi = instructions.Count - 1; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index daf959bec..328382c7d 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -84,11 +84,21 @@ byte[] Write(PdbCustomDebugInfo cdi) { case PdbCustomDebugInfoKind.AsyncMethod: WriteAsyncMethodSteppingInformation((PdbAsyncMethodCustomDebugInfo)cdi); break; + + case PdbCustomDebugInfoKind.CompilationMetadataReferences: + WriteCompilationMetadataReferences((PdbCompilationMetadataReferencesCustomDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.CompilationOptions: + WriteCompilationOptions((PdbCompilationOptionsCustomDebugInfo)cdi); + break; } return outStream.ToArray(); } void WriteUTF8Z(string s) { + if (s.IndexOf('\0') >= 0) + helper.Error("String must not contain any NUL bytes"); var bytes = Encoding.UTF8.GetBytes(s); writer.WriteBytes(bytes); writer.WriteByte(0); @@ -269,5 +279,43 @@ uint GetOffsetSlow(MethodDef method, Instruction instr) { helper.Error("Couldn't find an instruction, maybe it was removed. It's still being referenced by some code or by the PDB"); return uint.MaxValue; } + + void WriteCompilationMetadataReferences(PdbCompilationMetadataReferencesCustomDebugInfo cdi) { + foreach (var mdRef in cdi.References) { + var name = mdRef.Name; + if (name is null) { + helper.Error("Metadata reference name is null"); + return; + } + WriteUTF8Z(name); + + var aliases = mdRef.Aliases; + if (aliases is null) { + helper.Error("Metadata reference aliases is null"); + return; + } + WriteUTF8Z(aliases); + + writer.WriteByte((byte)mdRef.Flags); + writer.WriteUInt32(mdRef.Timestamp); + writer.WriteUInt32(mdRef.SizeOfImage); + writer.WriteBytes(mdRef.Mvid.ToByteArray()); + } + } + + void WriteCompilationOptions(PdbCompilationOptionsCustomDebugInfo cdi) { + foreach (var kv in cdi.Options) { + if (kv.Key is null) { + helper.Error("Compiler option `key` is null"); + return; + } + if (kv.Value is null) { + helper.Error("Compiler option `value` is null"); + return; + } + WriteUTF8Z(kv.Key); + WriteUTF8Z(kv.Value); + } + } } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 23ec72a5b..4d8022340 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3362,6 +3362,8 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, case PdbCustomDebugInfoKind.DynamicLocalVariables: case PdbCustomDebugInfoKind.EmbeddedSource: case PdbCustomDebugInfoKind.SourceLink: + case PdbCustomDebugInfoKind.CompilationMetadataReferences: + case PdbCustomDebugInfoKind.CompilationOptions: AddCustomDebugInformationCore(serializerMethodContext, encodedToken, cdi, cdi.Guid); break; From 7a01346f51e7f7d994b7b77d57041e9b816d66dc Mon Sep 17 00:00:00 2001 From: SilverFox Date: Thu, 13 Aug 2020 14:24:11 +0800 Subject: [PATCH 385/511] '=' should be an vaild char for TypeNameParser.ReadTypeRefNoAssembly() --- src/DotNet/TypeNameParser.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index 9c74f47ca..f9a1ca779 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -358,7 +358,7 @@ protected TypeRef ReadTypeRefAndNestedNoAssembly(char nestedChar) { protected TypeRef ReadTypeRefNoAssembly() { // White space is important here. Any white space before the comma/EOF must be // parsed as part of the name. - GetNamespaceAndName(ReadId(false), out var ns, out var name); + GetNamespaceAndName(ReadId(false, false), out var ns, out var name); return ownerModule.UpdateRowId(new TypeRefUser(ownerModule, ns, name)); } @@ -455,13 +455,13 @@ internal int ReadInt32() { } } - internal string ReadId() => ReadId(true); + internal string ReadId() => ReadId(true, true); - internal string ReadId(bool ignoreWhiteSpace) { + internal string ReadId(bool ignoreWhiteSpace, bool ignoreEqualSign) { SkipWhite(); var sb = new StringBuilder(); int c; - while ((c = GetIdChar(ignoreWhiteSpace)) != -1) + while ((c = GetIdChar(ignoreWhiteSpace, ignoreEqualSign)) != -1) sb.Append((char)c); Verify(sb.Length > 0, "Expected an id"); return sb.ToString(); @@ -481,7 +481,8 @@ internal string ReadId(bool ignoreWhiteSpace) { /// Gets the next ID char or -1 if no more ID chars /// /// true if white space should be ignored - internal abstract int GetIdChar(bool ignoreWhiteSpace); + /// true if equal sign '=' should be ignored + internal abstract int GetIdChar(bool ignoreWhiteSpace, bool ignoreEqualSign); } /// @@ -824,7 +825,7 @@ int GetAsmNameChar() { } } - internal override int GetIdChar(bool ignoreWhiteSpace) { + internal override int GetIdChar(bool ignoreWhiteSpace, bool ignoreEqualSign) { int c = PeekChar(); if (c == -1) return -1; @@ -841,7 +842,7 @@ internal override int GetIdChar(bool ignoreWhiteSpace) { case '*': case '[': case ']': - case '=': + case '=' when ignoreEqualSign: return -1; default: From b6edf632c4a8541e91bb8024c9e290c5f2de072d Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Tue, 18 Aug 2020 20:43:48 +0200 Subject: [PATCH 386/511] Don't escape ReflectionNamespace, closes #377 --- src/DotNet/FullNameFactory.cs | 57 +++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index d7b30afaf..b20854b3a 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -132,7 +132,7 @@ public static StringBuilder NameSB(IType type, bool isReflection, StringBuilder if (type is TypeSpec ts) return NameSB(ts, isReflection, sb); if (type is TypeSig sig) - return NameSB(sig, false, sb); + return NameSB(sig, isReflection, sb); if (type is ExportedType et) return NameSB(et, isReflection, sb); return sb ?? new StringBuilder(); @@ -163,7 +163,7 @@ public static StringBuilder NamespaceSB(IType type, bool isReflection, StringBui if (type is TypeSpec ts) return NamespaceSB(ts, isReflection, sb); if (type is TypeSig sig) - return NamespaceSB(sig, false, sb); + return NamespaceSB(sig, isReflection, sb); if (type is ExportedType et) return NamespaceSB(et, isReflection, sb); return sb ?? new StringBuilder(); @@ -405,7 +405,7 @@ public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder /// The namespace public static StringBuilder NamespaceSB(TypeRef typeRef, bool isReflection, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeRef); + fnc.CreateNamespace(typeRef, true); return fnc.sb ?? new StringBuilder(); } @@ -523,7 +523,7 @@ public static string Namespace(TypeDef typeDef, bool isReflection, StringBuilder /// The namespace public static StringBuilder NamespaceSB(TypeDef typeDef, bool isReflection, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeDef); + fnc.CreateNamespace(typeDef, true); return fnc.sb ?? new StringBuilder(); } @@ -633,7 +633,7 @@ public static string Namespace(TypeSpec typeSpec, bool isReflection, StringBuild /// The namespace public static StringBuilder NamespaceSB(TypeSpec typeSpec, bool isReflection, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeSpec); + fnc.CreateNamespace(typeSpec, true); return fnc.sb ?? new StringBuilder(); } @@ -759,7 +759,7 @@ public static string Namespace(TypeSig typeSig, bool isReflection, StringBuilder /// The namespace public static StringBuilder NamespaceSB(TypeSig typeSig, bool isReflection, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeSig); + fnc.CreateNamespace(typeSig, true); return fnc.sb ?? new StringBuilder(); } @@ -895,7 +895,7 @@ public static string Namespace(ExportedType exportedType, bool isReflection, Str /// The namespace public static StringBuilder NamespaceSB(ExportedType exportedType, bool isReflection, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(exportedType); + fnc.CreateNamespace(exportedType, true); return fnc.sb ?? new StringBuilder(); } @@ -1050,13 +1050,13 @@ void CreateFullName(ITypeDefOrRef typeDefOrRef) { sb.Append(NULLVALUE); } - void CreateNamespace(ITypeDefOrRef typeDefOrRef) { + void CreateNamespace(ITypeDefOrRef typeDefOrRef, bool onlyNamespace) { if (typeDefOrRef is TypeRef) - CreateNamespace((TypeRef)typeDefOrRef); + CreateNamespace((TypeRef)typeDefOrRef, onlyNamespace); else if (typeDefOrRef is TypeDef) - CreateNamespace((TypeDef)typeDefOrRef); + CreateNamespace((TypeDef)typeDefOrRef, onlyNamespace); else if (typeDefOrRef is TypeSpec) - CreateNamespace((TypeSpec)typeDefOrRef); + CreateNamespace((TypeSpec)typeDefOrRef, onlyNamespace); else sb.Append(NULLVALUE); } @@ -1115,19 +1115,19 @@ void CreateFullName(TypeRef typeRef) { AddNestedTypeSeparator(); } - if (AddNamespace(typeRef.Namespace)) + if (AddNamespace(typeRef.Namespace, false)) sb.Append('.'); AddName(typeRef.Name); recursionCounter.Decrement(); } - void CreateNamespace(TypeRef typeRef) { + void CreateNamespace(TypeRef typeRef, bool onlyNamespace) { if (typeRef is null) { sb.Append(NULLVALUE); return; } - AddNamespace(typeRef.Namespace); + AddNamespace(typeRef.Namespace, onlyNamespace); } void CreateName(TypeRef typeRef) { @@ -1171,19 +1171,19 @@ void CreateFullName(TypeDef typeDef) { AddNestedTypeSeparator(); } - if (AddNamespace(typeDef.Namespace)) + if (AddNamespace(typeDef.Namespace, false)) sb.Append('.'); AddName(typeDef.Name); recursionCounter.Decrement(); } - void CreateNamespace(TypeDef typeDef) { + void CreateNamespace(TypeDef typeDef, bool onlyNamespace) { if (typeDef is null) { sb.Append(NULLVALUE); return; } - AddNamespace(typeDef.Namespace); + AddNamespace(typeDef.Namespace, onlyNamespace); } void CreateName(TypeDef typeDef) { @@ -1210,12 +1210,12 @@ void CreateFullName(TypeSpec typeSpec) { CreateFullName(typeSpec.TypeSig); } - void CreateNamespace(TypeSpec typeSpec) { + void CreateNamespace(TypeSpec typeSpec, bool onlyNamespace) { if (typeSpec is null) { sb.Append(NULLVALUE); return; } - CreateNamespace(typeSpec.TypeSig); + CreateNamespace(typeSpec.TypeSig, onlyNamespace); } void CreateName(TypeSpec typeSpec) { @@ -1245,7 +1245,7 @@ void CreateAssemblyQualifiedName(TypeSig typeSig) { } void CreateFullName(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAMESPACE | TYPESIG_NAME); - void CreateNamespace(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAMESPACE); + void CreateNamespace(TypeSig typeSig, bool onlyNamespace) => CreateTypeSigName(typeSig, TYPESIG_NAMESPACE | (onlyNamespace ? TYPESIG_ONLY_NAMESPACE : 0)); void CreateName(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAME); TypeSig ReplaceGenericArg(TypeSig typeSig) { @@ -1259,6 +1259,7 @@ TypeSig ReplaceGenericArg(TypeSig typeSig) { const int TYPESIG_NAMESPACE = 1; const int TYPESIG_NAME = 2; + const int TYPESIG_ONLY_NAMESPACE = 4; void CreateTypeSigName(TypeSig typeSig, int flags) { if (typeSig is null) { sb.Append(NULLVALUE); @@ -1298,7 +1299,7 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { if (createNamespace && createName) CreateFullName(((TypeDefOrRefSig)typeSig).TypeDefOrRef); else if (createNamespace) - CreateNamespace(((TypeDefOrRefSig)typeSig).TypeDefOrRef); + CreateNamespace(((TypeDefOrRefSig)typeSig).TypeDefOrRef, (flags & TYPESIG_ONLY_NAMESPACE) != 0); else if (createName) CreateName(((TypeDefOrRefSig)typeSig).TypeDefOrRef); break; @@ -1519,19 +1520,19 @@ void CreateFullName(ExportedType exportedType) { AddNestedTypeSeparator(); } - if (AddNamespace(exportedType.TypeNamespace)) + if (AddNamespace(exportedType.TypeNamespace, false)) sb.Append('.'); AddName(exportedType.TypeName); recursionCounter.Decrement(); } - void CreateNamespace(ExportedType exportedType) { + void CreateNamespace(ExportedType exportedType, bool onlyNamespace) { if (exportedType is null) { sb.Append(NULLVALUE); return; } - AddNamespace(exportedType.TypeNamespace); + AddNamespace(exportedType.TypeNamespace, onlyNamespace); } void CreateName(ExportedType exportedType) { @@ -1571,10 +1572,14 @@ void AddNestedTypeSeparator() { sb.Append('/'); } - bool AddNamespace(UTF8String @namespace) { + bool AddNamespace(UTF8String @namespace, bool onlyNamespace) { if (UTF8String.IsNullOrEmpty(@namespace)) return false; - AddIdentifier(@namespace.String); + // If it's reflection and only namespace (instead of full name), it's not escaped + if (onlyNamespace && isReflection) + sb.Append(@namespace.String); + else + AddIdentifier(@namespace.String); return true; } From 6500594caae614ac392e7a2a51ec3634e20cfec6 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 24 Aug 2020 17:58:25 +0200 Subject: [PATCH 387/511] Add .NET sun machine types --- src/DotNet/CpuArch.cs | 4 ++++ src/PE/Machine.cs | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/DotNet/CpuArch.cs b/src/DotNet/CpuArch.cs index 508500943..2e0c27a5d 100644 --- a/src/DotNet/CpuArch.cs +++ b/src/DotNet/CpuArch.cs @@ -49,6 +49,7 @@ public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { case Machine.I386_Native_FreeBSD: case Machine.I386_Native_Linux: case Machine.I386_Native_NetBSD: + case Machine.I386_Native_Sun: cpuArch = x86CpuArch; return true; @@ -57,6 +58,7 @@ public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { case Machine.AMD64_Native_FreeBSD: case Machine.AMD64_Native_Linux: case Machine.AMD64_Native_NetBSD: + case Machine.AMD64_Native_Sun: cpuArch = x64CpuArch; return true; @@ -69,6 +71,7 @@ public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { case Machine.ARMNT_Native_FreeBSD: case Machine.ARMNT_Native_Linux: case Machine.ARMNT_Native_NetBSD: + case Machine.ARMNT_Native_Sun: cpuArch = armCpuArch; return true; @@ -77,6 +80,7 @@ public static bool TryGetCpuArch(Machine machine, out CpuArch cpuArch) { case Machine.ARM64_Native_FreeBSD: case Machine.ARM64_Native_Linux: case Machine.ARM64_Native_NetBSD: + case Machine.ARM64_Native_Sun: //TODO: Support ARM64 goto default; diff --git a/src/PE/Machine.cs b/src/PE/Machine.cs index 79700e4e9..d3911c607 100644 --- a/src/PE/Machine.cs +++ b/src/PE/Machine.cs @@ -90,6 +90,11 @@ public enum Machine : ushort { AMD64_Native_NetBSD = AMD64 ^ 0x1993, ARMNT_Native_NetBSD = ARMNT ^ 0x1993, ARM64_Native_NetBSD = ARM64 ^ 0x1993, + + I386_Native_Sun = I386 ^ 0x1992, + AMD64_Native_Sun = AMD64 ^ 0x1992, + ARMNT_Native_Sun = ARMNT ^ 0x1992, + ARM64_Native_Sun = ARM64 ^ 0x1992, #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } @@ -111,12 +116,14 @@ public static bool Is64Bit(this Machine machine) { case Machine.AMD64_Native_FreeBSD: case Machine.AMD64_Native_Linux: case Machine.AMD64_Native_NetBSD: + case Machine.AMD64_Native_Sun: case Machine.ARM64: case Machine.ARM64_Native_Apple: case Machine.ARM64_Native_FreeBSD: case Machine.ARM64_Native_Linux: case Machine.ARM64_Native_NetBSD: + case Machine.ARM64_Native_Sun: return true; default: @@ -136,6 +143,7 @@ public static bool IsI386(this Machine machine) { case Machine.I386_Native_FreeBSD: case Machine.I386_Native_Linux: case Machine.I386_Native_NetBSD: + case Machine.I386_Native_Sun: return true; default: return false; @@ -154,6 +162,7 @@ public static bool IsAMD64(this Machine machine) { case Machine.AMD64_Native_FreeBSD: case Machine.AMD64_Native_Linux: case Machine.AMD64_Native_NetBSD: + case Machine.AMD64_Native_Sun: return true; default: return false; @@ -172,6 +181,7 @@ public static bool IsARMNT(this Machine machine) { case Machine.ARMNT_Native_FreeBSD: case Machine.ARMNT_Native_Linux: case Machine.ARMNT_Native_NetBSD: + case Machine.ARMNT_Native_Sun: return true; default: return false; @@ -190,6 +200,7 @@ public static bool IsARM64(this Machine machine) { case Machine.ARM64_Native_FreeBSD: case Machine.ARM64_Native_Linux: case Machine.ARM64_Native_NetBSD: + case Machine.ARM64_Native_Sun: return true; default: return false; From 5a59528824b59c320e8997615e427aebb60a26b7 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 29 Aug 2020 10:11:31 +0200 Subject: [PATCH 388/511] Update build.yml --- .github/workflows/build.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86e4282a2..a347ad382 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,22 @@ name: GitHub CI -on: push +on: + push: + paths: + - '.github/workflows/**' + - 'Examples/**' + - 'src/**' + - '!**/*.md' + branches: + - master + pull_request: + paths: + - 'Examples/**' + - 'src/**' + - '!**/*.md' + branches: + - master + release: + types: released jobs: build-windows: From a14ea62859eb0e6c658752cbf9353eb1aeddc8c6 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Sat, 29 Aug 2020 10:13:29 +0200 Subject: [PATCH 389/511] Update build.yml --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a347ad382..daac1968a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,12 +34,14 @@ jobs: .\build.ps1 - name: upload-artifact doesn't support wildcards + if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') shell: pwsh run: | New-Item -ItemType Directory nuget_files > $null Copy-Item src\bin\Release\*.*nupkg nuget_files - uses: actions/upload-artifact@v1 + if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') with: name: nupkg path: nuget_files From f5c61bff932942a483d5d6231677fa83138e4397 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 31 Aug 2020 21:13:26 +0200 Subject: [PATCH 390/511] Add AnalysisLevel=latest --- src/dnlib.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 556cdb675..43ceb236d 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -26,6 +26,7 @@ MIT $(InformationalVersion) dotnet;assembly;module;reader;writer;PDB;PortablePdb;WindowsPdb;IL;CIL;MSIL;metadata + latest strict;nullablePublicOnly true true From 98ea0898d24951aaace20c015fb69bc8221f456a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 11 Sep 2020 18:14:38 +0200 Subject: [PATCH 391/511] Support for custom/experimental CIL opcodes. (#378) * Support for custom/experimental CIL opcodes. Closes #367. * Add readonly to MethodBodyReaderBase.context. * Revert to old logic in MethodBodyWriterBase.WriteOpCode(). * Address review comments. * Make ReadOpCode() retain old behavior where possible. --- Examples/Example7.cs | 69 ++++++++++++++++++++++ Examples/Program.cs | 3 +- src/DotNet/Emit/Code.cs | 40 ++++++++++++- src/DotNet/Emit/DynamicMethodBodyReader.cs | 3 +- src/DotNet/Emit/MethodBodyReader.cs | 68 +++++++++++++++++++-- src/DotNet/Emit/MethodBodyReaderBase.cs | 34 +++++++++-- src/DotNet/Emit/OpCode.cs | 19 ++++-- src/DotNet/Emit/OpCodeType.cs | 2 + src/DotNet/Emit/OpCodes.cs | 2 +- src/DotNet/ModuleContext.cs | 31 ++++++++++ src/DotNet/ModuleDefMD.cs | 2 +- src/DotNet/Writer/MethodBodyWriter.cs | 4 +- src/DotNet/Writer/MethodBodyWriterBase.cs | 3 +- 13 files changed, 257 insertions(+), 23 deletions(-) create mode 100644 Examples/Example7.cs diff --git a/Examples/Example7.cs b/Examples/Example7.cs new file mode 100644 index 000000000..32c699885 --- /dev/null +++ b/Examples/Example7.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; +using System.Linq; +using dnlib.DotNet; +using dnlib.DotNet.Emit; + +namespace dnlib.Examples { + public class Example7 { + public static void Run() => new Example7().DoIt(); + + void DoIt() { + var test1 = new OpCode( + "test1", 0xf0, 0x00, OperandType.InlineNone, FlowControl.Next, StackBehaviour.Push0, StackBehaviour.Pop0); + var test2 = new OpCode( + "test2", 0xf0, 0x01, OperandType.InlineBrTarget, FlowControl.Branch, StackBehaviour.Push0, StackBehaviour.Pop0); + var test3 = new OpCode( + "test3", 0xf0, 0x02, OperandType.InlineString, FlowControl.Next, StackBehaviour.Push1, StackBehaviour.Pop0); + + var ctx = new ModuleContext(); + + ctx.RegisterExperimentalOpCode(test1); + ctx.RegisterExperimentalOpCode(test2); + ctx.RegisterExperimentalOpCode(test3); + + var mod = ModuleDefMD.Load(typeof(Example7).Module, ctx); + var body = mod.Types.Single(x => x.Name == nameof(Example7)).Methods.Single(x => x.Name == nameof(CustomCil)).Body; + + Console.WriteLine("Original:"); + foreach (var insn in body.Instructions) + Console.WriteLine("{0} (0x{1:X4})", insn, insn.OpCode.Value); + Console.WriteLine(); + + var code = body.Instructions; + + code.Clear(); + + var label = OpCodes.Nop.ToInstruction(); + + code.Add(test1.ToInstruction()); + code.Add(OpCodes.Nop.ToInstruction()); + code.Add(label); + code.Add(OpCodes.Ret.ToInstruction()); + code.Add(test2.ToInstruction(label)); + code.Add(test3.ToInstruction("foo")); + + Console.WriteLine("Modified:"); + foreach (var insn in body.Instructions) + Console.WriteLine("{0} (0x{1:X4})", insn, insn.OpCode.Value); + Console.WriteLine(); + + using (var stream = new MemoryStream()) { + mod.Write(stream); + + stream.Position = 0; + + mod = ModuleDefMD.Load(stream, ctx); + body = mod.Types.Single(x => x.Name == nameof(Example7)).Methods.Single(x => x.Name == nameof(CustomCil)).Body; + + Console.WriteLine("Roundtripped:"); + foreach (var insn in body.Instructions) + Console.WriteLine("{0} (0x{1:X4})", insn, insn.OpCode.Value); + Console.WriteLine(); + } + } + + void CustomCil() { + } + } +} diff --git a/Examples/Program.cs b/Examples/Program.cs index 69280ea7f..e22415ad6 100644 --- a/Examples/Program.cs +++ b/Examples/Program.cs @@ -7,7 +7,8 @@ static void Main(string[] args) { // Example3.Run(); // Example4.Run(); // Example5.Run(); - Example6.Run(); +// Example6.Run(); + Example7.Run(); } } } diff --git a/src/DotNet/Emit/Code.cs b/src/DotNet/Emit/Code.cs index 5d444a10f..9491639cd 100644 --- a/src/DotNet/Emit/Code.cs +++ b/src/DotNet/Emit/Code.cs @@ -173,7 +173,7 @@ public enum Code : ushort { Neg = 0x0065, Newarr = 0x008D, Newobj = 0x0073, -// No = 0xFE19, // Not supported by MS' CLI and must be parsed as an opcode without an operand + No = 0xFE19, Nop = 0x0000, Not = 0x0066, Or = 0x0060, @@ -240,18 +240,52 @@ public enum Code : ushort { } public static partial class Extensions { + /// + /// Determines whether a is experimental + /// + /// The code + /// true if the is experimental; otherwise, false + public static bool IsExperimental(this Code code) { + byte hi = (byte)((ushort)code >> 8); + + return hi >= 0xF0 && hi <= 0xFB; + } + /// /// Converts a to an /// /// The code /// A or null if it's invalid public static OpCode ToOpCode(this Code code) { - int hi = (ushort)code >> 8; - int lo = (byte)code; + byte hi = (byte)((ushort)code >> 8); + byte lo = (byte)code; + if (hi == 0) + return OpCodes.OneByteOpCodes[lo]; + if (hi == 0xFE) + return OpCodes.TwoByteOpCodes[lo]; + if (code == Code.UNKNOWN1) + return OpCodes.UNKNOWN1; + if (code == Code.UNKNOWN2) + return OpCodes.UNKNOWN2; + return null; + } + + /// + /// Converts a to an , using a module context to look + /// up potential experimental opcodes + /// + /// The code + /// The module context + /// A or null if it's invalid + public static OpCode ToOpCode(this Code code, ModuleContext context) { + byte hi = (byte)((ushort)code >> 8); + byte lo = (byte)code; if (hi == 0) return OpCodes.OneByteOpCodes[lo]; if (hi == 0xFE) return OpCodes.TwoByteOpCodes[lo]; + if (context.GetExperimentalOpCode(hi, lo) is OpCode op) + return op; if (code == Code.UNKNOWN1) return OpCodes.UNKNOWN1; if (code == Code.UNKNOWN2) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 920ec824a..bf69990fc 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -149,7 +149,8 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer) /// instance or a DynamicResolver instance. /// Importer /// Options - public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, DynamicMethodBodyReaderOptions options) { + public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, DynamicMethodBodyReaderOptions options) + : base(module.Context) { this.module = module; this.importer = importer; this.options = options; diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index d11d8cac7..2c19ae2d1 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -92,6 +92,18 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, Data public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader reader, IList parameters, GenericParamContext gpContext) => CreateCilBody(opResolver, reader, null, parameters, gpContext); + /// + /// Creates a CIL method body or returns an empty one if doesn't + /// point to the start of a valid CIL method body. + /// + /// The operand resolver + /// A reader positioned at the start of a .NET method body + /// Method parameters + /// Generic parameter context + /// The module context + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader reader, IList parameters, GenericParamContext gpContext, ModuleContext context) => + CreateCilBody(opResolver, reader, null, parameters, gpContext, context); + /// /// Creates a CIL method body or returns an empty one if is not /// a valid CIL method body. @@ -139,8 +151,22 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, Data /// present or if contains the exception handlers /// Method parameters /// Generic parameter context - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters, GenericParamContext gpContext) { - var mbReader = new MethodBodyReader(opResolver, codeReader, ehReader, parameters, gpContext); + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters, GenericParamContext gpContext) => + CreateCilBody(opResolver, codeReader, ehReader, parameters, gpContext, null); + + /// + /// Creates a CIL method body or returns an empty one if doesn't + /// point to the start of a valid CIL method body. + /// + /// The operand resolver + /// A reader positioned at the start of a .NET method body + /// Exception handler reader or null if exceptions aren't + /// present or if contains the exception handlers + /// Method parameters + /// Generic parameter context + /// The module context + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters, GenericParamContext gpContext, ModuleContext context) { + var mbReader = new MethodBodyReader(opResolver, codeReader, ehReader, parameters, gpContext, context); if (!mbReader.Read()) return new CilBody(); return mbReader.CreateCilBody(); @@ -176,10 +202,28 @@ public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte /// Code size /// Local variable signature token or 0 if none /// Generic parameter context - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok, GenericParamContext gpContext) { + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok, GenericParamContext gpContext) => + CreateCilBody(opResolver, code, exceptions, parameters, flags, maxStack, codeSize, localVarSigTok, gpContext, null); + + /// + /// Creates a CIL method body or returns an empty one if is not + /// a valid CIL method body. + /// + /// The operand resolver + /// All code + /// Exceptions or null if all exception handlers are in + /// + /// Method parameters + /// Method header flags, eg. 2 if tiny method + /// Max stack + /// Code size + /// Local variable signature token or 0 if none + /// Generic parameter context + /// The module context + public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters, ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok, GenericParamContext gpContext, ModuleContext context) { var codeReader = ByteArrayDataReaderFactory.CreateReader(code); var ehReader = exceptions is null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions); - var mbReader = new MethodBodyReader(opResolver, codeReader, ehReader, parameters, gpContext); + var mbReader = new MethodBodyReader(opResolver, codeReader, ehReader, parameters, gpContext, context); mbReader.SetHeader(flags, maxStack, codeSize, localVarSigTok); if (!mbReader.Read()) return new CilBody(); @@ -250,7 +294,21 @@ public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader codeR /// Method parameters /// Generic parameter context public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters, GenericParamContext gpContext) - : base(codeReader, parameters) { + : this(opResolver, codeReader, ehReader, parameters, gpContext, null) { + } + + /// + /// Constructor + /// + /// The operand resolver + /// A reader positioned at the start of a .NET method body + /// Exception handler reader or null if exceptions aren't + /// present or if contains the exception handlers + /// Method parameters + /// Generic parameter context + /// Module context + public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters, GenericParamContext gpContext, ModuleContext context) + : base(codeReader, parameters, context) { this.opResolver = opResolver; exceptionsReader = ehReader; this.gpContext = gpContext; diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index 157f25e8b..0d4e840b0 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -24,6 +24,7 @@ public abstract class MethodBodyReaderBase { protected uint codeEndOffs; /// Start offset of method protected uint codeStartOffs; + readonly ModuleContext context; /// /// Gets all parameters @@ -51,6 +52,14 @@ public abstract class MethodBodyReaderBase { protected MethodBodyReaderBase() { } + /// + /// Constructor + /// + /// The module context + protected MethodBodyReaderBase(ModuleContext context) { + this.context = context; + } + /// /// Constructor /// @@ -64,9 +73,20 @@ protected MethodBodyReaderBase(DataReader reader) /// /// The reader /// Method parameters or null if they're not known yet - protected MethodBodyReaderBase(DataReader reader, IList parameters) { + protected MethodBodyReaderBase(DataReader reader, IList parameters) + : this(reader, parameters, null) { + } + + /// + /// Constructor + /// + /// The reader + /// Method parameters or null if they're not known yet + /// The module context + protected MethodBodyReaderBase(DataReader reader, IList parameters, ModuleContext context) { this.reader = reader; this.parameters = parameters; + this.context = context; } /// @@ -218,9 +238,15 @@ Instruction ReadOneInstruction() { /// OpCode ReadOpCode() { var op = reader.ReadByte(); - if (op != 0xFE) - return OpCodes.OneByteOpCodes[op]; - return OpCodes.TwoByteOpCodes[reader.ReadByte()]; + if (op == 0xFE) + return OpCodes.TwoByteOpCodes[reader.ReadByte()]; + if (op >= 0xF0 && op <= 0xFB && !(context is null) && reader.BytesLeft >= 1) { + if (context.GetExperimentalOpCode(op, reader.ReadByte()) is OpCode opCode) + return opCode; + else + reader.Position--; + } + return OpCodes.OneByteOpCodes[op]; } /// diff --git a/src/DotNet/Emit/OpCode.cs b/src/DotNet/Emit/OpCode.cs index 964158fdf..d5e315f62 100644 --- a/src/DotNet/Emit/OpCode.cs +++ b/src/DotNet/Emit/OpCode.cs @@ -52,7 +52,14 @@ public sealed class OpCode { /// public int Size => Code < (Code)0x100 || Code == Code.UNKNOWN1 ? 1 : 2; - internal OpCode(string name, Code code, OperandType operandType, FlowControl flowControl, OpCodeType opCodeType, StackBehaviour push, StackBehaviour pop) { + /// + /// Constructs an experimental opcode. + /// + public OpCode(string name, byte first, byte second, OperandType operandType, FlowControl flowControl, StackBehaviour push, StackBehaviour pop) + : this(name, (Code)((first << 8) | second), operandType, flowControl, OpCodeType.Experimental, push, pop, true) { + } + + internal OpCode(string name, Code code, OperandType operandType, FlowControl flowControl, OpCodeType opCodeType, StackBehaviour push, StackBehaviour pop, bool experimental = false) { Name = name; Code = code; OperandType = operandType; @@ -60,10 +67,12 @@ internal OpCode(string name, Code code, OperandType operandType, FlowControl flo OpCodeType = opCodeType; StackBehaviourPush = push; StackBehaviourPop = pop; - if (((ushort)code >> 8) == 0) - OpCodes.OneByteOpCodes[(byte)code] = this; - else if (((ushort)code >> 8) == 0xFE) - OpCodes.TwoByteOpCodes[(byte)code] = this; + if (!experimental) { + if (((ushort)code >> 8) == 0) + OpCodes.OneByteOpCodes[(byte)code] = this; + else if (((ushort)code >> 8) == 0xFE) + OpCodes.TwoByteOpCodes[(byte)code] = this; + } } /// diff --git a/src/DotNet/Emit/OpCodeType.cs b/src/DotNet/Emit/OpCodeType.cs index a0d6df86f..6af8b86f2 100644 --- a/src/DotNet/Emit/OpCodeType.cs +++ b/src/DotNet/Emit/OpCodeType.cs @@ -17,5 +17,7 @@ public enum OpCodeType : byte { Prefix, /// Primitive, + /// + Experimental, } } diff --git a/src/DotNet/Emit/OpCodes.cs b/src/DotNet/Emit/OpCodes.cs index e9279617c..639f9c4b1 100644 --- a/src/DotNet/Emit/OpCodes.cs +++ b/src/DotNet/Emit/OpCodes.cs @@ -240,7 +240,7 @@ public static class OpCodes { public static readonly OpCode Constrained = new OpCode("constrained.", Code.Constrained, OperandType.InlineType, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); public static readonly OpCode Cpblk = new OpCode("cpblk", Code.Cpblk, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi_popi); public static readonly OpCode Initblk = new OpCode("initblk", Code.Initblk, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi_popi); -// public static readonly OpCode No = new OpCode("no.", Code.No, OperandType.ShortInlineI, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); + public static readonly OpCode No = new OpCode("no.", Code.No, OperandType.ShortInlineI, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); public static readonly OpCode Rethrow = new OpCode("rethrow", Code.Rethrow, OperandType.InlineNone, FlowControl.Throw, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Pop0); public static readonly OpCode Sizeof = new OpCode("sizeof", Code.Sizeof, OperandType.InlineType, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); public static readonly OpCode Refanytype = new OpCode("refanytype", Code.Refanytype, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); diff --git a/src/DotNet/ModuleContext.cs b/src/DotNet/ModuleContext.cs index 9f4fb270f..ee963194a 100644 --- a/src/DotNet/ModuleContext.cs +++ b/src/DotNet/ModuleContext.cs @@ -1,6 +1,7 @@ // dnlib: See LICENSE.txt for more info using System.Threading; +using dnlib.DotNet.Emit; namespace dnlib.DotNet { /// @@ -9,6 +10,7 @@ namespace dnlib.DotNet { public class ModuleContext { IAssemblyResolver assemblyResolver; IResolver resolver; + readonly OpCode[][] experimentalOpCodes = new OpCode[12][]; /// /// Gets/sets the assembly resolver. This is never null. @@ -67,5 +69,34 @@ public ModuleContext(IAssemblyResolver assemblyResolver, IResolver resolver) { if (resolver is null && !(assemblyResolver is null)) this.resolver = new Resolver(assemblyResolver); } + + /// + /// Registers an experimental CIL opcode. It must be a 2-byte opcode + /// where the first byte lies within the range 0xF0..0xFB. + /// + public void RegisterExperimentalOpCode(OpCode opCode) { + byte high = (byte)((ushort)opCode.Value >> 8); + byte low = (byte)opCode.Value; + OpCode[] array = experimentalOpCodes[high - 0xF0] ??= new OpCode[256]; + + array[low] = opCode; + } + + /// + /// Clears an experimental CIL opcode. + /// + public void ClearExperimentalOpCode(byte high, byte low) { + OpCode[] array = experimentalOpCodes[high - 0xF0]; + + if (array != null) + array[low] = null; + } + + /// + /// Attempts to get an experimental CIL opcode. + /// + public OpCode GetExperimentalOpCode(byte high, byte low) { + return experimentalOpCodes[high - 0xF0]?[low]; + } } } diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index a35cca3fe..4c8d323ca 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1298,7 +1298,7 @@ public CilBody ReadCilBody(IList parameters, RVA rva, GenericParamCon // seem to verify it. We must parse the method exactly the way the CLR parses it. var reader = metadata.PEImage.CreateReader(); reader.Position = (uint)metadata.PEImage.ToFileOffset(rva); - return MethodBodyReader.CreateCilBody(this, reader, parameters, gpContext); + return MethodBodyReader.CreateCilBody(this, reader, parameters, gpContext, Context); } /// diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 6890cef44..379103535 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -80,7 +80,9 @@ public MethodBodyWriter(ITokenProvider helper, CilBody cilBody, bool keepMaxStac this.keepMaxStack = keepMaxStack; } - internal MethodBodyWriter(ITokenProvider helper) => this.helper = helper; + internal MethodBodyWriter(ITokenProvider helper) { + this.helper = helper; + } internal void Reset(CilBody cilBody, bool keepMaxStack) { Reset(cilBody.Instructions, cilBody.ExceptionHandlers); diff --git a/src/DotNet/Writer/MethodBodyWriterBase.cs b/src/DotNet/Writer/MethodBodyWriterBase.cs index 3d6a648fe..dad3c6fee 100644 --- a/src/DotNet/Writer/MethodBodyWriterBase.cs +++ b/src/DotNet/Writer/MethodBodyWriterBase.cs @@ -158,9 +158,10 @@ protected virtual void WriteInstruction(ref ArrayWriter writer, Instruction inst /// The instruction protected void WriteOpCode(ref ArrayWriter writer, Instruction instr) { var code = instr.OpCode.Code; + var hi = (ushort)code >> 8; if ((ushort)code <= 0xFF) writer.WriteByte((byte)code); - else if (((ushort)code >> 8) == 0xFE) { + else if (hi == 0xFE || (hi >= 0xF0 && hi <= 0xFB)) { writer.WriteByte((byte)((ushort)code >> 8)); writer.WriteByte((byte)code); } From 3532ba7a74a3430d430247f9beff761b3bea1750 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 14 Sep 2020 15:49:36 +0200 Subject: [PATCH 392/511] Update hidden this param type, closes #392 --- src/DotNet/ParameterList.cs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index 17b62ee0e..0363ebd9a 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -118,10 +118,25 @@ internal void UpdateThisParameterType(TypeDef methodDeclaringType) { #endif if (methodDeclaringType is null) hiddenThisParameter.Type = null; - else if (methodDeclaringType.IsValueType) - hiddenThisParameter.Type = new ByRefSig(new ValueTypeSig(methodDeclaringType)); - else - hiddenThisParameter.Type = new ClassSig(methodDeclaringType); + else { + bool isValueType = methodDeclaringType.IsValueType; + ClassOrValueTypeSig instSig; + if (isValueType) + instSig = new ValueTypeSig(methodDeclaringType); + else + instSig = new ClassSig(methodDeclaringType); + TypeSig thisTypeSig; + if (methodDeclaringType.HasGenericParameters) { + int gpCount = methodDeclaringType.GenericParameters.Count; + var genArgs = new List(gpCount); + for (int i = 0; i < gpCount; i++) + genArgs.Add(new GenericVar(i, methodDeclaringType)); + thisTypeSig = new GenericInstSig(instSig, genArgs); + } + else + thisTypeSig = instSig; + hiddenThisParameter.Type = isValueType ? new ByRefSig(thisTypeSig) : thisTypeSig; + } #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif From 523c2d50ba017dde52ebeeacbd3e71e2877b9162 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Mon, 26 Oct 2020 19:42:04 +0100 Subject: [PATCH 393/511] Update build.yml --- .github/workflows/build.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index daac1968a..8d472cac4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Build shell: pwsh @@ -40,11 +40,12 @@ jobs: New-Item -ItemType Directory nuget_files > $null Copy-Item src\bin\Release\*.*nupkg nuget_files - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v2 if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') with: name: nupkg path: nuget_files + if-no-files-found: error - name: Upload to nuget.org if it's a new release if: startsWith(github.ref, 'refs/tags/') @@ -59,7 +60,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Build shell: pwsh From d547cdfb47f53261730c9e1682101e861f92bb6a Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Tue, 10 Nov 2020 23:42:32 +0100 Subject: [PATCH 394/511] Use .NET 5.0 SDK --- .github/workflows/build.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8d472cac4..82573751e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,6 +18,9 @@ on: release: types: released +env: + CI_REQ_DOTNET_SDK_VER: 5.0.100 + jobs: build-windows: name: Build (Windows) @@ -26,6 +29,10 @@ jobs: steps: - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{env.CI_REQ_DOTNET_SDK_VER}} + - name: Build shell: pwsh run: | @@ -62,6 +69,10 @@ jobs: steps: - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{env.CI_REQ_DOTNET_SDK_VER}} + - name: Build shell: pwsh run: ./build.ps1 From 756680e7ba61fba076f315f816f8e1a762f4ba55 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 11 Nov 2020 02:06:10 +0100 Subject: [PATCH 395/511] Use latest C# version --- Examples/Examples.csproj | 3 ++- src/dnlib.csproj | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index cdfb0601a..464ee1e49 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,9 +1,10 @@ - netcoreapp2.1;net45 + net5.0;net45 Exe false + latest diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 43ceb236d..7f2c17d0b 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -43,7 +43,7 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof ..\dnlib.snk true - 8.0 + latest true From 4e0837cb0f4319ffbcdd1642d1973fce203b2177 Mon Sep 17 00:00:00 2001 From: 0xd4d Date: Wed, 11 Nov 2020 02:06:27 +0100 Subject: [PATCH 396/511] Use is not null --- Examples/Example1.cs | 2 +- README.md | 2 +- src/DotNet/AllTypesHelper.cs | 2 +- src/DotNet/AssemblyDef.cs | 18 +- src/DotNet/AssemblyHash.cs | 2 +- src/DotNet/AssemblyNameInfo.cs | 2 +- src/DotNet/AssemblyResolver.cs | 44 +-- src/DotNet/CorLibTypes.cs | 2 +- src/DotNet/CustomAttribute.cs | 4 +- src/DotNet/CustomAttributeCollection.cs | 6 +- src/DotNet/CustomAttributeReader.cs | 20 +- src/DotNet/DeclSecurity.cs | 2 +- src/DotNet/Emit/DynamicMethodBodyReader.cs | 10 +- src/DotNet/Emit/Instruction.cs | 4 +- src/DotNet/Emit/InstructionPrinter.cs | 2 +- src/DotNet/Emit/MethodBody.cs | 2 +- src/DotNet/Emit/MethodBodyReader.cs | 4 +- src/DotNet/Emit/MethodBodyReaderBase.cs | 12 +- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/DotNet/EventDef.cs | 4 +- src/DotNet/ExportedType.cs | 12 +- src/DotNet/FieldDef.cs | 18 +- src/DotNet/FrameworkRedirect.cs | 2 +- src/DotNet/FullNameFactory.cs | 50 +-- src/DotNet/GenericParam.cs | 2 +- src/DotNet/IAssemblyResolver.cs | 6 +- src/DotNet/ICodedToken.cs | 34 +- src/DotNet/ICorLibTypes.cs | 4 +- src/DotNet/ILogger.cs | 4 +- src/DotNet/IResolver.cs | 4 +- src/DotNet/ITypeDefFinder.cs | 16 +- src/DotNet/Importer.cs | 48 +-- src/DotNet/MD/CompressedMetadata.cs | 2 +- src/DotNet/MD/DotNetStream.cs | 2 +- src/DotNet/MD/ENCMetadata.cs | 2 +- src/DotNet/MD/MetadataBase.cs | 28 +- src/DotNet/MD/MetadataFactory.cs | 12 +- src/DotNet/MD/RidList.cs | 4 +- src/DotNet/MD/TablesStream.cs | 8 +- src/DotNet/MD/TablesStream_Read.cs | 6 +- src/DotNet/MarshalType.cs | 4 +- src/DotNet/MemberFinder.cs | 16 +- src/DotNet/MemberRef.cs | 22 +- src/DotNet/MethodDef.cs | 14 +- src/DotNet/MethodSpec.cs | 6 +- src/DotNet/ModuleContext.cs | 2 +- src/DotNet/ModuleDef.cs | 32 +- src/DotNet/ModuleDefMD.cs | 36 +- src/DotNet/ModuleLoader.cs | 6 +- src/DotNet/ParamDef.cs | 4 +- src/DotNet/ParameterList.cs | 12 +- src/DotNet/Pdb/Dss/MDEmitter.cs | 22 +- src/DotNet/Pdb/Dss/MetaDataImport.cs | 6 +- src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs | 14 +- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 2 +- src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs | 2 +- src/DotNet/Pdb/Dss/SymbolReaderImpl.cs | 8 +- src/DotNet/Pdb/Dss/SymbolWriterImpl.cs | 2 +- src/DotNet/Pdb/Managed/DbiDocument.cs | 2 +- src/DotNet/Pdb/Managed/DbiModule.cs | 6 +- src/DotNet/Pdb/Managed/DbiScope.cs | 4 +- src/DotNet/Pdb/Managed/PdbReader.cs | 6 +- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 8 +- src/DotNet/Pdb/PdbReaderContext.cs | 4 +- src/DotNet/Pdb/PdbState.cs | 10 +- .../Pdb/Portable/ImportScopeBlobReader.cs | 6 +- .../Portable/LocalConstantSigBlobReader.cs | 2 +- .../Portable/LocalConstantSigBlobWriter.cs | 4 +- .../PortablePdbCustomDebugInfoReader.cs | 20 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 26 +- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 4 +- src/DotNet/Pdb/SymbolReaderFactory.cs | 6 +- .../WindowsPdb/PdbCustomDebugInfoReader.cs | 10 +- .../PseudoCustomDebugInfoFactory.cs | 10 +- src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs | 16 +- src/DotNet/PropertyDef.cs | 8 +- src/DotNet/ReflectionExtensions.cs | 8 +- src/DotNet/Resolver.cs | 6 +- src/DotNet/ResourceCollection.cs | 16 +- src/DotNet/Resources/BuiltInResourceData.cs | 2 +- src/DotNet/Resources/ResourceDataFactory.cs | 4 +- src/DotNet/Resources/ResourceReader.cs | 4 +- src/DotNet/SigComparer.cs | 324 +++++++++--------- src/DotNet/SignatureReader.cs | 2 +- src/DotNet/TIAHelper.cs | 8 +- src/DotNet/TypeDef.cs | 78 ++--- src/DotNet/TypeDefFinder.cs | 8 +- src/DotNet/TypeHelper.cs | 6 +- src/DotNet/TypeNameParser.cs | 18 +- src/DotNet/TypeRef.cs | 6 +- src/DotNet/TypeSig.cs | 12 +- src/DotNet/TypeSpec.cs | 8 +- src/DotNet/Utils.cs | 4 +- src/DotNet/WinMDHelpers.cs | 14 +- src/DotNet/Writer/BlobHeap.cs | 10 +- src/DotNet/Writer/ByteArrayChunk.cs | 2 +- src/DotNet/Writer/ChunkList.cs | 4 +- src/DotNet/Writer/CustomAttributeWriter.cs | 18 +- src/DotNet/Writer/DeclSecurityWriter.cs | 2 +- src/DotNet/Writer/ManagedExportsWriter.cs | 8 +- src/DotNet/Writer/MarshalBlobWriter.cs | 2 +- src/DotNet/Writer/MaxStackCalculator.cs | 6 +- src/DotNet/Writer/Metadata.cs | 58 ++-- src/DotNet/Writer/MethodBody.cs | 4 +- src/DotNet/Writer/MethodBodyWriter.cs | 2 +- src/DotNet/Writer/ModuleWriter.cs | 8 +- src/DotNet/Writer/ModuleWriterBase.cs | 44 +-- src/DotNet/Writer/NativeModuleWriter.cs | 22 +- src/DotNet/Writer/PreserveTokensMetadata.cs | 2 +- src/DotNet/Writer/RelocDirectory.cs | 6 +- src/DotNet/Writer/SerializerMethodContext.cs | 6 +- src/DotNet/Writer/SignatureWriter.cs | 14 +- src/DotNet/Writer/StringsHeap.cs | 12 +- src/DotNet/Writer/USHeap.cs | 10 +- src/DotNet/Writer/Win32ResourcesChunk.cs | 2 +- src/IO/DataReader.cs | 2 +- src/IO/DataReaderFactoryFactory.cs | 2 +- src/IO/MemoryMappedDataReaderFactory.cs | 2 +- src/PE/PEImage.cs | 4 +- src/PE/PEInfo.cs | 4 +- src/Utils/LazyList.cs | 22 +- src/W32Resources/ResourceName.cs | 2 +- src/W32Resources/Win32Resources.cs | 2 +- 123 files changed, 791 insertions(+), 791 deletions(-) diff --git a/Examples/Example1.cs b/Examples/Example1.cs index 63ef143a3..e2b5dd3e5 100644 --- a/Examples/Example1.cs +++ b/Examples/Example1.cs @@ -18,7 +18,7 @@ public static void Run() { totalNumTypes++; Console.WriteLine(); Console.WriteLine("Type: {0}", type.FullName); - if (!(type.BaseType is null)) + if (type.BaseType is not null) Console.WriteLine(" Base type: {0}", type.BaseType.FullName); Console.WriteLine(" Methods: {0}", type.Methods.Count); diff --git a/README.md b/README.md index 6c6452df8..0cee42416 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ NOTE: VS' debugger crashes if there's a `DebuggableAttribute` attribute and if t ```C# var ca = module.Assembly.CustomAttributes.Find("System.Diagnostics.DebuggableAttribute"); -if (!(ca is null) && ca.ConstructorArguments.Count == 1) { +if (ca is not null && ca.ConstructorArguments.Count == 1) { var arg = ca.ConstructorArguments[0]; // VS' debugger crashes if value == 0x107, so clear EnC bit if (arg.Type.FullName == "System.Diagnostics.DebuggableAttribute/DebuggingModes" && arg.Value is int value && value == 0x107) { diff --git a/src/DotNet/AllTypesHelper.cs b/src/DotNet/AllTypesHelper.cs index a6e5c7465..2dcac1f1e 100644 --- a/src/DotNet/AllTypesHelper.cs +++ b/src/DotNet/AllTypesHelper.cs @@ -14,7 +14,7 @@ readonly struct AllTypesHelper { public static IEnumerable Types(IEnumerable types) { var visited = new Dictionary(); var stack = new Stack>(); - if (!(types is null)) + if (types is not null) stack.Push(types.GetEnumerator()); while (stack.Count > 0) { var enumerator = stack.Pop(); diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 75bdd0e14..bb081eec0 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -379,7 +379,7 @@ public static AssemblyDef Load(string fileName, ModuleCreationOptions options = return asm; } catch { - if (!(module is null)) + if (module is not null) module.Dispose(); throw; } @@ -416,7 +416,7 @@ public static AssemblyDef Load(byte[] data, ModuleCreationOptions options = null return asm; } catch { - if (!(module is null)) + if (module is not null) module.Dispose(); throw; } @@ -453,7 +453,7 @@ public static AssemblyDef Load(IntPtr addr, ModuleCreationOptions options = null return asm; } catch { - if (!(module is null)) + if (module is not null) module.Dispose(); throw; } @@ -494,7 +494,7 @@ public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = nu return asm; } catch { - if (!(module is null)) + if (module is not null) module.Dispose(); throw; } @@ -529,7 +529,7 @@ public TypeDef Find(string fullName, bool isReflectionName) { if (module is null) continue; var type = module.Find(fullName, isReflectionName); - if (!(type is null)) + if (type is not null) return type; } return null; @@ -550,7 +550,7 @@ public TypeDef Find(TypeRef typeRef) { if (module is null) continue; var type = module.Find(typeRef); - if (!(type is null)) + if (type is not null) return type; } return null; @@ -710,14 +710,14 @@ void IListListener.OnLazyAdd(int index, ref ModuleDef module) { void IListListener.OnAdd(int index, ModuleDef module) { if (module is null) return; - if (!(module.Assembly is null)) + if (module.Assembly is not null) throw new InvalidOperationException("Module already has an assembly. Remove it from that assembly before adding it to this assembly."); module.Assembly = this; } /// void IListListener.OnRemove(int index, ModuleDef module) { - if (!(module is null)) + if (module is not null) module.Assembly = null; } @@ -728,7 +728,7 @@ void IListListener.OnResize(int index) { /// void IListListener.OnClear() { foreach (var module in modules.GetEnumerable_NoLock()) { - if (!(module is null)) + if (module is not null) module.Assembly = null; } } diff --git a/src/DotNet/AssemblyHash.cs b/src/DotNet/AssemblyHash.cs index af89ba0b0..22de5f3eb 100644 --- a/src/DotNet/AssemblyHash.cs +++ b/src/DotNet/AssemblyHash.cs @@ -28,7 +28,7 @@ public AssemblyHash(AssemblyHashAlgorithm hashAlgo) => /// public void Dispose() { - if (!(hasher is null)) + if (hasher is not null) ((IDisposable)hasher).Dispose(); } diff --git a/src/DotNet/AssemblyNameInfo.cs b/src/DotNet/AssemblyNameInfo.cs index fe199589d..f2ec9c588 100644 --- a/src/DotNet/AssemblyNameInfo.cs +++ b/src/DotNet/AssemblyNameInfo.cs @@ -253,7 +253,7 @@ public AssemblyNameInfo(AssemblyName asmName) { publicKeyOrToken = (PublicKeyBase)PublicKeyBase.CreatePublicKey(asmName.GetPublicKey()) ?? PublicKeyBase.CreatePublicKeyToken(asmName.GetPublicKeyToken()); name = asmName.Name ?? string.Empty; - culture = !(asmName.CultureInfo is null) && !(asmName.CultureInfo.Name is null) ? asmName.CultureInfo.Name : string.Empty; + culture = asmName.CultureInfo is not null && asmName.CultureInfo.Name is not null ? asmName.CultureInfo.Name : string.Empty; } /// diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index bc1eab8a5..9c194b29e 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -57,7 +57,7 @@ public GacInfo(int version, string prefix, string path, string[] subDirs) { static AssemblyResolver() { gacInfos = new List(); - if (!(Type.GetType("Mono.Runtime") is null)) { + if (Type.GetType("Mono.Runtime") is not null) { var dirs = new Dictionary(StringComparer.OrdinalIgnoreCase); var extraMonoPathsList = new List(); foreach (var prefix in FindMonoPrefixes()) { @@ -83,7 +83,7 @@ static AssemblyResolver() { } var paths = Environment.GetEnvironmentVariable("MONO_PATH"); - if (!(paths is null)) { + if (paths is not null) { foreach (var tmp in paths.Split(Path.PathSeparator)) { var path = tmp.Trim(); if (path != string.Empty && Directory.Exists(path)) @@ -254,7 +254,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { int count = modules.Count; for (int i = 0; i < count; i++) { var module = modules[i]; - if (!(module is null)) + if (module is not null) module.EnableTypeDefFindCache = true; } } @@ -274,7 +274,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { // Dupe assembly. Don't insert it. var dupeModule = resolvedAssembly.ManifestModule; - if (!(dupeModule is null)) + if (dupeModule is not null) dupeModule.Dispose(); return asm1 ?? asm2; #if THREAD_SAFE @@ -289,7 +289,7 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { /// true if 's assembly is cached, false /// if it's not cached because some other assembly with the exact same full name has /// already been cached or if or its assembly is null. - public bool AddToCache(ModuleDef module) => !(module is null) && AddToCache(module.Assembly); + public bool AddToCache(ModuleDef module) => module is not null && AddToCache(module.Assembly); /// /// Add an assembly to the assembly cache @@ -305,7 +305,7 @@ public bool AddToCache(AssemblyDef asm) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (cachedAssemblies.TryGetValue(asmKey, out var cachedAsm) && !(cachedAsm is null)) + if (cachedAssemblies.TryGetValue(asmKey, out var cachedAsm) && cachedAsm is not null) return asm == cachedAsm; cachedAssemblies[asmKey] = asm; return true; @@ -321,7 +321,7 @@ public bool AddToCache(AssemblyDef asm) { /// true if its assembly was removed, false if it wasn't removed /// since it wasn't in the cache, it has no assembly, or was /// null - public bool Remove(ModuleDef module) => !(module is null) && Remove(module.Assembly); + public bool Remove(ModuleDef module) => module is not null && Remove(module.Assembly); /// /// Removes the assembly from the cache @@ -392,13 +392,13 @@ AssemblyDef Resolve2(IAssembly assembly, ModuleDef sourceModule) { return resolvedAssembly; var moduleContext = defaultModuleContext; - if (moduleContext is null && !(sourceModule is null)) + if (moduleContext is null && sourceModule is not null) moduleContext = sourceModule.Context; resolvedAssembly = FindExactAssembly(assembly, PreFindAssemblies(assembly, sourceModule, true), moduleContext) ?? FindExactAssembly(assembly, FindAssemblies(assembly, sourceModule, true), moduleContext) ?? FindExactAssembly(assembly, PostFindAssemblies(assembly, sourceModule, true), moduleContext); - if (!(resolvedAssembly is null)) + if (resolvedAssembly is not null) return resolvedAssembly; if (!findExactMatch) { @@ -428,7 +428,7 @@ AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, Mod try { mod = ModuleDefMD.Load(path, moduleContext); var asm = mod.Assembly; - if (!(asm is null) && asmComparer.Equals(assembly, asm)) { + if (asm is not null && asmComparer.Equals(assembly, asm)) { mod = null; return asm; } @@ -436,7 +436,7 @@ AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, Mod catch { } finally { - if (!(mod is null)) + if (mod is not null) mod.Dispose(); } } @@ -470,10 +470,10 @@ AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumer try { mod = ModuleDefMD.Load(path, moduleContext); var asm = mod.Assembly; - if (!(asm is null) && asmComparer.CompareClosest(assembly, closest, asm) == 1) { - if (!IsCached(closest) && !(closest is null)) { + if (asm is not null && asmComparer.CompareClosest(assembly, closest, asm) == 1) { + if (!IsCached(closest) && closest is not null) { var closeMod = closest.ManifestModule; - if (!(closeMod is null)) + if (closeMod is not null) closeMod.Dispose(); } closest = asm; @@ -483,7 +483,7 @@ AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumer catch { } finally { - if (!(mod is null)) + if (mod is not null) mod.Dispose(); } } @@ -503,7 +503,7 @@ bool IsCached(AssemblyDef asm) { } IEnumerable FindAssemblies2(IAssembly assembly, IEnumerable paths) { - if (!(paths is null)) { + if (paths is not null) { var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); var exts = assembly.IsContentTypeWindowsRuntime ? winMDAssemblyExtensions : assemblyExtensions; foreach (var ext in exts) { @@ -601,14 +601,14 @@ IEnumerable FindAssembliesGacExactly(IAssembly assembly, ModuleDef sourc foreach (var path in FindAssembliesGacExactly(gacInfo, assembly, sourceModule)) yield return path; } - if (!(extraMonoPaths is null)) { + if (extraMonoPaths is not null) { foreach (var path in GetExtraMonoPaths(assembly, sourceModule)) yield return path; } } static IEnumerable GetExtraMonoPaths(IAssembly assembly, ModuleDef sourceModule) { - if (!(extraMonoPaths is null)) { + if (extraMonoPaths is not null) { foreach (var dir in extraMonoPaths) { string file; try { @@ -626,7 +626,7 @@ static IEnumerable GetExtraMonoPaths(IAssembly assembly, ModuleDef sourc IEnumerable FindAssembliesGacExactly(GacInfo gacInfo, IAssembly assembly, ModuleDef sourceModule) { var pkt = PublicKeyBase.ToPublicKeyToken(assembly.PublicKeyOrToken); - if (!(gacInfo is null) && !(pkt is null)) { + if (gacInfo is not null && pkt is not null) { string pktString = pkt.ToString(); string verString = Utils.CreateVersionWithNoUndefinedValues(assembly.Version).ToString(); var cultureString = UTF8String.ToSystemStringOrEmpty(assembly.Culture); @@ -655,14 +655,14 @@ IEnumerable FindAssembliesGacAny(IAssembly assembly, ModuleDef sourceMod foreach (var path in FindAssembliesGacAny(gacInfo, assembly, sourceModule)) yield return path; } - if (!(extraMonoPaths is null)) { + if (extraMonoPaths is not null) { foreach (var path in GetExtraMonoPaths(assembly, sourceModule)) yield return path; } } IEnumerable FindAssembliesGacAny(GacInfo gacInfo, IAssembly assembly, ModuleDef sourceModule) { - if (!(gacInfo is null)) { + if (gacInfo is not null) { var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); foreach (var subDir in gacInfo.SubDirs) { var baseDir = Path.Combine(gacInfo.Path, subDir); @@ -771,7 +771,7 @@ protected IEnumerable GetModulePrivateSearchPaths(ModuleDef module) { } catch { } - if (!(baseDir is null)) + if (baseDir is not null) return new List { baseDir }; return Array2.Empty(); } diff --git a/src/DotNet/CorLibTypes.cs b/src/DotNet/CorLibTypes.cs index c13bc4aa4..8a2f598d9 100644 --- a/src/DotNet/CorLibTypes.cs +++ b/src/DotNet/CorLibTypes.cs @@ -131,7 +131,7 @@ ITypeDefOrRef CreateCorLibTypeRef(bool isCorLib, string name) { var tr = new TypeRefUser(module, "System", name, corLibAssemblyRef); if (isCorLib) { var td = module.Find(tr); - if (!(td is null)) + if (td is not null) return td; } return module.UpdateRowId(tr); diff --git a/src/DotNet/CustomAttribute.cs b/src/DotNet/CustomAttribute.cs index c0699c883..030d27fb2 100644 --- a/src/DotNet/CustomAttribute.cs +++ b/src/DotNet/CustomAttribute.cs @@ -37,7 +37,7 @@ public string TypeFullName { if (ctor is MethodDef mdCtor) { var declType = mdCtor.DeclaringType; - if (!(declType is null)) + if (declType is not null) return declType.FullName; } @@ -48,7 +48,7 @@ public string TypeFullName { /// /// true if the raw custom attribute blob hasn't been parsed /// - public bool IsRawBlob => !(rawData is null); + public bool IsRawBlob => rawData is not null; /// /// Gets the raw custom attribute blob or null if the CA was successfully parsed. diff --git a/src/DotNet/CustomAttributeCollection.cs b/src/DotNet/CustomAttributeCollection.cs index 214f1443b..c3b8a53af 100644 --- a/src/DotNet/CustomAttributeCollection.cs +++ b/src/DotNet/CustomAttributeCollection.cs @@ -30,7 +30,7 @@ public CustomAttributeCollection(int length, object context, Func /// Full name of custom attribute type /// true if the custom attribute type is present, false otherwise - public bool IsDefined(string fullName) => !(Find(fullName) is null); + public bool IsDefined(string fullName) => Find(fullName) is not null; /// /// Removes all custom attributes of a certain type @@ -50,7 +50,7 @@ public void RemoveAll(string fullName) { /// A or null if it wasn't found public CustomAttribute Find(string fullName) { foreach (var ca in this) { - if (!(ca is null) && ca.TypeFullName == fullName) + if (ca is not null && ca.TypeFullName == fullName) return ca; } @@ -64,7 +64,7 @@ public CustomAttribute Find(string fullName) { /// All s of the requested type public IEnumerable FindAll(string fullName) { foreach (var ca in this) { - if (!(ca is null) && ca.TypeFullName == fullName) + if (ca is not null && ca.TypeFullName == fullName) yield return ca; } } diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 21a56a417..46c7db465 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -23,24 +23,24 @@ sealed class CAAssemblyRefFinder : IAssemblyRefFinder { /// public AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { var modAsm = module.Assembly; - if (!(modAsm is null)) { + if (modAsm is not null) { var type = modAsm.Find(nonNestedTypeRef); // If the user added a new type with the same name as a corelib type, don't return it, // only return the type if it is this module's original type. if (type is TypeDefMD td && td.ReaderModule == module) return module.UpdateRowId(new AssemblyRefUser(modAsm)); } - else if (!(module.Find(nonNestedTypeRef) is null)) + else if (module.Find(nonNestedTypeRef) is not null) return AssemblyRef.CurrentAssembly; var corLibAsm = module.Context.AssemblyResolver.Resolve(module.CorLibTypes.AssemblyRef, module); - if (!(corLibAsm is null)) { + if (corLibAsm is not null) { var type = corLibAsm.Find(nonNestedTypeRef); - if (!(type is null)) + if (type is not null) return module.CorLibTypes.AssemblyRef; } - if (!(modAsm is null)) + if (modAsm is not null) return module.UpdateRowId(new AssemblyRefUser(modAsm)); return AssemblyRef.CurrentAssembly; } @@ -409,7 +409,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy case SerializationType.TaggedObject: realArgType = ReadFieldOrPropType(); var arraySig = realArgType as SZArraySig; - if (!(arraySig is null)) + if (arraySig is not null) result = ReadArrayArgument(arraySig); else result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out var tmpType); @@ -418,7 +418,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy // It's ET.Class if it's eg. a ctor System.Type arg type case (SerializationType)ElementType.Class: var tdr = argType as TypeDefOrRefSig; - if (!(tdr is null) && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System") { + if (tdr is not null && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System") { if (tdr.TypeName == "Type") { result = ReadValue(SerializationType.Type, tdr, out realArgType); break; @@ -457,7 +457,7 @@ object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgTy } object ReadEnumValue(TypeSig underlyingType) { - if (!(underlyingType is null)) { + if (underlyingType is not null) { if (underlyingType.ElementType < ElementType.Boolean || underlyingType.ElementType > ElementType.U8) throw new CABlobParserException("Invalid enum underlying type"); return ReadValue((SerializationType)underlyingType.ElementType, underlyingType, out var realArgType); @@ -509,11 +509,11 @@ static TypeSig GetEnumUnderlyingType(TypeSig type) { static TypeDef GetTypeDef(TypeSig type) { if (type is TypeDefOrRefSig tdr) { var td = tdr.TypeDef; - if (!(td is null)) + if (td is not null) return td; var tr = tdr.TypeRef; - if (!(tr is null)) + if (tr is not null) return tr.Resolve(); } diff --git a/src/DotNet/DeclSecurity.cs b/src/DotNet/DeclSecurity.cs index b7724ff6b..76ef83909 100644 --- a/src/DotNet/DeclSecurity.cs +++ b/src/DotNet/DeclSecurity.cs @@ -131,7 +131,7 @@ internal static string GetNet1xXmlStringInternal(IList secAtt if (arg.Type.GetElementType() != ElementType.String) return null; var utf8 = arg.Value as UTF8String; - if (!(utf8 is null)) + if (utf8 is not null) return utf8; if (arg.Value is string s) return s; diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index bf69990fc..abaa8efd4 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -91,16 +91,16 @@ public object Read(object instance) { public bool Exists(object instance) { InitializeField(instance.GetType()); - return !(fieldInfo is null); + return fieldInfo is not null; } void InitializeField(Type type) { - if (!(fieldInfo is null)) + if (fieldInfo is not null) return; var flags = SR.BindingFlags.Instance | SR.BindingFlags.Public | SR.BindingFlags.NonPublic; fieldInfo = type.GetField(fieldName1, flags); - if (fieldInfo is null && !(fieldName2 is null)) + if (fieldInfo is null && fieldName2 is not null) fieldInfo = type.GetField(fieldName2, flags); } } @@ -305,7 +305,7 @@ public bool Read() { } void CreateExceptionHandlers() { - if (!(ehHeader is null)) { + if (ehHeader is not null) { if (ehHeader.Length < 4) return; var reader = new BinaryReader(new MemoryStream(ehHeader)); @@ -362,7 +362,7 @@ void CreateExceptionHandlers() { } } } - else if (!(ehInfos is null)) { + else if (ehInfos is not null) { foreach (var ehInfo in CreateExceptionInfos(ehInfos)) { var tryStart = GetInstructionThrow((uint)ehInfo.StartAddr); var tryEnd = GetInstruction((uint)ehInfo.EndAddr); diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index da35f889e..b3b4ba406 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -405,7 +405,7 @@ void CalculateStackUsageCall(Code code, out int pushes, out int pops) { pops += sig.Params.Count; var paramsAfterSentinel = sig.ParamsAfterSentinel; - if (!(paramsAfterSentinel is null)) + if (paramsAfterSentinel is not null) pops += paramsAfterSentinel.Count; if (implicitThis && code != Code.Newobj) pops++; @@ -714,7 +714,7 @@ public int GetParameterIndex() { case Code.Ldarg: case Code.Ldarg_S: var parameter = Operand as Parameter; - if (!(parameter is null)) + if (parameter is not null) return parameter.Index; break; } diff --git a/src/DotNet/Emit/InstructionPrinter.cs b/src/DotNet/Emit/InstructionPrinter.cs index 290caa3c7..632c0d607 100644 --- a/src/DotNet/Emit/InstructionPrinter.cs +++ b/src/DotNet/Emit/InstructionPrinter.cs @@ -67,7 +67,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string sb.Append(extra); if (op is IFullName) sb.Append((op as IFullName).FullName); - else if (!(op is null)) + else if (op is not null) sb.Append(op.ToString()); else sb.Append("null"); diff --git a/src/DotNet/Emit/MethodBody.cs b/src/DotNet/Emit/MethodBody.cs index 9bed3b686..d21b39fa7 100644 --- a/src/DotNet/Emit/MethodBody.cs +++ b/src/DotNet/Emit/MethodBody.cs @@ -150,7 +150,7 @@ public PdbMethod PdbMethod { /// /// true if is not null /// - public bool HasPdbMethod => !(PdbMethod is null); + public bool HasPdbMethod => PdbMethod is not null; /// /// Gets the total size of the body in the PE file, including header, IL bytes, and exception handlers. diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index 2c19ae2d1..01950f8f6 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -429,7 +429,7 @@ protected override MethodSig ReadInlineSig(Instruction instr) { if (standAloneSig is null) return null; var sig = standAloneSig.MethodSig; - if (!(sig is null)) + if (sig is not null) sig.OriginalToken = standAloneSig.MDToken.Raw; return sig; } @@ -453,7 +453,7 @@ void ReadExceptionHandlers(out uint totalBodySize) { } bool canSaveTotalBodySize; DataReader ehReader; - if (!(exceptionsReader is null)) { + if (exceptionsReader is not null) { canSaveTotalBodySize = false; ehReader = exceptionsReader.Value; } diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index 0d4e840b0..dc2aee896 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -208,7 +208,7 @@ protected Instruction GetInstruction(uint offset) { /// protected Instruction GetInstructionThrow(uint offset) { var instr = GetInstruction(offset); - if (!(instr is null)) + if (instr is not null) return instr; throw new InvalidOperationException($"There's no instruction @ {offset:X4}"); } @@ -240,7 +240,7 @@ OpCode ReadOpCode() { var op = reader.ReadByte(); if (op == 0xFE) return OpCodes.TwoByteOpCodes[reader.ReadByte()]; - if (op >= 0xF0 && op <= 0xFB && !(context is null) && reader.BytesLeft >= 1) { + if (op >= 0xF0 && op <= 0xFB && context is not null && reader.BytesLeft >= 1) { if (context.GetExperimentalOpCode(op, reader.ReadByte()) is OpCode opCode) return opCode; else @@ -542,7 +542,7 @@ protected bool Add(ExceptionHandler eh) { /// at the end of the method. /// The instruction offset uint GetOffset(Instruction instr) { - if (!(instr is null)) + if (instr is not null) return instr.Offset; var instructions = this.instructions; if (instructions.Count == 0) @@ -561,7 +561,7 @@ public virtual void RestoreMethod(MethodDef method) { body.Variables.Clear(); var locals = this.locals; - if (!(locals is null)) { + if (locals is not null) { int count = locals.Count; for (int i = 0; i < count; i++) body.Variables.Add(locals[i]); @@ -569,7 +569,7 @@ public virtual void RestoreMethod(MethodDef method) { body.Instructions.Clear(); var instructions = this.instructions; - if (!(instructions is null)) { + if (instructions is not null) { int count = instructions.Count; for (int i = 0; i < count; i++) body.Instructions.Add(instructions[i]); @@ -577,7 +577,7 @@ public virtual void RestoreMethod(MethodDef method) { body.ExceptionHandlers.Clear(); var exceptionHandlers = this.exceptionHandlers; - if (!(exceptionHandlers is null)) { + if (exceptionHandlers is not null) { int count = exceptionHandlers.Count; for (int i = 0; i < count; i++) body.ExceptionHandlers.Add(exceptionHandlers[i]); diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index 28d8ef5e6..dbb01405c 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -60,7 +60,7 @@ static Type GetTypeUsingTypeBuilder(IntPtr address) { var mb = tb.DefineMethod(METHOD_NAME, SR.MethodAttributes.Static, typeof(void), Array2.Empty()); try { - if (!(setMethodBodyMethodInfo is null)) + if (setMethodBodyMethodInfo is not null) return GetTypeNET45(tb, mb, address); else return GetTypeNET40(tb, mb, address); diff --git a/src/DotNet/EventDef.cs b/src/DotNet/EventDef.cs index 7c1c4c27f..b299136d7 100644 --- a/src/DotNet/EventDef.cs +++ b/src/DotNet/EventDef.cs @@ -221,9 +221,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (!(currentDeclaringType is null)) + if (currentDeclaringType is not null) currentDeclaringType.Events.Remove(this); // Will set DeclaringType2 = null - if (!(value is null)) + if (value is not null) value.Events.Add(this); // Will set DeclaringType2 = value } } diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 84d7cff6f..44aa0f8c9 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -86,7 +86,7 @@ protected virtual void InitializeCustomDebugInfos() => public bool IsValueType { get { var td = Resolve(); - return !(td is null) && td.IsValueType; + return td is not null && td.IsValueType; } } @@ -231,7 +231,7 @@ void InitializeImplementation() { /// /// true if it's nested within another /// - public bool IsNested => !(DeclaringType is null); + public bool IsNested => DeclaringType is not null; /// /// Gets the declaring type, if any @@ -510,7 +510,7 @@ static TypeDef Resolve(ModuleDef sourceModule, ExportedType et) { break; var td = etAsm.Find(et.FullName, false); - if (!(td is null)) + if (td is not null) return td; et = FindExportedType(etAsm, et); @@ -542,7 +542,7 @@ static ExportedType FindExportedType(AssemblyDef asm, ExportedType et) { /// If the type couldn't be resolved public TypeDef ResolveThrow() { var type = Resolve(); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); } @@ -555,12 +555,12 @@ public TypeRef ToTypeRef() { TypeRef result = null, prev = null; var mod = module; IImplementation impl = this; - for (int i = 0; i < MAX_LOOP_ITERS && !(impl is null); i++) { + for (int i = 0; i < MAX_LOOP_ITERS && impl is not null; i++) { if (impl is ExportedType et) { var newTr = mod.UpdateRowId(new TypeRefUser(mod, et.TypeNamespace, et.TypeName)); if (result is null) result = newTr; - if (!(prev is null)) + if (prev is not null) prev.ResolutionScope = newTr; prev = newTr; diff --git a/src/DotNet/FieldDef.cs b/src/DotNet/FieldDef.cs index 2bbaf726f..1e72ac34b 100644 --- a/src/DotNet/FieldDef.cs +++ b/src/DotNet/FieldDef.cs @@ -370,7 +370,7 @@ void InitializeConstant() { public bool HasCustomAttributes => CustomAttributes.Count > 0; /// - public bool HasImplMap => !(ImplMap is null); + public bool HasImplMap => ImplMap is not null; /// /// Gets/sets the declaring type (owner type) @@ -381,9 +381,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (!(currentDeclaringType is null)) + if (currentDeclaringType is not null) currentDeclaringType.Fields.Remove(this); // Will set DeclaringType2 = null - if (!(value is null)) + if (value is not null) value.Fields.Add(this); // Will set DeclaringType2 = value } } @@ -431,12 +431,12 @@ public FieldSig FieldSig { /// /// true if is not null /// - public bool HasLayoutInfo => !(FieldOffset is null); + public bool HasLayoutInfo => FieldOffset is not null; /// /// true if is not null /// - public bool HasConstant => !(Constant is null); + public bool HasConstant => Constant is not null; /// /// Gets the constant element type or if there's no constant @@ -451,7 +451,7 @@ public ElementType ElementType { /// /// true if is not null /// - public bool HasMarshalType => !(MarshalType is null); + public bool HasMarshalType => MarshalType is not null; /// /// Gets/sets the field type @@ -460,7 +460,7 @@ public TypeSig FieldType { get => FieldSig.GetFieldType(); set { var sig = FieldSig; - if (!(sig is null)) + if (sig is not null) sig.Type = value; } } @@ -677,11 +677,11 @@ bool GetClassSize(TypeDef declaringType, TypeSig ts, int ptrSize, out uint size) return false; var td = tdrs.TypeDef; - if (!(td is null)) + if (td is not null) return TypeDef.GetClassSize(td, out size); var tr = tdrs.TypeRef; - if (!(tr is null)) + if (tr is not null) return TypeDef.GetClassSize(tr.Resolve(), out size); return false; diff --git a/src/DotNet/FrameworkRedirect.cs b/src/DotNet/FrameworkRedirect.cs index a361008c7..7208342fd 100644 --- a/src/DotNet/FrameworkRedirect.cs +++ b/src/DotNet/FrameworkRedirect.cs @@ -317,7 +317,7 @@ public static bool TryApplyFrameworkRedirect(IAssembly assembly, ModuleDef sourc TryApplyFrameworkRedirectCore(assembly, sourceModule, out redirectedAssembly); static bool TryApplyFrameworkRedirectCore(IAssembly assembly, ModuleDef sourceModule, out IAssembly redirectedAssembly) { - if (!(sourceModule is null)) { + if (sourceModule is not null) { if (sourceModule.IsClr40) return TryApplyFrameworkRedirect(assembly, frmRedir4, out redirectedAssembly); if (sourceModule.IsClr20) diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index b20854b3a..11ed94c62 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -68,7 +68,7 @@ public static bool MustUseAssemblyName(ModuleDef module, IType type, bool allowC return true; // If it's present in this module, but it's a corlib type, then we will need the // assembly name. - return !(module.Find(tr) is null); + return module.Find(tr) is not null; } else return true; @@ -228,7 +228,7 @@ public static string PropertyFullName(string declaringType, UTF8String name, Cal /// Property full name public static StringBuilder PropertyFullNameSB(string declaringType, UTF8String name, CallingConventionSig propertySig, IList typeGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (!(typeGenArgs is null)) { + if (typeGenArgs is not null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } @@ -260,7 +260,7 @@ public static string EventFullName(string declaringType, UTF8String name, ITypeD /// Property full name public static StringBuilder EventFullNameSB(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef, IList typeGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (!(typeGenArgs is null)) { + if (typeGenArgs is not null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } @@ -292,7 +292,7 @@ public static string FieldFullName(string declaringType, string name, FieldSig f /// Field full name public static StringBuilder FieldFullNameSB(string declaringType, string name, FieldSig fieldSig, IList typeGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (!(typeGenArgs is null)) { + if (typeGenArgs is not null) { fnc.genericArguments = new GenericArguments(); fnc.genericArguments.PushTypeArgs(typeGenArgs); } @@ -328,11 +328,11 @@ public static string MethodFullName(string declaringType, string name, MethodSig /// Method full name public static StringBuilder MethodFullNameSB(string declaringType, string name, MethodSig methodSig, IList typeGenArgs, IList methodGenArgs, MethodDef gppMethod, StringBuilder sb) { var fnc = new FullNameFactory(false, null, sb); - if (!(typeGenArgs is null) || !(methodGenArgs is null)) + if (typeGenArgs is not null || methodGenArgs is not null) fnc.genericArguments = new GenericArguments(); - if (!(typeGenArgs is null)) + if (typeGenArgs is not null) fnc.genericArguments.PushTypeArgs(typeGenArgs); - if (!(methodGenArgs is null)) + if (methodGenArgs is not null) fnc.genericArguments.PushMethodArgs(methodGenArgs); fnc.CreateMethodFullName(declaringType, name, methodSig, gppMethod); return fnc.sb ?? new StringBuilder(); @@ -811,11 +811,11 @@ public static string FullName(TypeSig typeSig, bool isReflection, IFullNameFacto /// The full name public static StringBuilder FullNameSB(TypeSig typeSig, bool isReflection, IFullNameFactoryHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { var fnc = new FullNameFactory(isReflection, helper, sb); - if (!(typeGenArgs is null) || !(methodGenArgs is null)) + if (typeGenArgs is not null || methodGenArgs is not null) fnc.genericArguments = new GenericArguments(); - if (!(typeGenArgs is null)) + if (typeGenArgs is not null) fnc.genericArguments.PushTypeArgs(typeGenArgs); - if (!(methodGenArgs is null)) + if (methodGenArgs is not null) fnc.genericArguments.PushMethodArgs(methodGenArgs); fnc.CreateFullName(typeSig); return fnc.sb ?? new StringBuilder(); @@ -1029,7 +1029,7 @@ IType GetDefinitionType(IType type) { GenericInstSig gis; if (sig is TypeDefOrRefSig tdr) type = GetDefinitionType(tdr.TypeDefOrRef); - else if (!((gis = sig as GenericInstSig) is null)) + else if ((gis = sig as GenericInstSig) is not null) type = GetDefinitionType(gis.GenericType); else type = GetDefinitionType(sig.Next); @@ -1166,7 +1166,7 @@ void CreateFullName(TypeDef typeDef) { } var declaringTypeDef = typeDef.DeclaringType; - if (!(declaringTypeDef is null)) { + if (declaringTypeDef is not null) { CreateFullName(declaringTypeDef); AddNestedTypeSeparator(); } @@ -1717,13 +1717,13 @@ IScope GetScope(TypeRef typeRef) { var scope = typeRef.ResolutionScope; if (scope is null) result = null; //TODO: Check ownerModule's ExportedType table - else if (!((tr = scope as TypeRef) is null)) + else if ((tr = scope as TypeRef) is not null) result = GetScope(tr); - else if (!((asmRef = scope as AssemblyRef) is null)) + else if ((asmRef = scope as AssemblyRef) is not null) result = asmRef; - else if (!((modRef = scope as ModuleRef) is null)) + else if ((modRef = scope as ModuleRef) is not null) result = modRef; - else if (!((modDef = scope as ModuleDef) is null)) + else if ((modDef = scope as ModuleDef) is not null) result = modDef; else result = null; // Should never be reached @@ -2062,7 +2062,7 @@ IAssembly GetDefinitionAssembly(ExportedType exportedType) { var scope = exportedType.Implementation; if (scope is ExportedType et) result = GetDefinitionAssembly(et); - else if (!((asmRef = scope as AssemblyRef) is null)) + else if ((asmRef = scope as AssemblyRef) is not null) result = asmRef; else if (scope is FileDef) { var ownerModule = GetOwnerModule(exportedType); @@ -2089,13 +2089,13 @@ IScope GetScope(ExportedType exportedType) { var scope = exportedType.Implementation; if (scope is ExportedType et) result = GetScope(et); - else if (!((asmRef = scope as AssemblyRef) is null)) + else if ((asmRef = scope as AssemblyRef) is not null) result = asmRef; - else if (!((file = scope as FileDef) is null)) { + else if ((file = scope as FileDef) is not null) { var ownerModule = GetOwnerModule(exportedType); //TODO: Not all modules' names are equal to the name in FileDef.Name var modRef = new ModuleRefUser(ownerModule, file.Name); - if (!(ownerModule is null)) + if (ownerModule is not null) ownerModule.UpdateRowId(modRef); result = modRef; } @@ -2116,11 +2116,11 @@ void CreateFieldFullName(string declaringType, string name, FieldSig fieldSig) { CreateFullName(fieldSig?.Type); sb.Append(' '); - if (!(declaringType is null)) { + if (declaringType is not null) { sb.Append(declaringType); sb.Append("::"); } - if (!(name is null)) + if (name is not null) sb.Append(name); } @@ -2132,11 +2132,11 @@ void CreateMethodFullName(string declaringType, string name, MethodBaseSig metho CreateFullName(methodSig.RetType); sb.Append(' '); - if (!(declaringType is null)) { + if (declaringType is not null) { sb.Append(declaringType); sb.Append("::"); } - if (!(name is null)) + if (name is not null) sb.Append(name); if (methodSig.Generic) { @@ -2185,7 +2185,7 @@ void CreatePropertyFullName(string declaringType, UTF8String name, CallingConven void CreateEventFullName(string declaringType, UTF8String name, ITypeDefOrRef typeDefOrRef) { CreateFullName(typeDefOrRef); sb.Append(' '); - if (!(declaringType is null)) { + if (declaringType is not null) { sb.Append(declaringType); sb.Append("::"); } diff --git a/src/DotNet/GenericParam.cs b/src/DotNet/GenericParam.cs index 06ea94e6e..82cb469b4 100644 --- a/src/DotNet/GenericParam.cs +++ b/src/DotNet/GenericParam.cs @@ -272,7 +272,7 @@ internal virtual void OnLazyAdd2(int index, ref GenericParamConstraint value) { /// void IListListener.OnAdd(int index, GenericParamConstraint value) { - if (!(value.Owner is null)) + if (value.Owner is not null) throw new InvalidOperationException("Generic param constraint is already owned by another generic param. Set Owner to null first."); value.Owner = this; } diff --git a/src/DotNet/IAssemblyResolver.cs b/src/DotNet/IAssemblyResolver.cs index 448287708..2d3eee45f 100644 --- a/src/DotNet/IAssemblyResolver.cs +++ b/src/DotNet/IAssemblyResolver.cs @@ -58,7 +58,7 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, IAssembly as if (assembly is null) return null; var asm = self.Resolve(assembly, sourceModule); - if (!(asm is null)) + if (asm is not null) return asm; throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); } @@ -75,7 +75,7 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, AssemblyName if (assembly is null) return null; var asm = self.Resolve(new AssemblyNameInfo(assembly), sourceModule); - if (!(asm is null)) + if (asm is not null) return asm; throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); } @@ -92,7 +92,7 @@ public static AssemblyDef ResolveThrow(this IAssemblyResolver self, string asmFu if (asmFullName is null) return null; var asm = self.Resolve(new AssemblyNameInfo(asmFullName), sourceModule); - if (!(asm is null)) + if (asm is not null) return asm; throw new AssemblyResolveException($"Could not resolve assembly: {asmFullName}"); } diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index 036f4e986..a592c9ccf 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -163,15 +163,15 @@ public static partial class Extensions { public static bool IsCorLib(this IAssembly asm) { if (asm is AssemblyDef asmDef) { var manifestModule = asmDef.ManifestModule; - if (!(manifestModule is null)) { + if (manifestModule is not null) { var isCorModule = manifestModule.IsCoreLibraryModule; - if (!(isCorModule is null)) + if (isCorModule is not null) return isCorModule.Value; } } string asmName; - return !(asm is null) && + return asm is not null && UTF8String.IsNullOrEmpty(asm.Culture) && ((asmName = UTF8String.ToSystemStringOrEmpty(asm.Name)).Equals("mscorlib", StringComparison.OrdinalIgnoreCase) || asmName.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) || @@ -206,14 +206,14 @@ public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType = t return null; var module = type.Module; - if (!(module is null)) { + if (module is not null) { var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); - if (!(corLibType is null)) + if (corLibType is not null) return corLibType; } var td = type as TypeDef; - if (!(td is null)) + if (td is not null) return CreateClassOrValueType(type, checkValueType ? td.IsValueType : false); if (type is TypeRef tr) { @@ -398,17 +398,17 @@ public static ITypeDefOrRef GetBaseType(this ITypeDefOrRef tdr, bool throwOnReso return null; var git = ts.TypeSig.ToGenericInstSig(); - if (!(git is null)) + if (git is not null) tdr = git.GenericType?.TypeDefOrRef; else tdr = ts.TypeSig.ToTypeDefOrRefSig()?.TypeDefOrRef; td = tdr as TypeDef; - if (!(td is null)) + if (td is not null) return td.BaseType; tr = tdr as TypeRef; - if (!(tr is null)) { + if (tr is not null) { td = throwOnResolveFailure ? tr.ResolveThrow() : tr.Resolve(); return td?.BaseType; } @@ -434,11 +434,11 @@ public static TypeDef ResolveTypeDef(this ITypeDefOrRef tdr) { tdr = tdr.ScopeType; td = tdr as TypeDef; - if (!(td is null)) + if (td is not null) return td; tr = tdr as TypeRef; - if (!(tr is null)) + if (tr is not null) return tr.Resolve(); return null; @@ -462,11 +462,11 @@ public static TypeDef ResolveTypeDefThrow(this ITypeDefOrRef tdr) { tdr = tdr.ScopeType; td = tdr as TypeDef; - if (!(td is null)) + if (td is not null) return td; tr = tdr as TypeRef; - if (!(tr is null)) + if (tr is not null) return tr.ResolveThrow(); throw new TypeResolveException($"Could not resolve type: {tdr} ({tdr?.DefinitionAssembly})"); @@ -525,11 +525,11 @@ public static MethodDef ResolveMethodDef(this IMethod method) { if (method is MethodSpec ms) { md = ms.Method as MethodDef; - if (!(md is null)) + if (md is not null) return md; mr = ms.Method as MemberRef; - if (!(mr is null)) + if (mr is not null) return mr.ResolveMethod(); } @@ -553,11 +553,11 @@ public static MethodDef ResolveMethodDefThrow(this IMethod method) { if (method is MethodSpec ms) { md = ms.Method as MethodDef; - if (!(md is null)) + if (md is not null) return md; mr = ms.Method as MemberRef; - if (!(mr is null)) + if (mr is not null) return mr.ResolveMethodThrow(); } diff --git a/src/DotNet/ICorLibTypes.cs b/src/DotNet/ICorLibTypes.cs index 25f7dae31..ab924df4b 100644 --- a/src/DotNet/ICorLibTypes.cs +++ b/src/DotNet/ICorLibTypes.cs @@ -121,13 +121,13 @@ public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, ITypeDefOrR if (type is TypeDef td && td.DeclaringType is null && - !((corLibType = self.GetCorLibTypeSig(td.Namespace, td.Name, td.DefinitionAssembly)) is null)) { + (corLibType = self.GetCorLibTypeSig(td.Namespace, td.Name, td.DefinitionAssembly)) is not null) { return corLibType; } if (type is TypeRef tr && !(tr.ResolutionScope is TypeRef) && - !((corLibType = self.GetCorLibTypeSig(tr.Namespace, tr.Name, tr.DefinitionAssembly)) is null)) { + (corLibType = self.GetCorLibTypeSig(tr.Namespace, tr.Name, tr.DefinitionAssembly)) is not null) { return corLibType; } diff --git a/src/DotNet/ILogger.cs b/src/DotNet/ILogger.cs index cce66bbcc..32952e4f0 100644 --- a/src/DotNet/ILogger.cs +++ b/src/DotNet/ILogger.cs @@ -410,7 +410,7 @@ public sealed class DummyLogger : ILogger { /// errors. It must have a public constructor that takes a as the only /// argument. public DummyLogger(Type exceptionToThrow) { - if (!(exceptionToThrow is null)) { + if (exceptionToThrow is not null) { if (!exceptionToThrow.IsSubclassOf(typeof(Exception))) throw new ArgumentException($"Not a System.Exception sub class: {exceptionToThrow.GetType()}"); ctor = exceptionToThrow.GetConstructor(new Type[] { typeof(string) }); @@ -421,7 +421,7 @@ public DummyLogger(Type exceptionToThrow) { /// public void Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) { - if (loggerEvent == LoggerEvent.Error && !(ctor is null)) + if (loggerEvent == LoggerEvent.Error && ctor is not null) throw (Exception)ctor.Invoke(new object[] { string.Format(format, args) }); } diff --git a/src/DotNet/IResolver.cs b/src/DotNet/IResolver.cs index 78ed3419d..136e2dc6e 100644 --- a/src/DotNet/IResolver.cs +++ b/src/DotNet/IResolver.cs @@ -61,7 +61,7 @@ public static partial class Extensions { /// If the type couldn't be resolved public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef, ModuleDef sourceModule) { var type = self.Resolve(typeRef, sourceModule); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not resolve type: {typeRef} ({typeRef?.DefinitionAssembly})"); } @@ -75,7 +75,7 @@ public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef, Mod /// If the method/field couldn't be resolved public static IMemberForwarded ResolveThrow(this IMemberRefResolver self, MemberRef memberRef) { var memberDef = self.Resolve(memberRef); - if (!(memberDef is null)) + if (memberDef is not null) return memberDef; throw new MemberRefResolveException($"Could not resolve method/field: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); } diff --git a/src/DotNet/ITypeDefFinder.cs b/src/DotNet/ITypeDefFinder.cs index 3efa6956a..ab0b69ca2 100644 --- a/src/DotNet/ITypeDefFinder.cs +++ b/src/DotNet/ITypeDefFinder.cs @@ -35,7 +35,7 @@ public static partial class Extensions { /// If type couldn't be found public static TypeDef FindThrow(this ITypeDefFinder self, TypeRef typeRef) { var type = self.Find(typeRef); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not find type: {typeRef}"); } @@ -52,7 +52,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, TypeRef typeRef) { /// If type couldn't be found public static TypeDef FindThrow(this ITypeDefFinder self, string fullName, bool isReflectionName) { var type = self.Find(fullName, isReflectionName); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not find type: {fullName}"); } @@ -74,7 +74,7 @@ public static TypeDef FindThrow(this ITypeDefFinder self, string fullName, bool /// If type couldn't be found public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) { var type = self.Find(fullName, false); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not find type: {fullName}"); } @@ -96,7 +96,7 @@ public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) /// If type couldn't be found public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullName) { var type = self.Find(fullName, true); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not find type: {fullName}"); } @@ -108,7 +108,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// The type ref /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) => !(self.Find(typeRef) is null); + public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) => self.Find(typeRef) is not null; /// /// Checks whether a exists @@ -119,7 +119,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// type names are separated by a + character. If false, nested type names /// are separated by a / character. /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, string fullName, bool isReflectionName) => !(self.Find(fullName, isReflectionName) is null); + public static bool TypeExists(this ITypeDefFinder self, string fullName, bool isReflectionName) => self.Find(fullName, isReflectionName) is not null; /// /// Checks whether a exists @@ -127,7 +127,7 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// Full name of the type (no assembly information). Nested types are separated by / /// true if the exists, false otherwise - public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) => !(self.Find(fullName, false) is null); + public static bool TypeExistsNormal(this ITypeDefFinder self, string fullName) => self.Find(fullName, false) is not null; /// /// Checks whether a exists @@ -135,6 +135,6 @@ public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullN /// this /// Full name of the type (no assembly information). Nested types are separated by + /// true if the exists, false otherwise - public static bool TypeExistsReflection(this ITypeDefFinder self, string fullName) => !(self.Find(fullName, true) is null); + public static bool TypeExistsReflection(this ITypeDefFinder self, string fullName) => self.Find(fullName, true) is not null; } } diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 01d57b850..f19f1aa9a 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -307,7 +307,7 @@ TypeDef GetDeclaringType(MemberRef mr) { return td; td = TryResolve(mr.Class as TypeRef) as TypeDef; - if (!(td is null)) + if (td is not null) return td; var modRef = mr.Class as ModuleRef; @@ -335,7 +335,7 @@ bool IsThisModule(TypeRef tr) { } bool IsThisModule(ModuleRef modRef) => - !(modRef is null) && + modRef is not null && module.Name == modRef.Name && Equals(module.Assembly, modRef.DefinitionAssembly); @@ -364,7 +364,7 @@ IResolutionScope CreateScopeReference(Type type) { return null; var asmName = type.Assembly.GetName(); var modAsm = module.Assembly; - if (!(modAsm is null)) { + if (modAsm is not null) { if (UTF8String.ToSystemStringOrEmpty(modAsm.Name).Equals(asmName.Name, StringComparison.OrdinalIgnoreCase)) { if (UTF8String.ToSystemStringOrEmpty(module.Name).Equals(type.Module.ScopeName, StringComparison.OrdinalIgnoreCase)) return module; @@ -400,12 +400,12 @@ TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList op // Assume all required modifiers are closer to the real type. // Assume all modifiers should be applied in the same order as in the lists. - if (!(requiredModifiers is null)) { + if (requiredModifiers is not null) { foreach (var modifier in requiredModifiers) ts = new CModReqdSig(Import(modifier), ts); } - if (!(optionalModifiers is null)) { + if (optionalModifiers is not null) { foreach (var modifier in optionalModifiers) ts = new CModOptSig(Import(modifier), ts); } @@ -657,13 +657,13 @@ public IType Import(IType type) { TypeSpec ts; TypeSig sig; - if (!((td = type as TypeDef) is null)) + if ((td = type as TypeDef) is not null) result = Import(td); - else if (!((tr = type as TypeRef) is null)) + else if ((tr = type as TypeRef) is not null) result = Import(tr); - else if (!((ts = type as TypeSpec) is null)) + else if ((ts = type as TypeSpec) is not null) result = Import(ts); - else if (!((sig = type as TypeSig) is null)) + else if ((sig = type as TypeSig) is not null) result = Import(sig); else result = null; @@ -683,7 +683,7 @@ public ITypeDefOrRef Import(TypeDef type) { if (TryToUseTypeDefs && type.Module == module) return type; var mapped = mapper?.Map(type); - if (!(mapped is null)) + if (mapped is not null) return mapped; return Import2(type); } @@ -696,7 +696,7 @@ TypeRef Import2(TypeDef type) { TypeRef result; var declType = type.DeclaringType; - if (!(declType is null)) + if (declType is not null) result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, Import2(declType))); else result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, CreateScopeReference(type.DefinitionAssembly, type.Module))); @@ -709,7 +709,7 @@ IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { if (defAsm is null) return null; var modAsm = module.Assembly; - if (!(defMod is null) && !(defAsm is null) && !(modAsm is null)) { + if (defMod is not null && defAsm is not null && modAsm is not null) { if (UTF8String.CaseInsensitiveEquals(modAsm.Name, defAsm.Name)) { if (UTF8String.CaseInsensitiveEquals(module.Name, defMod.Name)) return module; @@ -729,7 +729,7 @@ IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { /// The imported type or null public ITypeDefOrRef Import(TypeRef type) { var mapped = mapper?.Map(type); - if (!(mapped is null)) + if (mapped is not null) return mapped; return TryResolve(Import2(type)); @@ -743,7 +743,7 @@ TypeRef Import2(TypeRef type) { TypeRef result; var declaringType = type.DeclaringType; - if (!(declaringType is null)) + if (declaringType is not null) result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, Import2(declaringType))); else result = module.UpdateRowId(new TypeRefUser(module, type.Namespace, type.Name, CreateScopeReference(type.DefinitionAssembly, type.Module))); @@ -845,7 +845,7 @@ public TypeSig Import(TypeSig type) { TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); - if (!(corLibType is null)) + if (corLibType is not null) return corLibType; if (isValueType) @@ -923,7 +923,7 @@ T Import(T sig, T old) where T : MethodBaseSig { sig.Params.Add(Import(p)); sig.GenParamCount = old.GenParamCount; var paramsAfterSentinel = sig.ParamsAfterSentinel; - if (!(paramsAfterSentinel is null)) { + if (paramsAfterSentinel is not null) { foreach (var p in old.ParamsAfterSentinel) paramsAfterSentinel.Add(Import(p)); } @@ -1000,9 +1000,9 @@ public IField Import(IField field) { MemberRef mr; FieldDef fd; - if (!((fd = field as FieldDef) is null)) + if ((fd = field as FieldDef) is not null) result = Import(fd); - else if (!((mr = field as MemberRef) is null)) + else if ((mr = field as MemberRef) is not null) result = Import(mr); else result = null; @@ -1027,11 +1027,11 @@ public IMethod Import(IMethod method) { MethodSpec ms; MemberRef mr; - if (!((md = method as MethodDef) is null)) + if ((md = method as MethodDef) is not null) result = Import(md); - else if (!((ms = method as MethodSpec) is null)) + else if ((ms = method as MethodSpec) is not null) result = Import(ms); - else if (!((mr = method as MemberRef) is null)) + else if ((mr = method as MemberRef) is not null) result = Import(mr); else result = null; @@ -1053,7 +1053,7 @@ public IField Import(FieldDef field) { if (!recursionCounter.Increment()) return null; var mapped = mapper?.Map(field); - if (!(mapped is null)) { + if (mapped is not null) { recursionCounter.Decrement(); return mapped; } @@ -1087,7 +1087,7 @@ public IMethod Import(MethodDef method) { if (!recursionCounter.Increment()) return null; var mapped = mapper?.Map(method); - if (!(mapped is null)) { + if (mapped is not null) { recursionCounter.Decrement(); return mapped; } @@ -1129,7 +1129,7 @@ public MemberRef Import(MemberRef memberRef) { if (!recursionCounter.Increment()) return null; var mapped = mapper?.Map(memberRef); - if (!(mapped is null)) { + if (mapped is not null) { recursionCounter.Decrement(); return mapped; } diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index 3bccb2764..50f2b0f7f 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -97,7 +97,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui if (tablesStream is null) throw new BadImageFormatException("Missing MD stream"); - if (!(pdbStream is null)) + if (pdbStream is not null) tablesStream.Initialize(pdbStream.TypeSystemTableRows); else tablesStream.Initialize(null); diff --git a/src/DotNet/MD/DotNetStream.cs b/src/DotNet/MD/DotNetStream.cs index f43a36d80..b6e6f3cf1 100644 --- a/src/DotNet/MD/DotNetStream.cs +++ b/src/DotNet/MD/DotNetStream.cs @@ -104,7 +104,7 @@ public void Dispose() { protected virtual void Dispose(bool disposing) { if (disposing) { var mdReaderFactory = this.mdReaderFactory; - if (!(mdReaderFactory is null)) + if (mdReaderFactory is not null) mdReaderFactory.DataReaderInvalidated -= DataReaderFactory_DataReaderInvalidated; streamHeader = null; this.mdReaderFactory = null; diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 83a81b3fe..ed8b4ccf9 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -169,7 +169,7 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui if (tablesStream is null) throw new BadImageFormatException("Missing MD stream"); - if (!(pdbStream is null)) + if (pdbStream is not null) tablesStream.Initialize(pdbStream.TypeSystemTableRows); else tablesStream.Initialize(null); diff --git a/src/DotNet/MD/MetadataBase.cs b/src/DotNet/MD/MetadataBase.cs index 92903e054..c770c2e9a 100644 --- a/src/DotNet/MD/MetadataBase.cs +++ b/src/DotNet/MD/MetadataBase.cs @@ -214,7 +214,7 @@ protected MetadataBase(IPEImage peImage, ImageCor20Header cor20Header, MetadataH isStandalonePortablePdb = false; } catch { - if (!(peImage is null)) + if (peImage is not null) peImage.Dispose(); throw; } @@ -234,14 +234,14 @@ internal MetadataBase(MetadataHeader mdHeader, bool isStandalonePortablePdb) { public void Initialize(DataReaderFactory mdReaderFactory) { mdReaderFactoryToDisposeLater = mdReaderFactory; uint metadataBaseOffset; - if (!(peImage is null)) { + if (peImage is not null) { Debug.Assert(mdReaderFactory is null); - Debug.Assert(!(cor20Header is null)); + Debug.Assert(cor20Header is not null); metadataBaseOffset = (uint)peImage.ToFileOffset(cor20Header.Metadata.VirtualAddress); mdReaderFactory = peImage.DataReaderFactory; } else { - Debug.Assert(!(mdReaderFactory is null)); + Debug.Assert(mdReaderFactory is not null); metadataBaseOffset = 0; } InitializeInternal(mdReaderFactory, metadataBaseOffset); @@ -425,7 +425,7 @@ public override uint GetOwnerTypeOfField(uint fieldRid) { } void InitializeInverseFieldOwnerRidList() { - if (!(fieldRidToTypeDefRid is null)) + if (fieldRidToTypeDefRid is not null) return; var newFieldRidToTypeDefRid = new uint[tablesStream.FieldTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -452,7 +452,7 @@ public override uint GetOwnerTypeOfMethod(uint methodRid) { } void InitializeInverseMethodOwnerRidList() { - if (!(methodRidToTypeDefRid is null)) + if (methodRidToTypeDefRid is not null) return; var newMethodRidToTypeDefRid = new uint[tablesStream.MethodTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -479,7 +479,7 @@ public override uint GetOwnerTypeOfEvent(uint eventRid) { } void InitializeInverseEventOwnerRidList() { - if (!(eventRidToTypeDefRid is null)) + if (eventRidToTypeDefRid is not null) return; var newEventRidToTypeDefRid = new uint[tablesStream.EventTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -506,7 +506,7 @@ public override uint GetOwnerTypeOfProperty(uint propertyRid) { } void InitializeInversePropertyOwnerRidList() { - if (!(propertyRidToTypeDefRid is null)) + if (propertyRidToTypeDefRid is not null) return; var newPropertyRidToTypeDefRid = new uint[tablesStream.PropertyTable.Rows]; var ownerList = GetTypeDefRidList(); @@ -539,7 +539,7 @@ public override uint GetOwnerOfGenericParam(uint gpRid) { } void InitializeInverseGenericParamOwnerRidList() { - if (!(gpRidToOwnerRid is null)) + if (gpRidToOwnerRid is not null) return; var gpTable = tablesStream.GenericParamTable; var newGpRidToOwnerRid = new uint[gpTable.Rows]; @@ -584,7 +584,7 @@ public override uint GetOwnerOfGenericParamConstraint(uint gpcRid) { } void InitializeInverseGenericParamConstraintOwnerRidList() { - if (!(gpcRidToOwnerRid is null)) + if (gpcRidToOwnerRid is not null) return; var gpcTable = tablesStream.GenericParamConstraintTable; var newGpcRidToOwnerRid = new uint[gpcTable.Rows]; @@ -622,7 +622,7 @@ public override uint GetOwnerOfParam(uint paramRid) { } void InitializeInverseParamOwnerRidList() { - if (!(paramRidToOwnerRid is null)) + if (paramRidToOwnerRid is not null) return; var newParamRidToOwnerRid = new uint[tablesStream.ParamTable.Rows]; @@ -662,7 +662,7 @@ void InitializeNestedClassesDictionary() { var nestedRidsDict = new Dictionary((int)table.Rows); var nestedRids = new List((int)table.Rows); // Need it so we add the rids in correct order for (uint rid = 1; rid <= table.Rows; rid++) { - if (!(validTypeDefRids is null) && !validTypeDefRids.ContainsKey(rid)) + if (validTypeDefRids is not null && !validTypeDefRids.ContainsKey(rid)) continue; if (!tablesStream.TryReadNestedClassRow(rid, out var row)) continue; // Should never happen since rid is valid @@ -687,7 +687,7 @@ void InitializeNestedClassesDictionary() { var newNonNestedTypes = new List((int)(destTable.Rows - nestedRidsDict.Count)); for (uint rid = 1; rid <= destTable.Rows; rid++) { - if (!(validTypeDefRids is null) && !validTypeDefRids.ContainsKey(rid)) + if (validTypeDefRids is not null && !validTypeDefRids.ContainsKey(rid)) continue; if (nestedRidsDict.ContainsKey(rid)) continue; @@ -740,7 +740,7 @@ protected virtual void Dispose(bool disposing) { guidStream?.Dispose(); tablesStream?.Dispose(); var as2 = allStreams; - if (!(as2 is null)) { + if (as2 is not null) { foreach (var stream in as2) stream?.Dispose(); } diff --git a/src/DotNet/MD/MetadataFactory.cs b/src/DotNet/MD/MetadataFactory.cs index a0820108f..1904ed960 100644 --- a/src/DotNet/MD/MetadataFactory.cs +++ b/src/DotNet/MD/MetadataFactory.cs @@ -22,7 +22,7 @@ internal static MetadataBase Load(string fileName, CLRRuntimeReaderKind runtime) return Load(peImage = new PEImage(fileName), runtime); } catch { - if (!(peImage is null)) + if (peImage is not null) peImage.Dispose(); throw; } @@ -34,7 +34,7 @@ internal static MetadataBase Load(byte[] data, CLRRuntimeReaderKind runtime) { return Load(peImage = new PEImage(data), runtime); } catch { - if (!(peImage is null)) + if (peImage is not null) peImage.Dispose(); throw; } @@ -48,7 +48,7 @@ internal static MetadataBase Load(IntPtr addr, CLRRuntimeReaderKind runtime) { return Load(peImage = new PEImage(addr, ImageLayout.Memory, true), runtime); } catch { - if (!(peImage is null)) + if (peImage is not null) peImage.Dispose(); peImage = null; } @@ -57,7 +57,7 @@ internal static MetadataBase Load(IntPtr addr, CLRRuntimeReaderKind runtime) { return Load(peImage = new PEImage(addr, ImageLayout.File, true), runtime); } catch { - if (!(peImage is null)) + if (peImage is not null) peImage.Dispose(); throw; } @@ -69,7 +69,7 @@ internal static MetadataBase Load(IntPtr addr, ImageLayout imageLayout, CLRRunti return Load(peImage = new PEImage(addr, imageLayout, true), runtime); } catch { - if (!(peImage is null)) + if (peImage is not null) peImage.Dispose(); throw; } @@ -148,7 +148,7 @@ static MetadataBase Create(IPEImage peImage, CLRRuntimeReaderKind runtime, bool return md; } catch { - if (!(md is null)) + if (md is not null) md.Dispose(); throw; } diff --git a/src/DotNet/MD/RidList.cs b/src/DotNet/MD/RidList.cs index fe1a54c29..62ed3d5df 100644 --- a/src/DotNet/MD/RidList.cs +++ b/src/DotNet/MD/RidList.cs @@ -54,7 +54,7 @@ namespace dnlib.DotNet.MD { /// A rid or 0 if is invalid public uint this[int index] { get { - if (!(rids is null)) { + if (rids is not null) { if ((uint)index >= (uint)rids.Count) return 0; return rids[index]; @@ -119,7 +119,7 @@ bool MoveNextOther() { current = 0; return false; } - if (!(rids is null)) + if (rids is not null) current = rids[(int)index]; else current = startRid + index; diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 488451306..0f52e1289 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -214,7 +214,7 @@ public void Initialize(uint[] typeSystemTableRows) { var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out int maxPresentTables); - if (!(typeSystemTableRows is null)) + if (typeSystemTableRows is not null) maxPresentTables = DotNetTableSizes.normalMaxTables; mdTables = new MDTable[tableInfos.Length]; @@ -235,7 +235,7 @@ public void Initialize(uint[] typeSystemTableRows) { extraData = reader.ReadUInt32(); var debugSizes = sizes; - if (!(typeSystemTableRows is null)) { + if (typeSystemTableRows is not null) { debugSizes = new uint[sizes.Length]; for (int i = 0; i < 64; i++) { if (DotNetTableSizes.IsSystemTable((Table)i)) @@ -333,9 +333,9 @@ void InitializeTables() { protected override void Dispose(bool disposing) { if (disposing) { var mt = mdTables; - if (!(mt is null)) { + if (mt is not null) { foreach (var mdTable in mt) { - if (!(mdTable is null)) + if (mdTable is not null) mdTable.Dispose(); } mdTables = null; diff --git a/src/DotNet/MD/TablesStream_Read.cs b/src/DotNet/MD/TablesStream_Read.cs index 7ff05fbc1..6f8dc7a0a 100644 --- a/src/DotNet/MD/TablesStream_Read.cs +++ b/src/DotNet/MD/TablesStream_Read.cs @@ -142,7 +142,7 @@ public bool TryReadMethodRow(uint rid, out RawMethodRow row) { return false; } var mrr = methodRowReader; - if (!(mrr is null) && mrr.TryReadRow(rid, out row)) + if (mrr is not null && mrr.TryReadRow(rid, out row)) return true; var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; @@ -1142,7 +1142,7 @@ public bool TryReadColumn(MDTable table, uint rid, ColumnInfo column, out uint v return false; } var cr = columnReader; - if (!(cr is null) && cr.ReadColumn(table, rid, column, out value)) + if (cr is not null && cr.ReadColumn(table, rid, column, out value)) return true; var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize + (uint)column.Offset; @@ -1160,7 +1160,7 @@ internal bool TryReadColumn24(MDTable table, uint rid, ColumnInfo column, out ui return false; } var cr = columnReader; - if (!(cr is null) && cr.ReadColumn(table, rid, column, out value)) + if (cr is not null && cr.ReadColumn(table, rid, column, out value)) return true; var reader = table.DataReader; reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize + (uint)column.Offset; diff --git a/src/DotNet/MarshalType.cs b/src/DotNet/MarshalType.cs index 066f230bc..432e51e47 100644 --- a/src/DotNet/MarshalType.cs +++ b/src/DotNet/MarshalType.cs @@ -121,7 +121,7 @@ public ITypeDefOrRef UserDefinedSubType { /// /// true if is valid /// - public bool IsUserDefinedSubTypeValid => !(userDefinedSubType is null); + public bool IsUserDefinedSubTypeValid => userDefinedSubType is not null; /// /// Default constructor @@ -160,7 +160,7 @@ public SafeArrayMarshalType(VariantType vt, ITypeDefOrRef userDefinedSubType) /// public override string ToString() { var udt = userDefinedSubType; - if (!(udt is null)) + if (udt is not null) return $"{nativeType} ({vt}, {udt})"; return $"{nativeType} ({vt})"; } diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index 330209cd6..89564d731 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -343,7 +343,7 @@ void Add(IEnumerable eds) { void Add(EventDef ed) { if (ed is null || EventDefs.ContainsKey(ed)) return; - if (!(ed.DeclaringType is null) && ed.DeclaringType.Module != validModule) + if (ed.DeclaringType is not null && ed.DeclaringType.Module != validModule) return; EventDefs[ed] = true; Push(ed.EventType); @@ -365,7 +365,7 @@ void Add(IEnumerable fds) { void Add(FieldDef fd) { if (fd is null || FieldDefs.ContainsKey(fd)) return; - if (!(fd.DeclaringType is null) && fd.DeclaringType.Module != validModule) + if (fd.DeclaringType is not null && fd.DeclaringType.Module != validModule) return; FieldDefs[fd] = true; Add(fd.CustomAttributes); @@ -427,7 +427,7 @@ void Add(IEnumerable methods) { void Add(MethodDef md) { if (md is null || MethodDefs.ContainsKey(md)) return; - if (!(md.DeclaringType is null) && md.DeclaringType.Module != validModule) + if (md.DeclaringType is not null && md.DeclaringType.Module != validModule) return; MethodDefs[md] = true; Add(md.Signature); @@ -474,12 +474,12 @@ void Add(IEnumerable instrs) { case OperandType.InlineVar: case OperandType.ShortInlineVar: var local = instr.Operand as Local; - if (!(local is null)) { + if (local is not null) { Add(local); break; } var arg = instr.Operand as Parameter; - if (!(arg is null)) { + if (arg is not null) { Add(arg); break; } @@ -568,7 +568,7 @@ void Add(MethodOverride mo) { void Add(MethodSpec ms) { if (ms is null || MethodSpecs.ContainsKey(ms)) return; - if (!(ms.Method is null) && !(ms.Method.DeclaringType is null) && ms.Method.DeclaringType.Module != validModule) + if (ms.Method is not null && ms.Method.DeclaringType is not null && ms.Method.DeclaringType.Module != validModule) return; MethodSpecs[ms] = true; Push(ms.Method); @@ -586,7 +586,7 @@ void Add(IEnumerable pds) { void Add(PropertyDef pd) { if (pd is null || PropertyDefs.ContainsKey(pd)) return; - if (!(pd.DeclaringType is null) && pd.DeclaringType.Module != validModule) + if (pd.DeclaringType is not null && pd.DeclaringType.Module != validModule) return; PropertyDefs[pd] = true; Add(pd.Type); @@ -661,7 +661,7 @@ void Add(TypeSig ts) { return; TypeSigs[ts] = true; - for (; !(ts is null); ts = ts.Next) { + for (; ts is not null; ts = ts.Next) { switch (ts.ElementType) { case ElementType.Void: case ElementType.Boolean: diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index 159d7d414..ef1fe8325 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -124,7 +124,7 @@ public ITypeDefOrRef DeclaringType { if (owner is ModuleRef mr) { var tr = GetGlobalTypeRef(mr); - if (!(module is null)) + if (module is not null) return module.UpdateRowId(tr); return tr; } @@ -137,7 +137,7 @@ TypeRefUser GetGlobalTypeRef(ModuleRef mr) { if (module is null) return CreateDefaultGlobalTypeRef(mr); var globalType = module.GlobalType; - if (!(globalType is null) && new SigComparer().Equals(module, mr)) + if (globalType is not null && new SigComparer().Equals(module, mr)) return new TypeRefUser(module, globalType.Namespace, globalType.Name, mr); var asm = module.Assembly; if (asm is null) @@ -153,7 +153,7 @@ TypeRefUser GetGlobalTypeRef(ModuleRef mr) { TypeRefUser CreateDefaultGlobalTypeRef(ModuleRef mr) { var tr = new TypeRefUser(module, string.Empty, "", mr); - if (!(module is null)) + if (module is not null) module.UpdateRowId(tr); return tr; } @@ -175,12 +175,12 @@ TypeRefUser CreateDefaultGlobalTypeRef(ModuleRef mr) { /// /// true if this is a method reference ( != null) /// - public bool IsMethodRef => !(MethodSig is null); + public bool IsMethodRef => MethodSig is not null; /// /// true if this is a field reference ( != null) /// - public bool IsFieldRef => !(FieldSig is null); + public bool IsFieldRef => FieldSig is not null; /// /// Gets/sets the method sig @@ -238,7 +238,7 @@ public TypeSig ReturnType { get => MethodSig?.RetType; set { var ms = MethodSig; - if (!(ms is null)) + if (ms is not null) ms.RetType = value; } } @@ -258,10 +258,10 @@ public string FullName { typeGenArgs = sig.GenericArguments; } var methodSig = MethodSig; - if (!(methodSig is null)) + if (methodSig is not null) return FullNameFactory.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null, null, null); var fieldSig = FieldSig; - if (!(fieldSig is null)) + if (fieldSig is not null) return FullNameFactory.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs, null); return string.Empty; } @@ -305,7 +305,7 @@ public IMemberForwarded Resolve() { /// If the method/field couldn't be resolved public IMemberForwarded ResolveThrow() { var memberDef = Resolve(); - if (!(memberDef is null)) + if (memberDef is not null) return memberDef; throw new MemberRefResolveException($"Could not resolve method/field: {this} ({this.GetDefinitionAssembly()})"); } @@ -323,7 +323,7 @@ public IMemberForwarded ResolveThrow() { /// If the field couldn't be resolved public FieldDef ResolveFieldThrow() { var field = ResolveField(); - if (!(field is null)) + if (field is not null) return field; throw new MemberRefResolveException($"Could not resolve field: {this} ({this.GetDefinitionAssembly()})"); } @@ -341,7 +341,7 @@ public FieldDef ResolveFieldThrow() { /// If the method couldn't be resolved public MethodDef ResolveMethodThrow() { var method = ResolveMethod(); - if (!(method is null)) + if (method is not null) return method; throw new MemberRefResolveException($"Could not resolve method: {this} ({this.GetDefinitionAssembly()})"); } diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 8fb4aa5a4..9b58f7b1e 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -348,9 +348,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (!(currentDeclaringType is null)) + if (currentDeclaringType is not null) currentDeclaringType.Methods.Remove(this); // Will set DeclaringType2 = null - if (!(value is null)) + if (value is not null) value.Methods.Add(this); // Will set DeclaringType2 = value } } @@ -419,7 +419,7 @@ public NativeMethodBody NativeBody { /// /// true if it has a /// - public bool HasBody => !(Body is null); + public bool HasBody => Body is not null; /// /// true if there's at least one in @@ -429,7 +429,7 @@ public NativeMethodBody NativeBody { /// /// true if is not null /// - public bool HasImplMap => !(ImplMap is null); + public bool HasImplMap => ImplMap is not null; /// /// Gets the full name @@ -494,7 +494,7 @@ public TypeSig ReturnType { get => MethodSig?.RetType; set { var ms = MethodSig; - if (!(ms is null)) + if (ms is not null) ms.RetType = value; } } @@ -934,7 +934,7 @@ internal virtual void OnLazyAdd2(int index, ref GenericParam value) { /// void IListListener.OnAdd(int index, GenericParam value) { - if (!(value.Owner is null)) + if (value.Owner is not null) throw new InvalidOperationException("Generic param is already owned by another type/method. Set Owner to null first."); value.Owner = this; } @@ -964,7 +964,7 @@ internal virtual void OnLazyAdd2(int index, ref ParamDef value) { /// void IListListener.OnAdd(int index, ParamDef value) { - if (!(value.DeclaringMethod is null)) + if (value.DeclaringMethod is not null) throw new InvalidOperationException("Param is already owned by another method. Set DeclaringMethod to null first."); value.DeclaringMethod = this; } diff --git a/src/DotNet/MethodSpec.cs b/src/DotNet/MethodSpec.cs index a064e9636..de3393acf 100644 --- a/src/DotNet/MethodSpec.cs +++ b/src/DotNet/MethodSpec.cs @@ -95,7 +95,7 @@ MethodSig IMethod.MethodSig { get => method?.MethodSig; set { var m = method; - if (!(m is null)) + if (m is not null) m.MethodSig = value; } } @@ -108,7 +108,7 @@ public UTF8String Name { } set { var m = method; - if (!(m is null)) + if (m is not null) m.Name = value; } } @@ -142,7 +142,7 @@ public string FullName { if (m is MemberRef memberRef) { var methodSig = memberRef.MethodSig; - if (!(methodSig is null)) { + if (methodSig is not null) { var gis = (memberRef.Class as TypeSpec)?.TypeSig as GenericInstSig; var typeGenArgs = gis?.GenericArguments; return FullNameFactory.MethodFullName(memberRef.GetDeclaringTypeFullName(), memberRef.Name, methodSig, typeGenArgs, methodGenArgs, null, null); diff --git a/src/DotNet/ModuleContext.cs b/src/DotNet/ModuleContext.cs index ee963194a..b0ccfe00e 100644 --- a/src/DotNet/ModuleContext.cs +++ b/src/DotNet/ModuleContext.cs @@ -66,7 +66,7 @@ public ModuleContext(IResolver resolver) public ModuleContext(IAssemblyResolver assemblyResolver, IResolver resolver) { this.assemblyResolver = assemblyResolver; this.resolver = resolver; - if (resolver is null && !(assemblyResolver is null)) + if (resolver is null && assemblyResolver is not null) this.resolver = new Resolver(assemblyResolver); } diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 684a1ae29..881b888a9 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -305,12 +305,12 @@ public MethodDef EntryPoint { /// /// true if is non-null /// - public bool IsManagedEntryPointValid => !(ManagedEntryPoint is null); + public bool IsManagedEntryPointValid => ManagedEntryPoint is not null; /// /// true if is non-null /// - public bool IsEntryPointValid => !(EntryPoint is null); + public bool IsEntryPointValid => EntryPoint is not null; /// /// Gets a list of all s @@ -449,7 +449,7 @@ public bool EnableTypeDefFindCache { public bool IsManifestModule { get { var asm = assembly; - return !(asm is null) && asm.ManifestModule == this; + return asm is not null && asm.ManifestModule == this; } } @@ -551,7 +551,7 @@ public string RuntimeVersion { public WinMDStatus WinMDStatus { get { var cval = cachedWinMDStatus; - if (!(cval is null)) + if (cval is not null) return cval.Value; cachedWinMDStatus = cval = CalculateWinMDStatus(RuntimeVersion); return cval.Value; @@ -582,7 +582,7 @@ public WinMDStatus WinMDStatus { public string RuntimeVersionWinMD { get { var rtver = runtimeVersionWinMD; - if (!(rtver is null)) + if (rtver is not null) return rtver; runtimeVersionWinMD = rtver = CalculateRuntimeVersionWinMD(RuntimeVersion); return rtver; @@ -597,7 +597,7 @@ public string RuntimeVersionWinMD { public string WinMDVersion { get { var ver = winMDVersion; - if (!(ver is null)) + if (ver is not null) return ver; winMDVersion = ver = CalculateWinMDVersion(RuntimeVersion); return ver; @@ -859,7 +859,7 @@ protected virtual void Dispose(bool disposing) { if (!disposing) return; var tdf = typeDefFinder; - if (!(tdf is null)) { + if (tdf is not null) { tdf.Dispose(); typeDefFinder = null; } @@ -1086,13 +1086,13 @@ public void SetPdbState(PdbState pdbState) { if (pdbState is null) throw new ArgumentNullException(nameof(pdbState)); var orig = Interlocked.CompareExchange(ref this.pdbState, pdbState, null); - if (!(orig is null)) + if (orig is not null) throw new InvalidOperationException("PDB file has already been initialized"); } uint GetCor20RuntimeVersion() { var rtVer = Cor20HeaderRuntimeVersion; - if (!(rtVer is null)) + if (rtVer is not null) return rtVer.Value; return IsClr1x ? 0x00020000U : 0x00020005; } @@ -1162,17 +1162,17 @@ public int GetPointerSize(int defaultPointerSize, int prefer32bitPointerSize) { /// void IListListener.OnLazyAdd(int index, ref TypeDef value) { #if DEBUG - if (!(value.DeclaringType is null)) - throw new InvalidOperationException("Added type's !(DeclaringType is null)"); + if (value.DeclaringType is not null) + throw new InvalidOperationException("Added type's DeclaringType is not null"); #endif value.Module2 = this; } /// void IListListener.OnAdd(int index, TypeDef value) { - if (!(value.DeclaringType is null)) + if (value.DeclaringType is not null) throw new InvalidOperationException("Nested type is already owned by another type. Set DeclaringType to null first."); - if (!(value.Module is null)) + if (value.Module is not null) throw new InvalidOperationException("Type is already owned by another module. Remove it from that module's type list."); value.Module2 = this; } @@ -1230,11 +1230,11 @@ public TypeDef Find(ITypeDefOrRef typeRef) { return null; td = sig.TypeDef; - if (!(td is null)) + if (td is not null) return td.Module == this ? td : null; tr = sig.TypeRef; - if (!(tr is null)) + if (tr is not null) return Find(tr); return null; @@ -1395,7 +1395,7 @@ protected static bool IsGreaterAssemblyRefVersion(AssemblyRef found, AssemblyRef return true; var foundVer = found.Version; var newVer = newOne.Version; - return foundVer is null || (!(newVer is null) && newVer >= foundVer); + return foundVer is null || (newVer is not null && newVer >= foundVer); } ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 4c8d323ca..99c194cf9 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -388,11 +388,11 @@ void InitializePdb(ModuleCreationOptions options) { } SymbolReader CreateSymbolReader(ModuleCreationOptions options) { - if (!(options.PdbFileOrData is null)) { + if (options.PdbFileOrData is not null) { var pdbFileName = options.PdbFileOrData as string; if (!string.IsNullOrEmpty(pdbFileName)) { var symReader = SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbFileName); - if (!(symReader is null)) + if (symReader is not null) return symReader; } @@ -416,11 +416,11 @@ SymbolReader CreateSymbolReader(ModuleCreationOptions options) { public void LoadPdb(SymbolReader symbolReader) { if (symbolReader is null) return; - if (!(pdbState is null)) + if (pdbState is not null) throw new InvalidOperationException("PDB file has already been initialized"); var orig = Interlocked.CompareExchange(ref pdbState, new PdbState(symbolReader, this), null); - if (!(orig is null)) + if (orig is not null) throw new InvalidOperationException("PDB file has already been initialized"); } @@ -581,7 +581,7 @@ AssemblyRef FindCorLibAssemblyRef() { corLibAsmRef = asmRef; } } - if (!(corLibAsmRef is null)) + if (corLibAsmRef is not null) return corLibAsmRef; foreach (var corlib in corlibs) { @@ -592,13 +592,13 @@ AssemblyRef FindCorLibAssemblyRef() { if (IsGreaterAssemblyRefVersion(corLibAsmRef, asmRef)) corLibAsmRef = asmRef; } - if (!(corLibAsmRef is null)) + if (corLibAsmRef is not null) return corLibAsmRef; } // If we've loaded mscorlib itself, it won't have any AssemblyRefs to itself. var asm = Assembly; - if (!(asm is null) && (asm.IsCorLib() || !(Find("System.Object", false) is null))) { + if (asm is not null && (asm.IsCorLib() || Find("System.Object", false) is not null)) { IsCoreLibraryModule = true; return UpdateRowId(new AssemblyRefUser(asm)); } @@ -612,7 +612,7 @@ AssemblyRef FindCorLibAssemblyRef() { /// AssemblyRef CreateDefaultCorLibAssemblyRef() { var asmRef = GetAlternativeCorLibReference(); - if (!(asmRef is null)) + if (asmRef is not null) return UpdateRowId(asmRef); if (IsClr40) @@ -657,7 +657,7 @@ protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { var md = metadata; - if (!(md is null)) + if (md is not null) md.Dispose(); metadata = null; } @@ -1373,12 +1373,12 @@ internal ModuleDefMD ReadModule(uint fileRid, AssemblyDef owner) { catch { module = null; } - if (!(module is null)) { + if (module is not null) { // share context module.context = context; var asm = module.Assembly; - if (!(asm is null) && asm != owner) + if (asm is not null && asm != owner) asm.Modules.Remove(module); } return module; @@ -1396,7 +1396,7 @@ internal RidList GetModuleRidList() { } void InitializeModuleList() { - if (!(moduleRidList is null)) + if (moduleRidList is not null) return; uint rows = TablesStream.FileTable.Rows; var newModuleRidList = new List((int)rows); @@ -1409,7 +1409,7 @@ void InitializeModuleList() { if (!fileDef.ContainsMetadata) continue; var pathName = GetValidFilename(baseDir, UTF8String.ToSystemString(fileDef.Name)); - if (!(pathName is null)) + if (pathName is not null) newModuleRidList.Add(fileRid); } Interlocked.CompareExchange(ref moduleRidList, new StrongBox(RidList.Create(newModuleRidList)), null); @@ -1663,7 +1663,7 @@ public IManagedEntryPoint GetManagedEntryPoint() { /// A or null if none internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, GenericParamContext gpContext) { var mDec = methodDecrypter; - if (!(mDec is null) && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out var mb)) { + if (mDec is not null && mDec.GetMethodBody(method.OrigRid, rva, method.Parameters, gpContext, out var mb)) { if (mb is CilBody cilBody) return InitializeBodyFromPdb(method, cilBody); return mb; @@ -1687,7 +1687,7 @@ internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttrib /// Returns originak value CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body) { var ps = pdbState; - if (!(ps is null)) + if (ps is not null) ps.InitializeMethodBody(this, method, body); return body; } @@ -1697,7 +1697,7 @@ internal void InitializeCustomDebugInfos(MethodDefMD method, CilBody body, IList return; var ps = pdbState; - if (!(ps is null)) + if (ps is not null) ps.InitializeCustomDebugInfos(method, body, customDebugInfos); } @@ -1708,9 +1708,9 @@ internal void InitializeCustomDebugInfos(MethodDefMD method, CilBody body, IList /// A non-null string public string ReadUserString(uint token) { var sDec = stringDecrypter; - if (!(sDec is null)) { + if (sDec is not null) { var s = sDec.ReadUserString(token); - if (!(s is null)) + if (s is not null) return s; } return USStream.ReadNoNull(token & 0x00FFFFFF); diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index 380fe30ae..f723d9b20 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -65,7 +65,7 @@ void Load() { void Process() { while (stack.Count != 0) { - if (!(cancellationToken is null)) + if (cancellationToken is not null) cancellationToken.ThrowIfCancellationRequested(); var o = stack.Pop(); LoadObj(o); @@ -236,13 +236,13 @@ void Load(IMDTokenProvider mdt) { case Table.ManifestResource: var rsrc = mdt as Resource; - if (!(rsrc is null)) { + if (rsrc is not null) { Load(rsrc); break; } var mr = mdt as ManifestResource; - if (!(mr is null)) { + if (mr is not null) { Load(mr); break; } diff --git a/src/DotNet/ParamDef.cs b/src/DotNet/ParamDef.cs index 797cbba5e..1b001d028 100644 --- a/src/DotNet/ParamDef.cs +++ b/src/DotNet/ParamDef.cs @@ -209,7 +209,7 @@ protected virtual void InitializeCustomDebugInfos() => /// /// true if is not null /// - public bool HasConstant => !(Constant is null); + public bool HasConstant => Constant is not null; /// /// Gets the constant element type or if there's no constant @@ -224,7 +224,7 @@ public ElementType ElementType { /// /// true if is not null /// - public bool HasMarshalType => !(MarshalType is null); + public bool HasMarshalType => MarshalType is not null; /// public string FullName { diff --git a/src/DotNet/ParameterList.cs b/src/DotNet/ParameterList.cs index 0363ebd9a..080de79e3 100644 --- a/src/DotNet/ParameterList.cs +++ b/src/DotNet/ParameterList.cs @@ -216,7 +216,7 @@ ParamDef FindParamDef_NoLock(Parameter param) { int count = paramDefs.Count; for (int i = 0; i < count; i++) { var paramDef = paramDefs[i]; - if (!(paramDef is null) && paramDef.Sequence == seq) + if (paramDef is not null && paramDef.Sequence == seq) return paramDef; } return null; @@ -238,7 +238,7 @@ internal void CreateParamDef(Parameter param) { theLock.EnterWriteLock(); try { #endif var paramDef = FindParamDef_NoLock(param); - if (!(paramDef is null)) + if (paramDef is not null) return; if (param.IsHiddenThisParameter) { hiddenThisParamDef = UpdateRowId_NoLock(new ParamDefUser(UTF8String.Empty, ushort.MaxValue, 0)); @@ -419,7 +419,7 @@ public TypeSig Type { get => typeSig; set { typeSig = value; - if (!(parameterList is null)) + if (parameterList is not null) parameterList.TypeUpdated(this); } } @@ -437,7 +437,7 @@ public TypeSig Type { /// /// true if it has a /// - public bool HasParamDef => !(ParamDef is null); + public bool HasParamDef => ParamDef is not null; /// /// Gets the name from . If is null, @@ -450,7 +450,7 @@ public string Name { } set { var paramDef = ParamDef; - if (!(paramDef is null)) + if (paramDef is not null) paramDef.Name = value; } } @@ -507,7 +507,7 @@ internal Parameter(ParameterList parameterList, int paramIndex, int methodSigInd /// Creates a if it doesn't already exist /// public void CreateParamDef() { - if (!(parameterList is null)) + if (parameterList is not null) parameterList.CreateParamDef(this); } diff --git a/src/DotNet/Pdb/Dss/MDEmitter.cs b/src/DotNet/Pdb/Dss/MDEmitter.cs index 1238debe3..5b38003fb 100644 --- a/src/DotNet/Pdb/Dss/MDEmitter.cs +++ b/src/DotNet/Pdb/Dss/MDEmitter.cs @@ -37,28 +37,28 @@ public override void GetMethodProps(uint mb, uint* pClass, ushort* szMethod, uin var method = tokenToMethodDef[mb]; var row = metadata.TablesHeap.MethodTable[mb & 0x00FFFFFF]; - if (!(pClass is null)) + if (pClass is not null) *pClass = new MDToken(MD.Table.TypeDef, metadata.GetRid(method.DeclaringType)).Raw; - if (!(pdwAttr is null)) + if (pdwAttr is not null) *pdwAttr = row.Flags; - if (!(ppvSigBlob is null)) + if (ppvSigBlob is not null) *ppvSigBlob = IntPtr.Zero; - if (!(pcbSigBlob is null)) + if (pcbSigBlob is not null) *pcbSigBlob = 0; - if (!(pulCodeRVA is null)) + if (pulCodeRVA is not null) *pulCodeRVA = row.RVA; - if (!(pdwImplFlags is null)) + if (pdwImplFlags is not null) *pdwImplFlags = row.ImplFlags; string name = method.Name.String ?? string.Empty; int len = (int)Math.Min((uint)name.Length + 1, cchMethod); - if (!(szMethod is null)) { + if (szMethod is not null) { for (int i = 0; i < len - 1; i++, szMethod++) *szMethod = (ushort)name[i]; if (len > 0) *szMethod = 0; } - if (!(pchMethod is null)) + if (pchMethod is not null) *pchMethod = (uint)len; } @@ -67,9 +67,9 @@ public override void GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef throw new ArgumentException(); var type = tokenToTypeDef[td]; var row = metadata.TablesHeap.TypeDefTable[td & 0x00FFFFFF]; - if (!(pdwTypeDefFlags is null)) + if (pdwTypeDefFlags is not null) *pdwTypeDefFlags = row.Flags; - if (!(ptkExtends is null)) + if (ptkExtends is not null) *ptkExtends = row.Extends; CopyTypeName(type.Namespace, type.Name, szTypeDef, cchTypeDef, pchTypeDef); } @@ -79,7 +79,7 @@ public override void GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingC throw new ArgumentException(); var type = tokenToTypeDef[tdNestedClass]; var declType = type.DeclaringType; - if (!(ptdEnclosingClass is null)) { + if (ptdEnclosingClass is not null) { if (declType is null) *ptdEnclosingClass = 0; else diff --git a/src/DotNet/Pdb/Dss/MetaDataImport.cs b/src/DotNet/Pdb/Dss/MetaDataImport.cs index 1e90e1c7e..da7f827c2 100644 --- a/src/DotNet/Pdb/Dss/MetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/MetaDataImport.cs @@ -18,7 +18,7 @@ protected void CopyTypeName(string typeNamespace, string typeName, ushort* destB if (typeNamespace is null) typeNamespace = string.Empty; - if (!(destBuffer is null) && destBufferLen > 0) { + if (destBuffer is not null && destBufferLen > 0) { uint maxChars = destBufferLen - 1; uint w = 0; if (typeNamespace.Length > 0) { @@ -35,10 +35,10 @@ protected void CopyTypeName(string typeNamespace, string typeName, ushort* destB *destBuffer = 0; } - if (!(requiredLength is null)) { + if (requiredLength is not null) { int totalLen = typeNamespace.Length == 0 ? typeName.Length : typeNamespace.Length + 1 + typeName.Length; int copyLen = Math.Min(totalLen, (int)Math.Min(int.MaxValue, destBufferLen == 0 ? 0 : destBufferLen - 1)); - if (!(destBuffer is null)) + if (destBuffer is not null) *requiredLength = (uint)copyLen; else *requiredLength = (uint)totalLen; diff --git a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs index 85b9d236e..910904dbb 100644 --- a/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs +++ b/src/DotNet/Pdb/Dss/ReaderMetaDataImport.cs @@ -29,9 +29,9 @@ public override void GetTypeRefProps(uint tr, uint* ptkResolutionScope, ushort* throw new ArgumentException(); if (!metadata.TablesStream.TryReadTypeRefRow(token.Rid, out var row)) throw new ArgumentException(); - if (!(ptkResolutionScope is null)) + if (ptkResolutionScope is not null) *ptkResolutionScope = row.ResolutionScope; - if (!(szName is null) || !(pchName is null)) { + if (szName is not null || pchName is not null) { var typeNamespace = metadata.StringsStream.ReadNoNull(row.Namespace); var typeName = metadata.StringsStream.ReadNoNull(row.Name); CopyTypeName(typeNamespace, typeName, szName, cchName, pchName); @@ -44,11 +44,11 @@ public override void GetTypeDefProps(uint td, ushort* szTypeDef, uint cchTypeDef throw new ArgumentException(); if (!metadata.TablesStream.TryReadTypeDefRow(token.Rid, out var row)) throw new ArgumentException(); - if (!(pdwTypeDefFlags is null)) + if (pdwTypeDefFlags is not null) *pdwTypeDefFlags = row.Flags; - if (!(ptkExtends is null)) + if (ptkExtends is not null) *ptkExtends = row.Extends; - if (!(szTypeDef is null) || !(pchTypeDef is null)) { + if (szTypeDef is not null || pchTypeDef is not null) { var typeNamespace = metadata.StringsStream.ReadNoNull(row.Namespace); var typeName = metadata.StringsStream.ReadNoNull(row.Name); CopyTypeName(typeNamespace, typeName, szTypeDef, cchTypeDef, pchTypeDef); @@ -63,9 +63,9 @@ public override void GetSigFromToken(uint mdSig, byte** ppvSig, uint* pcbSig) { throw new ArgumentException(); if (!metadata.BlobStream.TryCreateReader(row.Signature, out var reader)) throw new ArgumentException(); - if (!(ppvSig is null)) + if (ppvSig is not null) *ppvSig = blobPtr + (reader.StartOffset - (uint)metadata.BlobStream.StartOffset); - if (!(pcbSig is null)) + if (pcbSig is not null) *pcbSig = reader.Length; } diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index a6c50acf6..062f6820d 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -80,7 +80,7 @@ public override PdbCustomDebugInfo[] CustomDebugInfos { get { if (customDebugInfos is null) { var sourceCode = SourceCode; - if (!(sourceCode is null)) + if (sourceCode is not null) customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; else customDebugInfos = Array2.Empty(); diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs index fb333a68f..564fab8ca 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs @@ -9,7 +9,7 @@ sealed class SymbolDocumentWriter : ISymbolDocumentWriter { public ISymUnmanagedDocumentWriter SymUnmanagedDocumentWriter => writer; public SymbolDocumentWriter(ISymUnmanagedDocumentWriter writer) => this.writer = writer; public void SetCheckSum(Guid algorithmId, byte[] checkSum) { - if (!(checkSum is null) && checkSum.Length != 0 && algorithmId != Guid.Empty) + if (checkSum is not null && checkSum.Length != 0 && algorithmId != Guid.Empty) writer.SetCheckSum(algorithmId, (uint)checkSum.Length, checkSum); } public void SetSource(byte[] source) => writer.SetSource((uint)source.Length, source); diff --git a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs index 41e46a04d..2fb78d42d 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderImpl.cs @@ -64,7 +64,7 @@ public override SymbolMethod GetMethod(MethodDef method, int version) { internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { var asyncMethod = PseudoCustomDebugInfoFactory.TryCreateAsyncMethod(method.Module, method, body, symMethod.AsyncKickoffMethod, symMethod.AsyncStepInfos, symMethod.AsyncCatchHandlerILOffset); - if (!(asyncMethod is null)) + if (asyncMethod is not null) result.Add(asyncMethod); const string CDI_NAME = "MD2"; @@ -83,10 +83,10 @@ public override void GetCustomDebugInfos(int token, GenericParamContext gpContex void GetCustomDebugInfos_ModuleDef(IList result) { var sourceLinkData = GetSourceLinkData(); - if (!(sourceLinkData is null)) + if (sourceLinkData is not null) result.Add(new PdbSourceLinkCustomDebugInfo(sourceLinkData)); var sourceServerData = GetSourceServerData(); - if (!(sourceServerData is null)) + if (sourceServerData is not null) result.Add(new PdbSourceServerCustomDebugInfo(sourceServerData)); } @@ -135,7 +135,7 @@ public override void Dispose() { void Dispose(bool disposing) { (reader as ISymUnmanagedDispose)?.Destroy(); var o = objsToKeepAlive; - if (!(o is null)) { + if (o is not null) { foreach (var obj in o) (obj as IDisposable)?.Dispose(); } diff --git a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index a480a3b13..22ba81a6d 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -19,7 +19,7 @@ sealed class SymbolWriterImpl : SymbolWriter { bool closeCalled; public override bool IsDeterministic => isDeterministic; - public override bool SupportsAsyncMethods => !(asyncMethodWriter is null); + public override bool SupportsAsyncMethods => asyncMethodWriter is not null; public SymbolWriterImpl(ISymUnmanagedWriter2 writer, string pdbFileName, Stream pdbStream, PdbWriterOptions options, bool ownsStream) { this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index 3c0de5f53..b13f70d6f 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -28,7 +28,7 @@ public override PdbCustomDebugInfo[] CustomDebugInfos { get { if (customDebugInfos is null) { var sourceCode = SourceCode; - if (!(sourceCode is null)) + if (sourceCode is not null) customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; else customDebugInfos = Array2.Empty(); diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index 2070f6b48..f0a76bdb8 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -157,13 +157,13 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, ref if (funcs[found].Lines is null) { while (found > 0) { var prevFunc = funcs[found - 1]; - if (!(prevFunc is null) || prevFunc.Address != address) + if (prevFunc is not null || prevFunc.Address != address) break; found--; } } else { - while (found < funcs.Length - 1 && !(funcs[found] is null)) { + while (found < funcs.Length - 1 && funcs[found] is not null) { var nextFunc = funcs[found + 1]; if (nextFunc.Address != address) break; @@ -171,7 +171,7 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, ref } } var func = funcs[found]; - if (!(func.Lines is null)) + if (func.Lines is not null) return; func.Lines = new List(); diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index 7e8b99a28..baa2e2636 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -110,7 +110,7 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) } reader.Position += 4;// typeIndex or 0 name = ReadUnicodeString(ref reader, end); - Debug.Assert(!(name is null)); + Debug.Assert(name is not null); if (name is null) break; var data = reader.ReadBytes((int)(end - reader.Position)); @@ -135,7 +135,7 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) } reader.Position = end; - if (!(child is null)) { + if (child is not null) { child.Read(counter, ref reader, childEnd.Value); childrenList.Add(child); child = null; diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index ea4a9e899..1159a2927 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -343,7 +343,7 @@ public override IList Documents { internal void GetCustomDebugInfos(DbiFunction symMethod, MethodDef method, CilBody body, IList result) { const string CDI_NAME = "MD2"; var asyncMethod = PseudoCustomDebugInfoFactory.TryCreateAsyncMethod(method.Module, method, body, symMethod.AsyncKickoffMethod, symMethod.AsyncStepInfos, symMethod.AsyncCatchHandlerILOffset); - if (!(asyncMethod is null)) + if (asyncMethod is not null) result.Add(asyncMethod); var cdiData = symMethod.Root.GetSymAttribute(CDI_NAME); @@ -358,9 +358,9 @@ public override void GetCustomDebugInfos(int token, GenericParamContext gpContex } void GetCustomDebugInfos_ModuleDef(IList result) { - if (!(sourcelinkData is null)) + if (sourcelinkData is not null) result.Add(new PdbSourceLinkCustomDebugInfo(sourcelinkData)); - if (!(srcsrvData is null)) + if (srcsrvData is not null) result.Add(new PdbSourceServerCustomDebugInfo(srcsrvData)); } } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 0dd4c447d..55909f8c6 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -431,7 +431,7 @@ public sealed class PdbDynamicLocal { public string Name { get { var n = name; - if (!(n is null)) + if (n is not null) return n; return local?.Name; } @@ -446,7 +446,7 @@ public string Name { /// /// true if it's a variable ( is not null) /// - public bool IsVariable => !(Local is null); + public bool IsVariable => Local is not null; /// /// Gets/sets the local. Could be null if there's no local (it's a 'const' local). @@ -572,7 +572,7 @@ public sealed class PdbTupleElementNames { public string Name { get { var n = name; - if (!(n is null)) + if (n is not null) return n; return local?.Name; } @@ -595,7 +595,7 @@ public Local Local { /// /// true if it's a variable. Variables don't have a scope ( and ) /// - public bool IsVariable => !(local is null); + public bool IsVariable => local is not null; /// /// Gets/sets the start of the scope or null. Only constants have a scope. diff --git a/src/DotNet/Pdb/PdbReaderContext.cs b/src/DotNet/Pdb/PdbReaderContext.cs index de6462022..74f57e823 100644 --- a/src/DotNet/Pdb/PdbReaderContext.cs +++ b/src/DotNet/Pdb/PdbReaderContext.cs @@ -9,7 +9,7 @@ readonly struct PdbReaderContext { readonly IPEImage peImage; readonly ImageDebugDirectory codeViewDebugDir; - public bool HasDebugInfo => !(codeViewDebugDir is null); + public bool HasDebugInfo => codeViewDebugDir is not null; public ImageDebugDirectory CodeViewDebugDirectory => codeViewDebugDir; public PdbReaderOptions Options { get; } @@ -48,7 +48,7 @@ public bool TryGetCodeViewData(out Guid guid, out uint age, out string pdbFilena guid = reader.ReadGuid(); age = reader.ReadUInt32(); pdbFilename = reader.TryReadZeroTerminatedUtf8String(); - return !(pdbFilename is null); + return pdbFilename is not null; } DataReader GetCodeViewDataReader() { diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index daad8b8c1..455c24d11 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -200,7 +200,7 @@ internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, Ci return; var method = reader.GetMethod(ownerMethod, 1); - if (!(method is null)) { + if (method is not null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); @@ -213,7 +213,7 @@ internal void InitializeCustomDebugInfos(MethodDef ownerMethod, CilBody body, IL return; var method = reader.GetMethod(ownerMethod, 1); - if (!(method is null)) + if (method is not null) method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); } @@ -231,7 +231,7 @@ static Compiler CalculateCompiler(ModuleDef module) { // The VB runtime can also be embedded, and if so, it seems that "Microsoft.VisualBasic.Embedded" // attribute is added to the assembly's custom attributes. var asm = module.Assembly; - if (!(asm is null) && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) + if (asm is not null && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) return Compiler.VisualBasic; #endif @@ -319,7 +319,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody for (int i = 0; i < constants.Count; i++) { var constant = constants[i]; var type = constant.Type.RemovePinnedAndModifiers(); - if (!(type is null)) { + if (type is not null) { // Fix a few values since they're stored as some other type in the PDB switch (type.ElementType) { case ElementType.Boolean: @@ -382,7 +382,7 @@ PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody case ElementType.Var: case ElementType.MVar: var gp = ((GenericSig)type).GenericParam; - if (!(gp is null)) { + if (gp is not null) { if (gp.HasNotNullableValueTypeConstraint) break; if (gp.HasReferenceTypeConstraint) diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index e42486221..8eee439eb 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -102,7 +102,7 @@ public void Read(uint imports, IList result) { import = null; break; } - if (!(import is null)) + if (import is not null) result.Add(import); } Debug.Assert(reader.Position == reader.Length); @@ -114,13 +114,13 @@ ITypeDefOrRef TryReadType(uint codedToken) { if (!b) return null; var type = module.ResolveToken(token) as ITypeDefOrRef; - Debug.Assert(!(type is null)); + Debug.Assert(type is not null); return type; } AssemblyRef TryReadAssemblyRef(uint rid) { var asmRef = module.ResolveToken(0x23000000 + rid) as AssemblyRef; - Debug.Assert(!(asmRef is null)); + Debug.Assert(asmRef is not null); return asmRef; } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index dccf20ed1..3bdee8c93 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -281,7 +281,7 @@ ITypeDefOrRef ReadTypeDefOrRef() { ISignatureReaderHelper helper = module; var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); var corType = module.CorLibTypes.GetCorLibTypeSig(tdr); - if (!(corType is null)) + if (corType is not null) return corType.TypeDefOrRef; return tdr; } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index 744989b94..3fd0816e9 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -134,7 +134,7 @@ void Write(DataWriter writer, TypeSig type, object value) { if (!valueWritten) { if (value is byte[]) writer.WriteBytes((byte[])value); - else if (!(value is null)) { + else if (value is not null) { helper.Error("Unsupported constant: " + value.GetType().FullName); return; } @@ -146,7 +146,7 @@ void Write(DataWriter writer, TypeSig type, object value) { WriteTypeDefOrRef(writer, ((ClassSig)type).TypeDefOrRef); if (value is byte[]) writer.WriteBytes((byte[])value); - else if (!(value is null)) + else if (value is not null) helper.Error("Expected a null constant"); return; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index 0990daaee..68b61ee80 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -78,7 +78,7 @@ PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { catchHandler = null; else { catchHandler = GetInstruction(catchHandlerOffset); - Debug.Assert(!(catchHandler is null)); + Debug.Assert(catchHandler is not null); if (catchHandler is null) return null; } @@ -86,7 +86,7 @@ PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { asyncInfo.CatchHandler = catchHandler; while (reader.Position < reader.Length) { var yieldInstr = GetInstruction(reader.ReadUInt32()); - Debug.Assert(!(yieldInstr is null)); + Debug.Assert(yieldInstr is not null); if (yieldInstr is null) return null; uint resumeOffset = reader.ReadUInt32(); @@ -94,18 +94,18 @@ PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { var moveNextToken = new MDToken(Table.Method, moveNextRid); MethodDef moveNextMethod; Instruction resumeInstr; - if (!(gpContext.Method is null) && moveNextToken == gpContext.Method.MDToken) { + if (gpContext.Method is not null && moveNextToken == gpContext.Method.MDToken) { moveNextMethod = gpContext.Method; resumeInstr = GetInstruction(resumeOffset); } else { moveNextMethod = module.ResolveToken(moveNextToken, gpContext) as MethodDef; - Debug.Assert(!(moveNextMethod is null)); + Debug.Assert(moveNextMethod is not null); if (moveNextMethod is null) return null; resumeInstr = GetInstruction(moveNextMethod, resumeOffset); } - Debug.Assert(!(resumeInstr is null)); + Debug.Assert(resumeInstr is not null); if (resumeInstr is null) return null; asyncInfo.AsyncStepInfos.Add(new PdbAsyncStepInfo(yieldInstr, moveNextMethod, resumeInstr)); @@ -156,7 +156,7 @@ PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { else { var start = GetInstruction(startOffset); var end = GetInstruction(startOffset + length); - Debug.Assert(!(start is null)); + Debug.Assert(start is not null); if (start is null) return null; smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); @@ -185,11 +185,11 @@ PdbCustomDebugInfo ReadCompilationMetadataReferences() { while (reader.BytesLeft > 0) { var name = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(!(name is null)); + Debug.Assert(name is not null); if (name is null) break; var aliases = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(!(aliases is null)); + Debug.Assert(aliases is not null); if (aliases is null) break; @@ -215,11 +215,11 @@ PdbCustomDebugInfo ReadCompilationOptions() { while (reader.BytesLeft > 0) { var key = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(!(key is null)); + Debug.Assert(key is not null); if (key is null) break; var value = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(!(value is null)); + Debug.Assert(value is not null); if (value is null) break; cdi.Options.Add(new KeyValuePair(key, value)); diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index d4b893305..105df8038 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -54,7 +54,7 @@ static Guid GetLanguageVendor(Guid language) { } SymbolDocument[] ReadDocuments() { - Debug.Assert(!(module is null)); + Debug.Assert(module is not null); var docTbl = pdbMetadata.TablesStream.DocumentTable; var docs = new SymbolDocument[docTbl.Rows]; var nameReader = new DocumentNameReader(pdbMetadata.BlobStream); @@ -151,7 +151,7 @@ SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { else { // SequencePointRecord - Debug.Assert(!(document is null)); + Debug.Assert(document is not null); if (document is null) return null; @@ -233,7 +233,7 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { stack.RemoveAt(stack.Count - 1); } - Debug.Assert(!(parent is null) || rootScopeOrNull is null); + Debug.Assert(parent is not null || rootScopeOrNull is null); custInfos.Clear(); GetCustomDebugInfos(token, gpContext, custInfos); var customDebugInfos = custInfos.Count == 0 ? Array2.Empty() : custInfos.ToArray(); @@ -241,7 +241,7 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { if (rootScopeOrNull is null) rootScopeOrNull = scope; stack.Add(scope); - if (!(parent is null)) + if (parent is not null) parent.childrenList.Add(scope); scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext); @@ -285,7 +285,7 @@ PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReade GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos); if (result is null) result = scope; - if (!(prevScope is null)) + if (prevScope is not null) prevScope.Parent = scope; importScopeBlobReader.Read(row.Imports, scope.Imports); prevScope = scope; @@ -349,16 +349,16 @@ void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEn internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { Debug.Assert(method.Module == module); GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out var asyncStepInfo); - if (!(asyncStepInfo is null)) { + if (asyncStepInfo is not null) { var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); - Debug.Assert(!(asyncMethod is null)); - if (!(asyncMethod is null)) + Debug.Assert(asyncMethod is not null); + if (asyncMethod is not null) result.Add(asyncMethod); } else if (symMethod.KickoffMethod != 0) { var iteratorMethod = TryCreateIteratorMethod(module, symMethod.KickoffMethod); - Debug.Assert(!(iteratorMethod is null)); - if (!(iteratorMethod is null)) + Debug.Assert(iteratorMethod is not null); + if (iteratorMethod is not null) result.Add(iteratorMethod); } } @@ -404,12 +404,12 @@ void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList GetConstants(ModuleDef module, GenericParamContext gpContext) { if (constantList >= constantListEnd) return Array2.Empty(); - Debug.Assert(!(constantsMetadata is null)); + Debug.Assert(constantsMetadata is not null); var res = new PdbConstant[constantListEnd - constantList]; int w = 0; diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index 686d425b8..5d0388548 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -66,12 +66,12 @@ static SymbolReader CreateCore(PdbReaderContext pdbContext, Metadata metadata, D if (!pdbContext.HasDebugInfo) return null; - if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && !(pdbStream is null) && IsWindowsPdb(pdbStream.CreateReader())) + if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && pdbStream is not null && IsWindowsPdb(pdbStream.CreateReader())) symReader = Dss.SymbolReaderWriterFactory.Create(pdbContext, metadata, pdbStream); else symReader = CreateManaged(pdbContext, metadata, pdbStream); - if (!(symReader is null)) { + if (symReader is not null) { error = false; return symReader; } @@ -105,7 +105,7 @@ static SymbolReader CreateManaged(PdbReaderContext pdbContext, Metadata metadata try { // Embedded PDBs have priority var embeddedReader = TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); - if (!(embeddedReader is null)) { + if (embeddedReader is not null) { pdbStream?.Dispose(); return embeddedReader; } diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index e0b6dae90..86dbf8460 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -81,11 +81,11 @@ void Read(IList result) { if (recVersion == CustomDebugInfoConstants.RecordVersion) { ulong recPosEnd = (ulong)reader.Position - 8 + (uint)recSize - (uint)alignmentSize; var cdi = ReadRecord(recKind, recPosEnd); - Debug.Assert(!(cdi is null)); + Debug.Assert(cdi is not null); Debug.Assert(reader.Position <= recPosEnd); if (reader.Position > recPosEnd) return; - if (!(cdi is null)) { + if (cdi is not null) { Debug.Assert(cdi.Kind == recKind); result.Add(cdi); } @@ -191,9 +191,9 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { local = localIndex < bodyOpt.Variables.Count ? bodyOpt.Variables[localIndex] : null; // Roslyn writes 0 to localIndex if it's a 'const' local, try to undo that now - if (localIndex == 0 && !(local is null) && local.Name != name) + if (localIndex == 0 && local is not null && local.Name != name) local = null; - if (!(local is null) && local.Name == name) + if (local is not null && local.Name == name) name = null; dynLocRec.Name = name; dynLocRec.Local = local; @@ -252,7 +252,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { local = bodyOpt.Variables[localIndex]; } - if (!(local is null) && local.Name == name) + if (local is not null && local.Name == name) name = null; tupleInfo.Local = local; tupleInfo.Name = name; diff --git a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs index 6b22f8ffc..6bee81eba 100644 --- a/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs +++ b/src/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs @@ -17,16 +17,16 @@ public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef modul var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); asyncMethod.KickoffMethod = kickoffMethod; - if (!(asyncCatchHandlerILOffset is null)) { + if (asyncCatchHandlerILOffset is not null) { asyncMethod.CatchHandlerInstruction = GetInstruction(body, asyncCatchHandlerILOffset.Value); - Debug.Assert(!(asyncMethod.CatchHandlerInstruction is null)); + Debug.Assert(asyncMethod.CatchHandlerInstruction is not null); } int count = asyncStepInfos.Count; for (int i = 0; i < count; i++) { var rawInfo = asyncStepInfos[i]; var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); - Debug.Assert(!(yieldInstruction is null)); + Debug.Assert(yieldInstruction is not null); if (yieldInstruction is null) continue; MethodDef breakpointMethod; @@ -41,12 +41,12 @@ public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef modul if (breakpointMethodToken.Table != Table.Method) continue; breakpointMethod = module.ResolveToken(breakpointMethodToken) as MethodDef; - Debug.Assert(!(breakpointMethod is null)); + Debug.Assert(breakpointMethod is not null); if (breakpointMethod is null) continue; breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); } - Debug.Assert(!(breakpointInstruction is null)); + Debug.Assert(breakpointInstruction is not null); if (breakpointInstruction is null) continue; diff --git a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs index 81f5ff354..1d7336de0 100644 --- a/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ b/src/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs @@ -101,7 +101,7 @@ bool ShouldAddMethod(MethodDef method) { for (int i = 0; i < count; i++) { var local = bodyVariables[i]; // Don't check whether it's the empty string. Only check for null. - if (!(local.Name is null)) + if (local.Name is not null) return true; if (local.Attributes != 0) return true; @@ -110,7 +110,7 @@ bool ShouldAddMethod(MethodDef method) { var bodyInstructions = body.Instructions; count = bodyInstructions.Count; for (int i = 0; i < count; i++) { - if (!(bodyInstructions[i].SequencePoint is null)) + if (bodyInstructions[i].SequencePoint is not null) return true; } @@ -169,7 +169,7 @@ public void Write(WindowsPdbWriter pdbWriter, IList instrs) { if (!otherDocsAvailable) break; - if (!(currPdbDoc is null)) + if (currPdbDoc is not null) checkedPdbDocs.Add(currPdbDoc, true); } } @@ -250,11 +250,11 @@ void Write(MethodDef method, List cdiBuilder) { if (cdiBuilder.Count != 0) { customDebugInfoWriterContext.Logger = GetLogger(); var cdiData = PdbCustomDebugInfoWriter.Write(metadata, method, customDebugInfoWriterContext, cdiBuilder); - if (!(cdiData is null)) + if (cdiData is not null) writer.SetSymAttribute(symbolToken, "MD2", cdiData); } - if (!(asyncMethod is null)) { + if (asyncMethod is not null) { if (!writer.SupportsAsyncMethods) Error("PDB symbol writer doesn't support writing async methods"); else @@ -272,7 +272,7 @@ void GetPseudoCustomDebugInfos(IList customDebugInfos, List< var cdi = customDebugInfos[i]; switch (cdi.Kind) { case PdbCustomDebugInfoKind.AsyncMethod: - if (!(asyncMethod is null)) + if (asyncMethod is not null) Error("Duplicate async method custom debug info"); else asyncMethod = (PdbAsyncMethodCustomDebugInfo)cdi; @@ -304,7 +304,7 @@ void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyn uint kickoffMethod = GetMethodToken(asyncMethod.KickoffMethod); writer.DefineKickoffMethod(kickoffMethod); - if (!(asyncMethod.CatchHandlerInstruction is null)) { + if (asyncMethod.CatchHandlerInstruction is not null) { int catchHandlerILOffset = info.GetOffset(asyncMethod.CatchHandlerInstruction); writer.DefineCatchHandlerILOffset((uint)catchHandlerILOffset); } @@ -435,7 +435,7 @@ public bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge /// public void Dispose() { - if (!(writer is null)) + if (writer is not null) Close(); writer?.Dispose(); writer = null; diff --git a/src/DotNet/PropertyDef.cs b/src/DotNet/PropertyDef.cs index 16a53bb20..67bd1f9ce 100644 --- a/src/DotNet/PropertyDef.cs +++ b/src/DotNet/PropertyDef.cs @@ -276,7 +276,7 @@ protected virtual void InitializePropertyMethods_NoLock() { /// /// true if is not null /// - public bool HasConstant => !(Constant is null); + public bool HasConstant => Constant is not null; /// /// Gets the constant element type or if there's no constant @@ -305,9 +305,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (!(currentDeclaringType is null)) + if (currentDeclaringType is not null) currentDeclaringType.Properties.Remove(this); // Will set DeclaringType2 = null - if (!(value is null)) + if (value is not null) value.Properties.Add(this); // Will set DeclaringType2 = value } } @@ -499,7 +499,7 @@ internal PropertyDefMD InitializeAll() { /// protected override void InitializePropertyMethods_NoLock() { - if (!(otherMethods is null)) + if (otherMethods is not null) return; IList newOtherMethods; IList newGetMethods, newSetMethods; diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index 899c83e03..3cf1fad50 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -33,7 +33,7 @@ public static bool IsSZArray(this Type self) { if (self is null || !self.IsArray) return false; var prop = self.GetType().GetProperty("IsSzArray", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (!(prop is null)) + if (prop is not null) return (bool)prop.GetValue(self, Array2.Empty()); return (self.Name ?? string.Empty).EndsWith("[]"); } @@ -85,7 +85,7 @@ public static ElementType GetElementType2(this Type a) { /// /// The method public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => - !(mb is null) && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; + mb is not null && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; /// /// Checks whether a parameter/prop/event type should be treated as if it is really a @@ -97,7 +97,7 @@ public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => /// Declaring type of method/event/property /// Parameter/property/event type internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) => - !(declaringType is null) && declaringType.IsGenericTypeDefinition && t == declaringType; + declaringType is not null && declaringType.IsGenericTypeDefinition && t == declaringType; /// /// Checks whether is a type definition and not a type spec @@ -105,7 +105,7 @@ internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Typ /// /// this public static bool IsTypeDef(this Type type) => - !(type is null) && !type.HasElementType && (!type.IsGenericType || type.IsGenericTypeDefinition); + type is not null && !type.HasElementType && (!type.IsGenericType || type.IsGenericTypeDefinition); internal static string Unescape(string name) { if (string.IsNullOrEmpty(name) || name.IndexOf('\\') < 0) diff --git a/src/DotNet/Resolver.cs b/src/DotNet/Resolver.cs index 950ec7a49..8196d1061 100644 --- a/src/DotNet/Resolver.cs +++ b/src/DotNet/Resolver.cs @@ -79,7 +79,7 @@ TypeDef ResolveExportedType(IList modules, TypeRef typeRef, ModuleDef return null; var td = etAsm.Find(typeRef); - if (!(td is null)) + if (td is not null) return td; modules = etAsm.Modules; @@ -140,9 +140,9 @@ TypeDef GetDeclaringType(MemberRef memberRef, IMemberRefParent parent) { if (new SigComparer().Equals(module, moduleRef)) globalType = module.GlobalType; var modAsm = module.Assembly; - if (globalType is null && !(modAsm is null)) { + if (globalType is null && modAsm is not null) { var moduleDef = modAsm.FindModule(moduleRef.Name); - if (!(moduleDef is null)) + if (moduleDef is not null) globalType = moduleDef.GlobalType; } return globalType; diff --git a/src/DotNet/ResourceCollection.cs b/src/DotNet/ResourceCollection.cs index 78ff42a73..debc42b03 100644 --- a/src/DotNet/ResourceCollection.cs +++ b/src/DotNet/ResourceCollection.cs @@ -41,7 +41,7 @@ public int IndexOf(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (!(resource is null) && resource.Name == name) + if (resource is not null && resource.Name == name) return i; } return -1; @@ -56,7 +56,7 @@ public int IndexOfEmbeddedResource(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (!(resource is null) && + if (resource is not null && resource.ResourceType == ResourceType.Embedded && resource.Name == name) return i; @@ -73,7 +73,7 @@ public int IndexOfAssemblyLinkedResource(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (!(resource is null) && + if (resource is not null && resource.ResourceType == ResourceType.AssemblyLinked && resource.Name == name) return i; @@ -90,7 +90,7 @@ public int IndexOfLinkedResource(UTF8String name) { int i = -1; foreach (var resource in this) { i++; - if (!(resource is null) && + if (resource is not null && resource.ResourceType == ResourceType.Linked && resource.Name == name) return i; @@ -105,7 +105,7 @@ public int IndexOfLinkedResource(UTF8String name) { /// The or null if none was found public Resource Find(UTF8String name) { foreach (var resource in this) { - if (!(resource is null) && resource.Name == name) + if (resource is not null && resource.Name == name) return resource; } return null; @@ -118,7 +118,7 @@ public Resource Find(UTF8String name) { /// The or null if none was found public EmbeddedResource FindEmbeddedResource(UTF8String name) { foreach (var resource in this) { - if (!(resource is null) && + if (resource is not null && resource.ResourceType == ResourceType.Embedded && resource.Name == name) return (EmbeddedResource)resource; @@ -133,7 +133,7 @@ public EmbeddedResource FindEmbeddedResource(UTF8String name) { /// The or null if none was found public AssemblyLinkedResource FindAssemblyLinkedResource(UTF8String name) { foreach (var resource in this) { - if (!(resource is null) && + if (resource is not null && resource.ResourceType == ResourceType.AssemblyLinked && resource.Name == name) return (AssemblyLinkedResource)resource; @@ -148,7 +148,7 @@ public AssemblyLinkedResource FindAssemblyLinkedResource(UTF8String name) { /// The or null if none was found public LinkedResource FindLinkedResource(UTF8String name) { foreach (var resource in this) { - if (!(resource is null) && + if (resource is not null && resource.ResourceType == ResourceType.Linked && resource.Name == name) return (LinkedResource)resource; diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index 98c4c076e..f3cb8f794 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -146,7 +146,7 @@ public override string ToString() { case ResourceTypeCode.ByteArray: case ResourceTypeCode.Stream: var ary = data as byte[]; - if (!(ary is null)) + if (ary is not null) return $"{code}: Length: {ary.Length}"; return $"{code}: '{data}'"; diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index cb2162a6b..d2a04993b 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -273,9 +273,9 @@ string TryGetRealAssemblyName(IAssembly asm) { if (simpleName == module.CorLibTypes.AssemblyRef.Name) return module.CorLibTypes.AssemblyRef.FullName; - if (!(moduleMD is null)) { + if (moduleMD is not null) { var asmRef = moduleMD.GetAssemblyRef(simpleName); - if (!(asmRef is null)) + if (asmRef is not null) return asmRef.FullName; } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index d079b1ced..f3eb329da 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -190,9 +190,9 @@ IResourceData ReadResourceData(List userTypes, int size) { throw new ResourceReaderException($"Invalid resource data code: {code}"); var userType = userTypes[userTypeIndex]; var serializedData = reader.ReadBytes((int)(endPos - reader.Position)); - if (!(createResourceDataDelegate is null)) { + if (createResourceDataDelegate is not null) { var res = createResourceDataDelegate(resourceDataFactory, userType, serializedData); - if (!(res is null)) + if (res is not null) return res; } return resourceDataFactory.CreateSerialized(serializedData, userType); diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 115f7e2ac..15ebc8d50 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -641,7 +641,7 @@ bool Equals(IAssembly aAsm, IAssembly bAsm, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - return !(td is null) && Equals(aAsm, td.Module.Assembly); + return td is not null && Equals(aAsm, td.Module.Assembly); } bool Equals(IAssembly aAsm, IAssembly bAsm, ExportedType b) { @@ -649,7 +649,7 @@ bool Equals(IAssembly aAsm, IAssembly bAsm, ExportedType b) { return true; var td = b.Resolve(); - return !(td is null) && Equals(aAsm, td.Module.Assembly); + return td is not null && Equals(aAsm, td.Module.Assembly); } bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, TypeRef b) { @@ -660,7 +660,7 @@ bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, TypeRef b) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(sourceModule); - return !(tda is null) && !(tdb is null) && Equals(tda.Module.Assembly, tdb.Module.Assembly); + return tda is not null && tdb is not null && Equals(tda.Module.Assembly, tdb.Module.Assembly); } bool Equals(IAssembly aAsm, ExportedType a, IAssembly bAsm, ExportedType b) { @@ -669,7 +669,7 @@ bool Equals(IAssembly aAsm, ExportedType a, IAssembly bAsm, ExportedType b) { var tda = a.Resolve(); var tdb = b.Resolve(); - return !(tda is null) && !(tdb is null) && Equals(tda.Module.Assembly, tdb.Module.Assembly); + return tda is not null && tdb is not null && Equals(tda.Module.Assembly, tdb.Module.Assembly); } bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, ExportedType b) { @@ -680,7 +680,7 @@ bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, ExportedType b) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(); - return !(tda is null) && !(tdb is null) && Equals(tda.Module.Assembly, tdb.Module.Assembly); + return tda is not null && tdb is not null && Equals(tda.Module.Assembly, tdb.Module.Assembly); } bool Equals(TypeDef a, IModule bMod, TypeRef b) { @@ -704,7 +704,7 @@ bool Equals(TypeDef a, FileDef bFile, ExportedType b) { return true; var td = b.Resolve(); - return !(td is null) && Equals(a.Module, td.Module) && Equals(a.DefinitionAssembly, td.DefinitionAssembly); + return td is not null && Equals(a.Module, td.Module) && Equals(a.DefinitionAssembly, td.DefinitionAssembly); } bool TypeDefScopeEquals(TypeDef a, TypeDef b) { @@ -725,7 +725,7 @@ bool Equals(TypeRef a, IModule ma, TypeRef b, IModule mb) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(sourceModule); - return !(tda is null) && !(tdb is null) && + return tda is not null && tdb is not null && Equals(tda.Module, tdb.Module) && Equals(tda.DefinitionAssembly, tdb.DefinitionAssembly); } @@ -737,7 +737,7 @@ bool Equals(TypeRef a, IModule ma, ExportedType b, FileDef fb) { var tda = a.Resolve(sourceModule); var tdb = b.Resolve(); - return !(tda is null) && !(tdb is null) && + return tda is not null && tdb is not null && Equals(tda.Module, tdb.Module) && Equals(tda.DefinitionAssembly, tdb.DefinitionAssembly); } @@ -748,7 +748,7 @@ bool Equals(Assembly aAsm, IAssembly bAsm, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - return !(td is null) && Equals(td.Module.Assembly, aAsm); + return td is not null && Equals(td.Module.Assembly, aAsm); } bool Equals(Assembly aAsm, IAssembly bAsm, ExportedType b) { @@ -756,7 +756,7 @@ bool Equals(Assembly aAsm, IAssembly bAsm, ExportedType b) { return true; var td = b.Resolve(); - return !(td is null) && Equals(td.Module.Assembly, aAsm); + return td is not null && Equals(td.Module.Assembly, aAsm); } bool Equals(Type a, IModule bMod, TypeRef b) { @@ -766,7 +766,7 @@ bool Equals(Type a, IModule bMod, TypeRef b) { // Could be an exported type. Resolve it and check again. var td = b.Resolve(sourceModule); - return !(td is null) && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); + return td is not null && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); } bool Equals(Type a, FileDef bFile, ExportedType b) { @@ -774,7 +774,7 @@ bool Equals(Type a, FileDef bFile, ExportedType b) { return true; var td = b.Resolve(); - return !(td is null) && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); + return td is not null && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); } /// @@ -798,15 +798,15 @@ public bool Equals(IMemberRef a, IMemberRef b) { PropertyDef pa, pb; EventDef ea, eb; - if (!((ta = a as IType) is null) && !((tb = b as IType) is null)) + if ((ta = a as IType) is not null && (tb = b as IType) is not null) result = Equals(ta, tb); - else if (!((fa = a as IField) is null) && !((fb = b as IField) is null) && fa.IsField && fb.IsField) + else if ((fa = a as IField) is not null && (fb = b as IField) is not null && fa.IsField && fb.IsField) result = Equals(fa, fb); - else if (!((ma = a as IMethod) is null) && !((mb = b as IMethod) is null)) + else if ((ma = a as IMethod) is not null && (mb = b as IMethod) is not null) result = Equals(ma, mb); - else if (!((pa = a as PropertyDef) is null) && !((pb = b as PropertyDef) is null)) + else if ((pa = a as PropertyDef) is not null && (pb = b as PropertyDef) is not null) result = Equals(pa, pb); - else if (!((ea = a as EventDef) is null) && !((eb = b as EventDef) is null)) + else if ((ea = a as EventDef) is not null && (eb = b as EventDef) is not null) result = Equals(ea, eb); else result = false; @@ -833,15 +833,15 @@ public int GetHashCode(IMemberRef a) { PropertyDef pa; EventDef ea; - if (!((ta = a as IType) is null)) + if ((ta = a as IType) is not null) result = GetHashCode(ta); - else if (!((fa = a as IField) is null)) + else if ((fa = a as IField) is not null) result = GetHashCode(fa); - else if (!((ma = a as IMethod) is null)) + else if ((ma = a as IMethod) is not null) result = GetHashCode(ma); - else if (!((pa = a as PropertyDef) is null)) + else if ((pa = a as PropertyDef) is not null) result = GetHashCode(pa); - else if (!((ea = a as EventDef) is null)) + else if ((ea = a as EventDef) is not null) result = GetHashCode(ea); else result = 0; // Should never be reached @@ -886,55 +886,55 @@ public bool Equals(IType a, IType b) { TypeSig sa, sb; ExportedType eta, etb; - if (!((tda = a as TypeDef) is null) & !((tdb = b as TypeDef) is null)) + if ((tda = a as TypeDef) is not null & (tdb = b as TypeDef) is not null) result = Equals(tda, tdb); - else if (!((tra = a as TypeRef) is null) & !((trb = b as TypeRef) is null)) + else if ((tra = a as TypeRef) is not null & (trb = b as TypeRef) is not null) result = Equals(tra, trb); - else if (!((tsa = a as TypeSpec) is null) & !((tsb = b as TypeSpec) is null)) + else if ((tsa = a as TypeSpec) is not null & (tsb = b as TypeSpec) is not null) result = Equals(tsa, tsb); - else if (!((sa = a as TypeSig) is null) & !((sb = b as TypeSig) is null)) + else if ((sa = a as TypeSig) is not null & (sb = b as TypeSig) is not null) result = Equals(sa, sb); - else if (!((eta = a as ExportedType) is null) & !((etb = b as ExportedType) is null)) + else if ((eta = a as ExportedType) is not null & (etb = b as ExportedType) is not null) result = Equals(eta, etb); - else if (!(tda is null) && !(trb is null)) + else if (tda is not null && trb is not null) result = Equals(tda, trb); // TypeDef vs TypeRef - else if (!(tra is null) && !(tdb is null)) + else if (tra is not null && tdb is not null) result = Equals(tdb, tra); // TypeDef vs TypeRef - else if (!(tda is null) && !(tsb is null)) + else if (tda is not null && tsb is not null) result = Equals(tda, tsb); // TypeDef vs TypeSpec - else if (!(tsa is null) && !(tdb is null)) + else if (tsa is not null && tdb is not null) result = Equals(tdb, tsa); // TypeDef vs TypeSpec - else if (!(tda is null) && !(sb is null)) + else if (tda is not null && sb is not null) result = Equals(tda, sb); // TypeDef vs TypeSig - else if (!(sa is null) && !(tdb is null)) + else if (sa is not null && tdb is not null) result = Equals(tdb, sa); // TypeDef vs TypeSig - else if (!(tda is null) && !(etb is null)) + else if (tda is not null && etb is not null) result = Equals(tda, etb); // TypeDef vs ExportedType - else if (!(eta is null) && !(tdb is null)) + else if (eta is not null && tdb is not null) result = Equals(tdb, eta); // TypeDef vs ExportedType - else if (!(tra is null) && !(tsb is null)) + else if (tra is not null && tsb is not null) result = Equals(tra, tsb); // TypeRef vs TypeSpec - else if (!(tsa is null) && !(trb is null)) + else if (tsa is not null && trb is not null) result = Equals(trb, tsa); // TypeRef vs TypeSpec - else if (!(tra is null) && !(sb is null)) + else if (tra is not null && sb is not null) result = Equals(tra, sb); // TypeRef vs TypeSig - else if (!(sa is null) && !(trb is null)) + else if (sa is not null && trb is not null) result = Equals(trb, sa); // TypeRef vs TypeSig - else if (!(tra is null) && !(etb is null)) + else if (tra is not null && etb is not null) result = Equals(tra, etb); // TypeRef vs ExportedType - else if (!(eta is null) && !(trb is null)) + else if (eta is not null && trb is not null) result = Equals(trb, eta); // TypeRef vs ExportedType - else if (!(tsa is null) && !(sb is null)) + else if (tsa is not null && sb is not null) result = Equals(tsa, sb); // TypeSpec vs TypeSig - else if (!(sa is null) && !(tsb is null)) + else if (sa is not null && tsb is not null) result = Equals(tsb, sa); // TypeSpec vs TypeSig - else if (!(tsa is null) && !(etb is null)) + else if (tsa is not null && etb is not null) result = Equals(tsa, etb); // TypeSpec vs ExportedType - else if (!(eta is null) && !(tsb is null)) + else if (eta is not null && tsb is not null) result = Equals(tsb, eta); // TypeSpec vs ExportedType - else if (!(sa is null) && !(etb is null)) + else if (sa is not null && etb is not null) result = Equals(sa, etb); // TypeSig vs ExportedType - else if (!(eta is null) && !(sb is null)) + else if (eta is not null && sb is not null) result = Equals(sb, eta); // TypeSig vs ExportedType else result = false; // Should never be reached @@ -961,15 +961,15 @@ public int GetHashCode(IType a) { TypeSig sig; ExportedType et; - if (!((td = a as TypeDef) is null)) + if ((td = a as TypeDef) is not null) hash = GetHashCode(td); - else if (!((tr = a as TypeRef) is null)) + else if ((tr = a as TypeRef) is not null) hash = GetHashCode(tr); - else if (!((ts = a as TypeSpec) is null)) + else if ((ts = a as TypeSpec) is not null) hash = GetHashCode(ts); - else if (!((sig = a as TypeSig) is null)) + else if ((sig = a as TypeSig) is not null) hash = GetHashCode(sig); - else if (!((et = a as ExportedType) is null)) + else if ((et = a as ExportedType) is not null) hash = GetHashCode(et); else hash = 0; // Should never be reached @@ -1008,7 +1008,7 @@ public bool Equals(TypeDef a, TypeRef b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (!(tra is null)) { + if (tra is not null) { result = Equals(tra, b); goto exit; } @@ -1018,19 +1018,19 @@ public bool Equals(TypeDef a, TypeRef b) { if (!Equals_TypeNames(a.Name, b.Name) || !Equals_TypeNamespaces(a.Namespace, b.Namespace)) result = false; - else if (!((dtb = scope as TypeRef) is null)) // nested type + else if ((dtb = scope as TypeRef) is not null) // nested type result = Equals(a.DeclaringType, dtb); // Compare enclosing types - else if (!(a.DeclaringType is null)) { + else if (a.DeclaringType is not null) { // a is nested, b isn't result = false; } else if (DontCompareTypeScope) result = true; - else if (!((bMod = scope as IModule) is null)) // 'b' is defined in the same assembly as 'a' + else if ((bMod = scope as IModule) is not null) // 'b' is defined in the same assembly as 'a' result = Equals(a, bMod, b); - else if (!((bAsm = scope as AssemblyRef) is null)) { + else if ((bAsm = scope as AssemblyRef) is not null) { var aMod = a.Module; - result = !(aMod is null) && Equals(aMod.Assembly, bAsm, b); + result = aMod is not null && Equals(aMod.Assembly, bAsm, b); if (!result) { if (!DontCheckTypeEquivalence) { var tdb = b.Resolve(); @@ -1079,7 +1079,7 @@ public bool Equals(TypeDef a, ExportedType b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (!(tra is null)) { + if (tra is not null) { result = Equals(tra, b); goto exit; } @@ -1089,20 +1089,20 @@ public bool Equals(TypeDef a, ExportedType b) { if (!Equals_TypeNames(a.Name, b.TypeName) || !Equals_TypeNamespaces(a.Namespace, b.TypeNamespace)) result = false; - else if (!((dtb = scope as ExportedType) is null)) { // nested type + else if ((dtb = scope as ExportedType) is not null) { // nested type result = Equals(a.DeclaringType, dtb); // Compare enclosing types } - else if (!(a.DeclaringType is null)) { + else if (a.DeclaringType is not null) { result = false; // a is nested, b isn't } else if (DontCompareTypeScope) result = true; else { - if (!((bFile = scope as FileDef) is null)) + if ((bFile = scope as FileDef) is not null) result = Equals(a, bFile, b); - else if (!((bAsm = scope as AssemblyRef) is null)) { + else if ((bAsm = scope as AssemblyRef) is not null) { var aMod = a.Module; - result = !(aMod is null) && Equals(aMod.Assembly, bAsm, b); + result = aMod is not null && Equals(aMod.Assembly, bAsm, b); } else result = false; @@ -1483,7 +1483,7 @@ public bool Equals(TypeDef a, TypeDef b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); var trb = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b); - if (!(tra is null) || !(trb is null)) { + if (tra is not null || trb is not null) { result = Equals((IType)tra ?? a, (IType)trb ?? b); goto exit; } @@ -1514,13 +1514,13 @@ public int GetHashCode(TypeDef a) { return GetHashCodeGlobalType(); if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (!(tra is null)) + if (tra is not null) return GetHashCode(tra); } int hash; hash = GetHashCode_TypeName(a.Name); - if (!(a.DeclaringType is null)) + if (a.DeclaringType is not null) hash += HASHCODE_MAGIC_NESTED_TYPE; else hash += GetHashCode_TypeNamespace(a.Namespace); @@ -1586,29 +1586,29 @@ bool EqualsResolutionScope(TypeRef a, TypeRef b) { bool resolveCheck = true; // if one of them is a TypeRef, the other one must be too - if (!((ea = ra as TypeRef) is null) | !((eb = rb as TypeRef) is null)) { + if ((ea = ra as TypeRef) is not null | (eb = rb as TypeRef) is not null) { result = Equals(ea, eb); resolveCheck = false; } else if (DontCompareTypeScope) result = true; // only compare if both are modules - else if (!((ma = ra as IModule) is null) & !((mb = rb as IModule) is null)) + else if ((ma = ra as IModule) is not null & (mb = rb as IModule) is not null) result = Equals(a, ma, b, mb); // only compare if both are assemblies - else if (!((aa = ra as AssemblyRef) is null) & !((ab = rb as AssemblyRef) is null)) + else if ((aa = ra as AssemblyRef) is not null & (ab = rb as AssemblyRef) is not null) result = Equals(aa, a, ab, b); - else if (!(aa is null) && rb is ModuleRef) { + else if (aa is not null && rb is ModuleRef) { var bMod = b.Module; - result = !(bMod is null) && Equals(bMod.Assembly, b, aa, a); + result = bMod is not null && Equals(bMod.Assembly, b, aa, a); } - else if (!(ab is null) && ra is ModuleRef) { + else if (ab is not null && ra is ModuleRef) { var aMod = a.Module; - result = !(aMod is null) && Equals(aMod.Assembly, a, ab, b); + result = aMod is not null && Equals(aMod.Assembly, a, ab, b); } - else if (!(aa is null) && !((modDef = rb as ModuleDef) is null)) + else if (aa is not null && (modDef = rb as ModuleDef) is not null) result = Equals(modDef.Assembly, aa, a); - else if (!(ab is null) && !((modDef = ra as ModuleDef) is null)) + else if (ab is not null && (modDef = ra as ModuleDef) is not null) result = Equals(modDef.Assembly, ab, b); else { result = false; @@ -1618,7 +1618,7 @@ bool EqualsResolutionScope(TypeRef a, TypeRef b) { if (!DontCheckTypeEquivalence) { var td1 = a.Resolve(); var td2 = b.Resolve(); - if (!(td1 is null) && !(td2 is null)) + if (td1 is not null && td2 is not null) result = TypeDefScopeEquals(td1, td2); } } @@ -1654,21 +1654,21 @@ bool EqualsImplementation(ExportedType a, ExportedType b) { bool checkResolve = true; // if one of them is an ExportedType, the other one must be too - if (!((ea = ia as ExportedType) is null) | !((eb = ib as ExportedType) is null)) { + if ((ea = ia as ExportedType) is not null | (eb = ib as ExportedType) is not null) { result = Equals(ea, eb); checkResolve = false; } else if (DontCompareTypeScope) result = true; // only compare if both are files - else if (!((fa = ia as FileDef) is null) & !((fb = ib as FileDef) is null)) + else if ((fa = ia as FileDef) is not null & (fb = ib as FileDef) is not null) result = Equals(fa, fb); // only compare if both are assemblies - else if (!((aa = ia as AssemblyRef) is null) & !((ab = ib as AssemblyRef) is null)) + else if ((aa = ia as AssemblyRef) is not null & (ab = ib as AssemblyRef) is not null) result = Equals(aa, a, ab, b); - else if (!(fa is null) && !(ab is null)) + else if (fa is not null && ab is not null) result = Equals(a.DefinitionAssembly, ab, b); - else if (!(fb is null) && !(aa is null)) + else if (fb is not null && aa is not null) result = Equals(b.DefinitionAssembly, aa, a); else { result = false; @@ -1677,7 +1677,7 @@ bool EqualsImplementation(ExportedType a, ExportedType b) { if (!result && checkResolve && !DontCheckTypeEquivalence) { var td1 = a.Resolve(); var td2 = b.Resolve(); - if (!(td1 is null) && !(td2 is null)) + if (td1 is not null && td2 is not null) result = TypeDefScopeEquals(td1, td2); } @@ -1714,19 +1714,19 @@ bool EqualsScope(TypeRef a, ExportedType b) { bool checkResolve = true; // If one is a nested type, the other one must be too - if (!((ea = ra as TypeRef) is null) | !((eb = ib as ExportedType) is null)) { + if ((ea = ra as TypeRef) is not null | (eb = ib as ExportedType) is not null) { result = Equals(ea, eb); checkResolve = false; } else if (DontCompareTypeScope) result = true; - else if (!((ma = ra as IModule) is null) & !((fb = ib as FileDef) is null)) + else if ((ma = ra as IModule) is not null & (fb = ib as FileDef) is not null) result = Equals(a, ma, b, fb); - else if (!((aa = ra as AssemblyRef) is null) & !((ab = ib as AssemblyRef) is null)) + else if ((aa = ra as AssemblyRef) is not null & (ab = ib as AssemblyRef) is not null) result = Equals(aa, a, ab, b); - else if (!(ma is null) && !(ab is null)) + else if (ma is not null && ab is not null) result = Equals(a.DefinitionAssembly, ab, b); - else if (!(fb is null) && !(aa is null)) + else if (fb is not null && aa is not null) result = Equals(b.DefinitionAssembly, aa, a); else { checkResolve = false; @@ -1735,7 +1735,7 @@ bool EqualsScope(TypeRef a, ExportedType b) { if (!result && checkResolve && !DontCheckTypeEquivalence) { var td1 = a.Resolve(); var td2 = b.Resolve(); - if (!(td1 is null) && !(td2 is null)) + if (td1 is not null && td2 is not null) result = TypeDefScopeEquals(td1, td2); } @@ -1791,14 +1791,14 @@ internal bool Equals(IModule a, IModule b) { return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); } - static bool IsCorLib(ModuleDef a) => !(a is null) && a.IsManifestModule && a.Assembly.IsCorLib(); + static bool IsCorLib(ModuleDef a) => a is not null && a.IsManifestModule && a.Assembly.IsCorLib(); static bool IsCorLib(IModule a) { var mod = a as ModuleDef; - return !(mod is null) && mod.IsManifestModule && mod.Assembly.IsCorLib(); + return mod is not null && mod.IsManifestModule && mod.Assembly.IsCorLib(); } - static bool IsCorLib(Module a) => !(a is null) && a.Assembly.ManifestModule == a && a.Assembly == typeof(void).Assembly; + static bool IsCorLib(Module a) => a is not null && a.Assembly.ManifestModule == a && a.Assembly == typeof(void).Assembly; static bool IsCorLib(IAssembly a) => a.IsCorLib(); static bool IsCorLib(Assembly a) => a == typeof(void).Assembly; @@ -2005,7 +2005,7 @@ public int GetHashCode(TypeSig a) { return 0; int hash; - if (!(genericArguments is null)) + if (genericArguments is not null) a = genericArguments.Resolve(a); switch (a.ElementType) { @@ -2220,22 +2220,22 @@ public bool Equals(CallingConventionSig a, CallingConventionSig b) { case CallingConvention.NativeVarArg: case CallingConvention.Unmanaged: MethodBaseSig ma = a as MethodBaseSig, mb = b as MethodBaseSig; - result = !(ma is null) && !(mb is null) && Equals(ma, mb); + result = ma is not null && mb is not null && Equals(ma, mb); break; case CallingConvention.Field: FieldSig fa = a as FieldSig, fb = b as FieldSig; - result = !(fa is null) && !(fb is null) && Equals(fa, fb); + result = fa is not null && fb is not null && Equals(fa, fb); break; case CallingConvention.LocalSig: LocalSig la = a as LocalSig, lb = b as LocalSig; - result = !(la is null) && !(lb is null) && Equals(la, lb); + result = la is not null && lb is not null && Equals(la, lb); break; case CallingConvention.GenericInst: GenericInstMethodSig ga = a as GenericInstMethodSig, gb = b as GenericInstMethodSig; - result = !(ga is null) && !(gb is null) && Equals(ga, gb); + result = ga is not null && gb is not null && Equals(ga, gb); break; default: @@ -2507,15 +2507,15 @@ public bool Equals(IMethod a, IMethod b) { MemberRef mra, mrb; MethodSpec msa, msb; - if (!((mda = a as MethodDef) is null) & !((mdb = b as MethodDef) is null)) + if ((mda = a as MethodDef) is not null & (mdb = b as MethodDef) is not null) result = Equals(mda, mdb); - else if (!((mra = a as MemberRef) is null) & !((mrb = b as MemberRef) is null)) + else if ((mra = a as MemberRef) is not null & (mrb = b as MemberRef) is not null) result = Equals(mra, mrb); - else if (!((msa = a as MethodSpec) is null) && !((msb = b as MethodSpec) is null)) + else if ((msa = a as MethodSpec) is not null && (msb = b as MethodSpec) is not null) result = Equals(msa, msb); - else if (!(mda is null) && !(mrb is null)) + else if (mda is not null && mrb is not null) result = Equals(mda, mrb); - else if (!(mra is null) && !(mdb is null)) + else if (mra is not null && mdb is not null) result = Equals(mdb, mra); else result = false; @@ -2540,11 +2540,11 @@ public int GetHashCode(IMethod a) { MemberRef mra; MethodSpec msa; - if (!((mda = a as MethodDef) is null)) + if ((mda = a as MethodDef) is not null) hash = GetHashCode(mda); - else if (!((mra = a as MemberRef) is null)) + else if ((mra = a as MemberRef) is not null) hash = GetHashCode(mra); - else if (!((msa = a as MethodSpec) is null)) + else if ((msa = a as MethodSpec) is not null) hash = GetHashCode(msa); else hash = 0; @@ -2579,7 +2579,7 @@ public bool Equals(MethodDef a, MemberRef b) { if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (!(mra is null)) { + if (mra is not null) { result = Equals(mra, b); goto exit; } @@ -2612,7 +2612,7 @@ public bool Equals(MethodDef a, MethodDef b) { if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); var mrb = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b); - if (!(mra is null) || !(mrb is null)) { + if (mra is not null || mrb is not null) { result = Equals((IMethod)mra ?? a, (IMethod)mrb ?? b); goto exit; } @@ -2639,7 +2639,7 @@ public int GetHashCode(MethodDef a) { return 0; if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (!(mra is null)) + if (mra is not null) return GetHashCode(mra); } @@ -2700,7 +2700,7 @@ public int GetHashCode(MemberRef a) { int hash = GetHashCode_MethodFieldName(a.Name); GenericInstSig git; - if (SubstituteGenericParameters && !((git = GetGenericInstanceType(a.Class)) is null)) { + if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); hash += GetHashCode(a.Signature); @@ -2752,12 +2752,12 @@ public int GetHashCode(MethodSpec a) { // We must do this or it won't get the same hash code as some MethodInfos var oldOptions = SetOptions(SigComparerOptions_SubstituteGenericParameters); var gim = a.GenericInstMethodSig; - if (!(gim is null)) { + if (gim is not null) { InitializeGenericArguments(); genericArguments.PushMethodArgs(gim.GenericArguments); } int hash = GetHashCode(a.Method); - if (!(gim is null)) + if (gim is not null) genericArguments.PopMethodArgs(); RestoreOptions(oldOptions); @@ -2785,18 +2785,18 @@ bool Equals(IMemberRefParent a, IMemberRefParent b) { MethodDef ma, mb; TypeDef td; - if (!((ita = a as ITypeDefOrRef) is null) && !((itb = b as ITypeDefOrRef) is null)) + if ((ita = a as ITypeDefOrRef) is not null && (itb = b as ITypeDefOrRef) is not null) result = Equals((IType)ita, (IType)itb); - else if (!((moda = a as ModuleRef) is null) & !((modb = b as ModuleRef) is null)) { + else if ((moda = a as ModuleRef) is not null & (modb = b as ModuleRef) is not null) { ModuleDef omoda = moda.Module, omodb = modb.Module; result = Equals((IModule)moda, (IModule)modb) && Equals(omoda?.Assembly, omodb?.Assembly); } - else if (!((ma = a as MethodDef) is null) && !((mb = b as MethodDef) is null)) + else if ((ma = a as MethodDef) is not null && (mb = b as MethodDef) is not null) result = Equals(ma, mb); - else if (!(modb is null) && !((td = a as TypeDef) is null)) + else if (modb is not null && (td = a as TypeDef) is not null) result = EqualsGlobal(td, modb); - else if (!(moda is null) && !((td = b as TypeDef) is null)) + else if (moda is not null && (td = b as TypeDef) is not null) result = EqualsGlobal(td, moda); else result = false; @@ -2820,11 +2820,11 @@ int GetHashCode(IMemberRefParent a) { ITypeDefOrRef ita; MethodDef ma; - if (!((ita = a as ITypeDefOrRef) is null)) + if ((ita = a as ITypeDefOrRef) is not null) hash = GetHashCode((IType)ita); else if (a is ModuleRef) hash = GetHashCodeGlobalType(); - else if (!((ma = a as MethodDef) is null)) { + else if ((ma = a as MethodDef) is not null) { // Only use the declaring type so we get the same hash code when hashing a MethodBase. hash = GetHashCode(ma.DeclaringType); } @@ -2853,13 +2853,13 @@ public bool Equals(IField a, IField b) { FieldDef fa, fb; MemberRef ma, mb; - if (!((fa = a as FieldDef) is null) & !((fb = b as FieldDef) is null)) + if ((fa = a as FieldDef) is not null & (fb = b as FieldDef) is not null) result = Equals(fa, fb); - else if (!((ma = a as MemberRef) is null) & !((mb = b as MemberRef) is null)) + else if ((ma = a as MemberRef) is not null & (mb = b as MemberRef) is not null) result = Equals(ma, mb); - else if (!(fa is null) && !(mb is null)) + else if (fa is not null && mb is not null) result = Equals(fa, mb); - else if (!(fb is null) && !(ma is null)) + else if (fb is not null && ma is not null) result = Equals(fb, ma); else result = false; @@ -2883,9 +2883,9 @@ public int GetHashCode(IField a) { FieldDef fa; MemberRef ma; - if (!((fa = a as FieldDef) is null)) + if ((fa = a as FieldDef) is not null) hash = GetHashCode(fa); - else if (!((ma = a as MemberRef) is null)) + else if ((ma = a as MemberRef) is not null) hash = GetHashCode(ma); else hash = 0; @@ -3109,15 +3109,15 @@ public bool Equals(IType a, Type b) { TypeSig sig; ExportedType et; - if (!((td = a as TypeDef) is null)) + if ((td = a as TypeDef) is not null) result = Equals(td, b); - else if (!((tr = a as TypeRef) is null)) + else if ((tr = a as TypeRef) is not null) result = Equals(tr, b); - else if (!((ts = a as TypeSpec) is null)) + else if ((ts = a as TypeSpec) is not null) result = Equals(ts, b); - else if (!((sig = a as TypeSig) is null)) + else if ((sig = a as TypeSig) is not null) result = Equals(sig, b); - else if (!((et = a as ExportedType) is null)) + else if ((et = a as ExportedType) is not null) result = Equals(et, b); else result = false; @@ -3154,7 +3154,7 @@ public bool Equals(TypeDef a, Type b) { if (!DontProjectWinMDRefs) { var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (!(tra is null)) { + if (tra is not null) { result = Equals(tra, b); goto exit; } @@ -3216,15 +3216,15 @@ public bool Equals(TypeRef a, Type b) { result = false; else if (!Equals_TypeNames(a.Name, ReflectionExtensions.Unescape(b.Name)) || !Equals_TypeNamespaces(a.Namespace, b)) result = false; - else if (!((dta = scope as TypeRef) is null)) // nested type + else if ((dta = scope as TypeRef) is not null) // nested type result = Equals(dta, b.DeclaringType); // Compare enclosing types else if (b.IsNested) result = false; // b is nested, a isn't else if (DontCompareTypeScope) result = true; - else if (!((aMod = scope as IModule) is null)) // 'a' is defined in the same assembly as 'b' + else if ((aMod = scope as IModule) is not null) // 'a' is defined in the same assembly as 'b' result = Equals(b, aMod, a); - else if (!((aAsm = scope as AssemblyRef) is null)) + else if ((aAsm = scope as AssemblyRef) is not null) result = Equals(b.Assembly, aAsm, a); else { result = false; @@ -3324,7 +3324,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { return false; bool result; - if (!(genericArguments is null)) + if (genericArguments is not null) a = genericArguments.Resolve(a); switch (a.ElementType) { @@ -3354,7 +3354,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = false; else if (IsFnPtrElementType(b)) { a = a.Next.RemoveModifiers(); - result = !(a is null) && a.ElementType == ElementType.FnPtr; + result = a is not null && a.ElementType == ElementType.FnPtr; } else result = Equals(a.Next, b.GetElementType()); @@ -3365,7 +3365,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = false; else if (IsFnPtrElementType(b)) { a = a.Next.RemoveModifiers(); - result = !(a is null) && a.ElementType == ElementType.FnPtr; + result = a is not null && a.ElementType == ElementType.FnPtr; } else result = Equals(a.Next, b.GetElementType()); @@ -3376,7 +3376,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = false; else if (IsFnPtrElementType(b)) { a = a.Next.RemoveModifiers(); - result = !(a is null) && a.ElementType == ElementType.FnPtr; + result = a is not null && a.ElementType == ElementType.FnPtr; } else result = Equals(a.Next, b.GetElementType()); @@ -3393,7 +3393,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { var ara = a as ArraySig; result = ara.Rank == b.GetArrayRank() && (IsFnPtrElementType(b) ? - !((a = a.Next.RemoveModifiers()) is null) && a.ElementType == ElementType.FnPtr : + (a = a.Next.RemoveModifiers()) is not null && a.ElementType == ElementType.FnPtr : Equals(a.Next, b.GetElementType())); } break; @@ -3412,7 +3412,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { case ElementType.MVar: result = b.IsGenericParameter && b.GenericParameterPosition == (a as GenericSig).Number && - !(b.DeclaringMethod is null); + b.DeclaringMethod is not null; break; case ElementType.GenericInst: @@ -3494,15 +3494,15 @@ public bool Equals(ExportedType a, Type b) { result = false; else if (!Equals_TypeNames(a.TypeName, ReflectionExtensions.Unescape(b.Name)) || !Equals_TypeNamespaces(a.TypeNamespace, b)) result = false; - else if (!((dta = scope as ExportedType) is null)) // nested type + else if ((dta = scope as ExportedType) is not null) // nested type result = Equals(dta, b.DeclaringType); // Compare enclosing types else if (b.IsNested) result = false; // b is nested, a isn't else if (DontCompareTypeScope) result = true; - else if (!((aFile = scope as FileDef) is null)) + else if ((aFile = scope as FileDef) is not null) result = Equals(b, aFile, a); - else if (!((aAsm = scope as AssemblyRef) is null)) + else if ((aAsm = scope as AssemblyRef) is not null) result = Equals(b.Assembly, aAsm, a); else result = false; @@ -3821,11 +3821,11 @@ bool DeclaringTypeEquals(IMethod a, MethodBase b) { MemberRef mr; MethodSpec ms; - if (!((md = a as MethodDef) is null)) + if ((md = a as MethodDef) is not null) result = DeclaringTypeEquals(md, b); - else if (!((mr = a as MemberRef) is null)) + else if ((mr = a as MemberRef) is not null) result = DeclaringTypeEquals(mr, b); - else if (!((ms = a as MethodSpec) is null)) + else if ((ms = a as MethodSpec) is not null) result = DeclaringTypeEquals(ms, b); else result = false; @@ -3894,11 +3894,11 @@ public bool Equals(IMethod a, MethodBase b) { MemberRef mr; MethodSpec ms; - if (!((md = a as MethodDef) is null)) + if ((md = a as MethodDef) is not null) result = Equals(md, b); - else if (!((mr = a as MemberRef) is null)) + else if ((mr = a as MemberRef) is not null) result = Equals(mr, b); - else if (!((ms = a as MethodSpec) is null)) + else if ((ms = a as MethodSpec) is not null) result = Equals(ms, b); else result = false; @@ -3932,7 +3932,7 @@ public bool Equals(MethodDef a, MethodBase b) { bool result; if (!DontProjectWinMDRefs) { var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (!(mra is null)) { + if (mra is not null) { result = Equals(mra, b); goto exit; } @@ -3940,7 +3940,7 @@ public bool Equals(MethodDef a, MethodBase b) { var amSig = a.MethodSig; result = Equals_MethodFieldNames(a.Name, b.Name) && - !(amSig is null) && + amSig is not null && ((amSig.Generic && b.IsGenericMethodDefinition && b.IsGenericMethod) || (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)) && Equals(amSig, b) && @@ -4022,12 +4022,12 @@ public bool Equals(MemberRef a, MethodBase b) { else { var amSig = a.MethodSig; result = Equals_MethodFieldNames(a.Name, b.Name) && - !(amSig is null) && + amSig is not null && ((amSig.Generic && b.IsGenericMethodDefinition && b.IsGenericMethod) || (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)); GenericInstSig git; - if (SubstituteGenericParameters && !((git = GetGenericInstanceType(a.Class)) is null)) { + if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(amSig, b); @@ -4074,17 +4074,17 @@ bool Equals(IMemberRefParent a, Type b, Module bModule) { MethodDef ma; TypeDef td; - if (!((ita = a as ITypeDefOrRef) is null)) + if ((ita = a as ITypeDefOrRef) is not null) result = Equals((IType)ita, b); - else if (!((moda = a as ModuleRef) is null)) { + else if ((moda = a as ModuleRef) is not null) { var omoda = moda.Module; result = b is null && // b is null => it's the global type Equals(moda, bModule) && Equals(omoda?.Assembly, bModule.Assembly); } - else if (!((ma = a as MethodDef) is null)) + else if ((ma = a as MethodDef) is not null) result = Equals(ma.DeclaringType, b); - else if (b is null && !((td = a as TypeDef) is null)) + else if (b is null && (td = a as TypeDef) is not null) result = td.IsGlobalModuleType; else result = false; @@ -4127,7 +4127,7 @@ public bool Equals(MethodSpec a, MethodBase b) { result = result && DeclaringTypeEquals(a.Method, b); var gim = a.GenericInstMethodSig; - result = result && !(gim is null) && Equals(gim.GenericArguments, b.GetGenericArguments()); + result = result && gim is not null && Equals(gim.GenericArguments, b.GetGenericArguments()); recursionCounter.Decrement(); return result; @@ -4199,7 +4199,7 @@ int GetHashCode(IList a, Type declaringType) { int GetHashCode_ReturnType(MethodBase a) { var mi = a as MethodInfo; - if (!(mi is null)) + if (mi is not null) return GetHashCode(mi.ReturnParameter, a.DeclaringType); return GetHashCode(typeof(void)); } @@ -4276,7 +4276,7 @@ bool ReturnTypeEquals(TypeSig a, MethodBase b) { bool result; var mi = b as MethodInfo; - if (!(mi is null)) + if (mi is not null) result = Equals(a, mi.ReturnParameter, b.DeclaringType); else if (b is ConstructorInfo) result = IsSystemVoid(a); @@ -4427,9 +4427,9 @@ public bool Equals(IField a, FieldInfo b) { FieldDef fa; MemberRef ma; - if (!((fa = a as FieldDef) is null)) + if ((fa = a as FieldDef) is not null) result = Equals(fa, b); - else if (!((ma = a as MemberRef) is null)) + else if ((ma = a as MemberRef) is not null) result = Equals(ma, b); else result = false; @@ -4508,7 +4508,7 @@ public bool Equals(MemberRef a, FieldInfo b) { bool result = Equals_MethodFieldNames(a.Name, b.Name); GenericInstSig git; - if (SubstituteGenericParameters && !((git = GetGenericInstanceType(a.Class)) is null)) { + if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(a.FieldSig, b); diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 4928bb866..1792bfa4c 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -68,7 +68,7 @@ public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig, G if (reader.reader.Length == 0) return null; var csig = reader.ReadSig(); - if (!(csig is null)) + if (csig is not null) csig.ExtraData = reader.GetExtraData(); return csig; } diff --git a/src/DotNet/TIAHelper.cs b/src/DotNet/TIAHelper.cs index df55adcb1..3fc034946 100644 --- a/src/DotNet/TIAHelper.cs +++ b/src/DotNet/TIAHelper.cs @@ -51,7 +51,7 @@ static bool stricmp(UTF8String a, UTF8String b) { UTF8String scope = null, identifier = null; var tia = td.CustomAttributes.Find("System.Runtime.InteropServices.TypeIdentifierAttribute"); - if (!(tia is null)) { + if (tia is not null) { if (tia.ConstructorArguments.Count >= 2) { if (tia.ConstructorArguments[0].Type.GetElementType() != ElementType.String) return null; @@ -110,12 +110,12 @@ static byte[] Concat(byte[] a, byte b, byte[] c) { return data; } - internal static bool IsTypeDefEquivalent(TypeDef td) => !(GetInfo(td) is null) && CheckEquivalent(td); + internal static bool IsTypeDefEquivalent(TypeDef td) => GetInfo(td) is not null && CheckEquivalent(td); static bool CheckEquivalent(TypeDef td) { - Debug.Assert(!(td is null)); + Debug.Assert(td is not null); - for (int i = 0; !(td is null) && i < 1000; i++) { + for (int i = 0; td is not null && i < 1000; i++) { if (i != 0) { var info = GetInfo(td); if (info is null) diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 082130437..7f5944472 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -334,7 +334,7 @@ void InitializeClassLayout() { } ClassLayout GetOrCreateClassLayout() { var cl = ClassLayout; - if (!(cl is null)) + if (cl is not null) return cl; Interlocked.CompareExchange(ref classLayout, new ClassLayoutUser(0, 0), null); return classLayout; @@ -359,9 +359,9 @@ public TypeDef DeclaringType { var currentDeclaringType = DeclaringType2; if (currentDeclaringType == value) return; - if (!(currentDeclaringType is null)) + if (currentDeclaringType is not null) currentDeclaringType.NestedTypes.Remove(this); // Will set DeclaringType2 = null - if (!(value is null)) + if (value is not null) value.NestedTypes.Add(this); // Will set DeclaringType2 = value // Make sure this is clear. Will be set whenever it's inserted into ModulDef.Types @@ -542,7 +542,7 @@ protected virtual void InitializeCustomDebugInfos() => /// /// true if is not null /// - public bool HasClassLayout => !(ClassLayout is null); + public bool HasClassLayout => ClassLayout is not null; /// /// Gets/sets the packing size. If you write to this property but @@ -667,7 +667,7 @@ public bool IsDelegate { /// /// true if this is a nested type (it has a declaring type) /// - public bool IsNested => !(DeclaringType is null); + public bool IsNested => DeclaringType is not null; /// public bool IsPrimitive => this.IsPrimitive(); @@ -900,7 +900,7 @@ public bool HasSecurity { public bool IsGlobalModuleType { get { var mod = Module; - return !(mod is null) && mod.GlobalType == this; + return mod is not null && mod.GlobalType == this; } } @@ -920,7 +920,7 @@ public TypeSig GetEnumUnderlyingType() { var field = fields[i]; if (!field.IsLiteral && !field.IsStatic) { var fieldSig = field.FieldSig; - if (!(fieldSig is null)) + if (fieldSig is not null) return fieldSig.Type; } } @@ -949,11 +949,11 @@ public IMemberForwarded Resolve(MemberRef memberRef, SigComparerOptions options) return null; var methodSig = memberRef.MethodSig; - if (!(methodSig is null)) + if (methodSig is not null) return FindMethodCheckBaseType(memberRef.Name, methodSig, options, memberRef.Module); var fieldSig = memberRef.FieldSig; - if (!(fieldSig is null)) + if (fieldSig is not null) return FindFieldCheckBaseType(memberRef.Name, fieldSig, options, memberRef.Module); return null; @@ -1057,7 +1057,7 @@ public MethodDef FindStaticConstructor() { /// The class constructor public MethodDef FindOrCreateStaticConstructor() { var cctor = FindStaticConstructor(); - if (!(cctor is null)) + if (cctor is not null) return cctor; var implFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; @@ -1116,7 +1116,7 @@ public MethodDef FindDefaultConstructor() { if (!method.IsInstanceConstructor) continue; var sig = method.MethodSig; - if (!(sig is null) && sig.Params.Count == 0) + if (sig is not null && sig.Params.Count == 0) return method; } return null; @@ -1368,9 +1368,9 @@ public IEnumerable FindProperties(UTF8String name) { /// The method or null if it wasn't found public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; - while (!(td is null)) { + while (td is not null) { var md = td.FindMethod(name, sig, options, sourceModule); - if (!(md is null)) + if (md is not null) return md; td = td.BaseType.ResolveTypeDef(); } @@ -1384,9 +1384,9 @@ public MethodDef FindMethodCheckBaseType(UTF8String name, MethodSig sig, SigComp /// The method or null if it wasn't found public MethodDef FindMethodCheckBaseType(UTF8String name) { var td = this; - while (!(td is null)) { + while (td is not null) { var md = td.FindMethod(name); - if (!(md is null)) + if (md is not null) return md; td = td.BaseType.ResolveTypeDef(); } @@ -1420,9 +1420,9 @@ public MethodDef FindMethodCheckBaseType(UTF8String name) { /// The field or null if it wasn't found public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; - while (!(td is null)) { + while (td is not null) { var fd = td.FindField(name, sig, options, sourceModule); - if (!(fd is null)) + if (fd is not null) return fd; td = td.BaseType.ResolveTypeDef(); } @@ -1436,9 +1436,9 @@ public FieldDef FindFieldCheckBaseType(UTF8String name, FieldSig sig, SigCompare /// The field or null if it wasn't found public FieldDef FindFieldCheckBaseType(UTF8String name) { var td = this; - while (!(td is null)) { + while (td is not null) { var fd = td.FindField(name); - if (!(fd is null)) + if (fd is not null) return fd; td = td.BaseType.ResolveTypeDef(); } @@ -1453,9 +1453,9 @@ public FieldDef FindFieldCheckBaseType(UTF8String name) { /// The event or null if it wasn't found public EventDef FindEventCheckBaseType(UTF8String name, ITypeDefOrRef eventType) { var td = this; - while (!(td is null)) { + while (td is not null) { var ed = td.FindEvent(name, eventType); - if (!(ed is null)) + if (ed is not null) return ed; td = td.BaseType.ResolveTypeDef(); } @@ -1469,9 +1469,9 @@ public EventDef FindEventCheckBaseType(UTF8String name, ITypeDefOrRef eventType) /// The event or null if it wasn't found public EventDef FindEventCheckBaseType(UTF8String name) { var td = this; - while (!(td is null)) { + while (td is not null) { var ed = td.FindEvent(name); - if (!(ed is null)) + if (ed is not null) return ed; td = td.BaseType.ResolveTypeDef(); } @@ -1505,9 +1505,9 @@ public EventDef FindEventCheckBaseType(UTF8String name) { /// The property or null if it wasn't found public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, SigComparerOptions options, ModuleDef sourceModule) { var td = this; - while (!(td is null)) { + while (td is not null) { var pd = td.FindProperty(name, sig, options, sourceModule); - if (!(pd is null)) + if (pd is not null) return pd; td = td.BaseType.ResolveTypeDef(); } @@ -1521,9 +1521,9 @@ public PropertyDef FindPropertyCheckBaseType(UTF8String name, PropertySig sig, S /// The property or null if it wasn't found public PropertyDef FindPropertyCheckBaseType(UTF8String name) { var td = this; - while (!(td is null)) { + while (td is not null) { var pd = td.FindProperty(name); - if (!(pd is null)) + if (pd is not null) return pd; td = td.BaseType.ResolveTypeDef(); } @@ -1604,7 +1604,7 @@ internal virtual void OnLazyAdd2(int index, ref FieldDef value) { /// void IListListener.OnAdd(int index, FieldDef value) { - if (!(value.DeclaringType is null)) + if (value.DeclaringType is not null) throw new InvalidOperationException("Field is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; } @@ -1634,7 +1634,7 @@ internal virtual void OnLazyAdd2(int index, ref MethodDef value) { /// void IListListener.OnAdd(int index, MethodDef value) { - if (!(value.DeclaringType is null)) + if (value.DeclaringType is not null) throw new InvalidOperationException("Method is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; value.Parameters.UpdateThisParameterType(this); @@ -1661,8 +1661,8 @@ void IListListener.OnClear() { /// void IListListener.OnLazyAdd(int index, ref TypeDef value) { #if DEBUG - if (!(value.Module2 is null)) - throw new InvalidOperationException("Added nested type's !(Module is null)"); + if (value.Module2 is not null) + throw new InvalidOperationException("Added nested type's Module is not null"); if (value.DeclaringType != this) throw new InvalidOperationException("Added nested type's DeclaringType != this"); #endif @@ -1670,9 +1670,9 @@ void IListListener.OnLazyAdd(int index, ref TypeDef value) { /// void IListListener.OnAdd(int index, TypeDef value) { - if (!(value.DeclaringType is null)) + if (value.DeclaringType is not null) throw new InvalidOperationException("Nested type is already owned by another type. Set DeclaringType to null first."); - if (!(value.Module is null)) + if (value.Module is not null) throw new InvalidOperationException("Type is already owned by another module. Remove it from that module's type list."); value.DeclaringType2 = this; } @@ -1705,7 +1705,7 @@ internal virtual void OnLazyAdd2(int index, ref EventDef value) { /// void IListListener.OnAdd(int index, EventDef value) { - if (!(value.DeclaringType is null)) + if (value.DeclaringType is not null) throw new InvalidOperationException("Event is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; } @@ -1735,7 +1735,7 @@ internal virtual void OnLazyAdd2(int index, ref PropertyDef value) { /// void IListListener.OnAdd(int index, PropertyDef value) { - if (!(value.DeclaringType is null)) + if (value.DeclaringType is not null) throw new InvalidOperationException("Property is already owned by another type. Set DeclaringType to null first."); value.DeclaringType2 = this; } @@ -1765,7 +1765,7 @@ internal virtual void OnLazyAdd2(int index, ref GenericParam value) { /// void IListListener.OnAdd(int index, GenericParam value) { - if (!(value.Owner is null)) + if (value.Owner is not null) throw new InvalidOperationException("Generic param is already owned by another type/method. Set Owner to null first."); value.Owner = this; } @@ -1862,7 +1862,7 @@ protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { // If Class is MethodDef, then it should be a vararg method var parent = mr.Class; md = parent as MethodDef; - if (!(md is null)) + if (md is not null) return md; // If it's a TypeSpec, it must be a generic instance type @@ -1882,7 +1882,7 @@ protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { // If it's a TypeRef, resolve it as if it is a reference to a type in the // current module, even if its ResolutionScope happens to be some other // assembly/module (that's what the CLR does) - if (parent is TypeRef tr && !(Module is null)) + if (parent is TypeRef tr && Module is not null) td = Module.Find(tr); } if (td is null) @@ -2056,7 +2056,7 @@ protected override void InitializeCustomDebugInfos() { } /// - protected override ModuleDef GetModule2_NoLock() => !(DeclaringType2_NoLock is null) ? null : readerModule; + protected override ModuleDef GetModule2_NoLock() => DeclaringType2_NoLock is not null ? null : readerModule; /// /// Constructor diff --git a/src/DotNet/TypeDefFinder.cs b/src/DotNet/TypeDefFinder.cs index 1e953aa3e..bfd560093 100644 --- a/src/DotNet/TypeDefFinder.cs +++ b/src/DotNet/TypeDefFinder.cs @@ -54,7 +54,7 @@ bool IsCacheEnabled_NoLock { if (isCacheEnabled == value) return; - if (!(typeEnumerator is null)) { + if (typeEnumerator is not null) { typeEnumerator.Dispose(); typeEnumerator = null; } @@ -92,7 +92,7 @@ public TypeDefFinder(IEnumerable rootTypes, bool includeNestedTypes) { } void InitializeTypeEnumerator() { - if (!(typeEnumerator is null)) { + if (typeEnumerator is not null) { typeEnumerator.Dispose(); typeEnumerator = null; } @@ -227,7 +227,7 @@ TypeDef FindSlowNormal(string fullName) { TypeDef GetNextTypeDef() { while (typeEnumerator.MoveNext()) { var type = typeEnumerator.Current; - if (!(type is null)) + if (type is not null) return type; } return null; @@ -265,7 +265,7 @@ public void Dispose() { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif - if (!(typeEnumerator is null)) + if (typeEnumerator is not null) typeEnumerator.Dispose(); typeEnumerator = null; typeRefCache = null; diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index f520050d4..83a670513 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -9,9 +9,9 @@ namespace dnlib.DotNet { struct TypeHelper { RecursionCounter recursionCounter; - internal static bool ContainsGenericParameter(StandAloneSig ss) => !(ss is null) && TypeHelper.ContainsGenericParameter(ss.Signature); - internal static bool ContainsGenericParameter(InterfaceImpl ii) => !(ii is null) && TypeHelper.ContainsGenericParameter(ii.Interface); - internal static bool ContainsGenericParameter(GenericParamConstraint gpc) => !(gpc is null) && ContainsGenericParameter(gpc.Constraint); + internal static bool ContainsGenericParameter(StandAloneSig ss) => ss is not null && TypeHelper.ContainsGenericParameter(ss.Signature); + internal static bool ContainsGenericParameter(InterfaceImpl ii) => ii is not null && TypeHelper.ContainsGenericParameter(ii.Interface); + internal static bool ContainsGenericParameter(GenericParamConstraint gpc) => gpc is not null && ContainsGenericParameter(gpc.Constraint); internal static bool ContainsGenericParameter(MethodSpec ms) { if (ms is null) diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index f9a1ca779..d84382004 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -238,7 +238,7 @@ public void Dispose() { protected virtual void Dispose(bool disposing) { if (!disposing) return; - if (!(reader is null)) + if (reader is not null) reader.Dispose(); reader = null; } @@ -389,17 +389,17 @@ internal TypeSig ToTypeSig(ITypeDefOrRef type) { internal AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { AssemblyRef asmRef = null; - if (!(nonNestedTypeRef is null) && !(typeNameParserHelper is null)) + if (nonNestedTypeRef is not null && typeNameParserHelper is not null) asmRef = typeNameParserHelper.FindAssemblyRef(nonNestedTypeRef); - if (!(asmRef is null)) + if (asmRef is not null) return asmRef; var ownerAsm = ownerModule.Assembly; - if (!(ownerAsm is null)) + if (ownerAsm is not null) return ownerModule.UpdateRowId(ownerAsm.ToAssemblyRef()); return AssemblyRef.CurrentAssembly; } - internal bool IsValueType(TypeRef typeRef) => !(typeRef is null) && typeRef.IsValueType; + internal bool IsValueType(TypeRef typeRef) => typeRef is not null && typeRef.IsValueType; internal static void Verify(bool b, string msg) { if (!b) @@ -575,12 +575,12 @@ TypeSig ReadType(bool readAssemblyReference) { result = null; if (typeRef == nonNestedTypeRef) { var corLibSig = ownerModule.CorLibTypes.GetCorLibTypeSig(typeRef.Namespace, typeRef.Name, typeRef.DefinitionAssembly); - if (!(corLibSig is null)) + if (corLibSig is not null) result = corLibSig; } if (result is null) { var typeDef = Resolve(asmRef, typeRef); - result = ToTypeSig(!(typeDef is null) ? (ITypeDefOrRef)typeDef : typeRef); + result = ToTypeSig(typeDef is not null ? (ITypeDefOrRef)typeDef : typeRef); } if (tspecs.Count != 0) @@ -598,7 +598,7 @@ TypeDef Resolve(AssemblyRef asmRef, TypeRef typeRef) { if (!(AssemblyNameComparer.CompareAll.Equals(asmRef, asm) && asmRef.IsRetargetable == asm.IsRetargetable)) return null; var td = asm.Find(typeRef); - return !(td is null) && td.Module == ownerModule ? td : null; + return td is not null && td.Module == ownerModule ? td : null; } AssemblyRef ReadOptionalAssemblyRef() { @@ -722,7 +722,7 @@ IList ReadTSpecs() { AssemblyRef ReadAssemblyRef() { var asmRef = new AssemblyRefUser(); - if (!(ownerModule is null)) + if (ownerModule is not null) ownerModule.UpdateRowId(asmRef); asmRef.Name = ReadAssemblyNameId(); diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index 82277e9fa..cc5360eb4 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -195,13 +195,13 @@ protected virtual void InitializeCustomDebugInfos() => /// /// true if it's nested within another /// - public bool IsNested => !(DeclaringType is null); + public bool IsNested => DeclaringType is not null; /// public bool IsValueType { get { var td = Resolve(); - return !(td is null) && td.IsValueType; + return td is not null && td.IsValueType; } } @@ -262,7 +262,7 @@ public TypeDef Resolve(ModuleDef sourceModule) { /// If the type couldn't be resolved public TypeDef ResolveThrow(ModuleDef sourceModule) { var type = Resolve(sourceModule); - if (!(type is null)) + if (type is not null) return type; throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); } diff --git a/src/DotNet/TypeSig.cs b/src/DotNet/TypeSig.cs index d83af1569..2132725f5 100644 --- a/src/DotNet/TypeSig.cs +++ b/src/DotNet/TypeSig.cs @@ -490,17 +490,17 @@ public abstract class TypeDefOrRefSig : LeafSig { /// /// Returns true if != null /// - public bool IsTypeRef => !(TypeRef is null); + public bool IsTypeRef => TypeRef is not null; /// /// Returns true if != null /// - public bool IsTypeDef => !(TypeDef is null); + public bool IsTypeDef => TypeDef is not null; /// /// Returns true if != null /// - public bool IsTypeSpec => !(TypeSpec is null); + public bool IsTypeSpec => TypeSpec is not null; /// /// Gets the or null if it's not a @@ -606,19 +606,19 @@ public abstract class GenericSig : LeafSig { /// /// true if it has an owner or /// - public bool HasOwner => !(genericParamProvider is null); + public bool HasOwner => genericParamProvider is not null; /// /// true if it has an owner ( is /// not null) /// - public bool HasOwnerType => !(OwnerType is null); + public bool HasOwnerType => OwnerType is not null; /// /// true if it has an owner ( is /// not null) /// - public bool HasOwnerMethod => !(OwnerMethod is null); + public bool HasOwnerMethod => OwnerMethod is not null; /// /// Gets the owner type or null if the owner is a or if it diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index 1156d471e..ec416ed0d 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -56,7 +56,7 @@ UTF8String IFullName.Name { } set { var mr = ScopeType; - if (!(mr is null)) + if (mr is not null) mr.Name = value; } } @@ -97,7 +97,7 @@ ITypeDefOrRef IMemberRef.DeclaringType { public bool IsValueType { get { var sig = TypeSig; - return !(sig is null) && sig.IsValueType; + return sig is not null && sig.IsValueType; } } @@ -105,7 +105,7 @@ public bool IsValueType { public bool IsPrimitive { get { var sig = TypeSig; - return !(sig is null) && sig.IsPrimitive; + return sig is not null && sig.IsPrimitive; } } @@ -291,7 +291,7 @@ sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD, IContainsGenericParamete /// protected override TypeSig GetTypeSigAndExtraData_NoLock(out byte[] extraData) { var sig = readerModule.ReadTypeSignature(signatureOffset, gpContext, out extraData); - if (!(sig is null)) + if (sig is not null) sig.Rid = origRid; return sig; } diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index 35b346e96..362846adb 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -40,12 +40,12 @@ internal static string GetAssemblyNameString(UTF8String name, Version version, U sb.Append(c); } - if (!(version is null)) { + if (version is not null) { sb.Append(", Version="); sb.Append(CreateVersionWithNoUndefinedValues(version).ToString()); } - if (!(culture is null)) { + if (culture is not null) { sb.Append(", Culture="); sb.Append(UTF8String.IsNullOrEmpty(culture) ? "neutral" : culture.String); } diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index 24b820e7e..31f0090e5 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -172,7 +172,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { var mscorlib = module?.CorLibTypes.AssemblyRef; var asm = new AssemblyRefUser(GetName(clrAsm), contractAsmVersion, new PublicKeyToken(GetPublicKeyToken(clrAsm)), UTF8String.Empty); - if (!(mscorlib is null) && mscorlib.Name == mscorlibName && IsValidMscorlibVersion(mscorlib.Version)) + if (mscorlib is not null && mscorlib.Name == mscorlibName && IsValidMscorlibVersion(mscorlib.Version)) asm.Version = mscorlib.Version; if (module is ModuleDefMD mod) { Version ver = null; @@ -191,7 +191,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { if (ver is null || asmRef.Version > ver) ver = asmRef.Version; } - if (!(ver is null)) + if (ver is not null) asm.Version = ver; } @@ -201,7 +201,7 @@ static AssemblyRef CreateAssembly(ModuleDef module, ClrAssembly clrAsm) { static readonly UTF8String mscorlibName = new UTF8String("mscorlib"); // Silverlight uses 5.0.5.0 - static bool IsValidMscorlibVersion(Version version) => !(version is null) && (uint)version.Major <= 5; + static bool IsValidMscorlibVersion(Version version) => version is not null && (uint)version.Major <= 5; static UTF8String GetName(ClrAssembly clrAsm) => clrAsm switch { @@ -292,7 +292,7 @@ public static TypeRef ToCLR(ModuleDef module, TypeRef tr, out bool isClrValueTyp var defAsm = tr.DefinitionAssembly; if (defAsm is null || !defAsm.IsContentTypeWindowsRuntime) return null; - if (!(tr.DeclaringType is null)) + if (tr.DeclaringType is not null) return null; if (!winMDToCLR.TryGetValue(new ClassName(tr.Namespace, tr.Name), out var pc)) @@ -315,7 +315,7 @@ public static ExportedType ToCLR(ModuleDef module, ExportedType et) { var defAsm = et.DefinitionAssembly; if (defAsm is null || !defAsm.IsContentTypeWindowsRuntime) return null; - if (!(et.DeclaringType is null)) + if (et.DeclaringType is not null) return null; if (!winMDToCLR.TryGetValue(new ClassName(et.TypeNamespace, et.TypeName), out var pc)) @@ -347,7 +347,7 @@ public static TypeSig ToCLR(ModuleDef module, TypeSig ts) { if (newTr is null) return null; } - else if (!((tr = tdr as TypeRef) is null)) { + else if ((tr = tdr as TypeRef) is not null) { newTr = ToCLR(module, tr, out isClrValueType); if (newTr is null) return null; @@ -389,7 +389,7 @@ public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { newCl = newTr; } - else if (!((ts = cl as TypeSpec) is null)) { + else if ((ts = cl as TypeSpec) is not null) { var gis = ts.TypeSig as GenericInstSig; if (gis is null || !(gis.GenericType is ClassSig)) return null; diff --git a/src/DotNet/Writer/BlobHeap.cs b/src/DotNet/Writer/BlobHeap.cs index 908c7180a..b34b1729d 100644 --- a/src/DotNet/Writer/BlobHeap.cs +++ b/src/DotNet/Writer/BlobHeap.cs @@ -28,7 +28,7 @@ public sealed class BlobHeap : HeapBase, IOffsetHeap { public void Populate(BlobStream blobStream) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Blob when it's read-only"); - if (!(originalData is null)) + if (originalData is not null) throw new InvalidOperationException("Can't call method twice"); if (nextOffset != 1) throw new InvalidOperationException("Add() has already been called"); @@ -99,15 +99,15 @@ uint AddToCache(byte[] data) { /// protected override void WriteToImpl(DataWriter writer) { - if (!(originalData is null)) + if (originalData is not null) writer.WriteBytes(originalData); else writer.WriteByte(0); - uint offset = !(originalData is null) ? (uint)originalData.Length : 1; + uint offset = originalData is not null ? (uint)originalData.Length : 1; foreach (var data in cached) { int rawLen = GetRawDataSize(data); - if (!(userRawData is null) && userRawData.TryGetValue(offset, out var rawData)) { + if (userRawData is not null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); writer.WriteBytes(rawData); @@ -134,7 +134,7 @@ public void SetRawData(uint offset, byte[] rawData) { public IEnumerable> GetAllRawData() { var memStream = new MemoryStream(); var writer = new DataWriter(memStream); - uint offset = !(originalData is null) ? (uint)originalData.Length : 1; + uint offset = originalData is not null ? (uint)originalData.Length : 1; foreach (var data in cached) { memStream.Position = 0; memStream.SetLength(0); diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 6dc9deb13..0bd6c5f37 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -57,7 +57,7 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public override bool Equals(object obj) { var other = obj as ByteArrayChunk; - return !(other is null) && Utils.Equals(array, other.array); + return other is not null && Utils.Equals(array, other.array); } } } diff --git a/src/DotNet/Writer/ChunkList.cs b/src/DotNet/Writer/ChunkList.cs index 8ca6a008a..2f2fd0848 100644 --- a/src/DotNet/Writer/ChunkList.cs +++ b/src/DotNet/Writer/ChunkList.cs @@ -21,7 +21,7 @@ public class ChunkList : ChunkListBase where T : class, IChunk { public void Add(T chunk, uint alignment) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); - if (!(chunk is null)) + if (chunk is not null) chunks.Add(new Elem(chunk, alignment)); } @@ -33,7 +33,7 @@ public void Add(T chunk, uint alignment) { public uint? Remove(T chunk) { if (setOffsetCalled) throw new InvalidOperationException("SetOffset() has already been called"); - if (!(chunk is null)) { + if (chunk is not null) { var chunks = this.chunks; for (int i = 0; i < chunks.Count; i++) { if (chunks[i].chunk == chunk) { diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index 2a6cd2a75..3d46200cd 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -93,7 +93,7 @@ void Write(CustomAttribute ca) { // Check whether it's raw first. If it is, we don't care whether the ctor is // invalid. Just use the raw data. if (ca.IsRawBlob) { - if ((!(ca.ConstructorArguments is null) && ca.ConstructorArguments.Count > 0) || (!(ca.NamedArguments is null) && ca.NamedArguments.Count > 0)) + if ((ca.ConstructorArguments is not null && ca.ConstructorArguments.Count > 0) || (ca.NamedArguments is not null && ca.NamedArguments.Count > 0)) helper.Error("Raw custom attribute contains arguments and/or named arguments"); writer.WriteBytes(ca.RawData); return; @@ -112,7 +112,7 @@ void Write(CustomAttribute ca) { if (ca.ConstructorArguments.Count != methodSig.Params.Count) helper.Error("Custom attribute arguments count != method sig arguments count"); - if (!(methodSig.ParamsAfterSentinel is null) && methodSig.ParamsAfterSentinel.Count > 0) + if (methodSig.ParamsAfterSentinel is not null && methodSig.ParamsAfterSentinel.Count > 0) helper.Error("Custom attribute ctor has parameters after the sentinel"); if (ca.NamedArguments.Count > ushort.MaxValue) helper.Error("Custom attribute has too many named arguments"); @@ -164,7 +164,7 @@ void WriteValue(TypeSig argType, CAArgument value) { if (argType is SZArraySig arrayType) { var argsArray = value.Value as IList; - if (argsArray is null && !(value.Value is null)) + if (argsArray is null && value.Value is not null) helper.Error("CAArgument.Value is not null or an array"); WriteArrayValue(arrayType, argsArray); } @@ -213,7 +213,7 @@ bool VerifyTypeAndValue(CAArgument value, ElementType etype, Type valueType) { static bool VerifyType(TypeSig type, ElementType etype) { type = type.RemoveModifiers(); // Assume it's an enum if it's a ValueType - return !(type is null) && (etype == type.ElementType || type.ElementType == ElementType.ValueType); + return type is not null && (etype == type.ElementType || type.ElementType == ElementType.ValueType); } static bool VerifyValue(object o, ElementType etype) { @@ -483,7 +483,7 @@ void WriteElem(TypeSig argType, CAArgument value) { case ElementType.ValueType: tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; underlyingType = GetEnumUnderlyingType(argType); - if (!(underlyingType is null)) + if (underlyingType is not null) WriteElem(underlyingType, value); else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value)) { // No error. Assume it's an enum that couldn't be resolved. @@ -606,11 +606,11 @@ static TypeDef GetEnumTypeDef(TypeSig type) { static TypeDef GetTypeDef(TypeSig type) { if (type is TypeDefOrRefSig tdr) { var td = tdr.TypeDef; - if (!(td is null)) + if (td is not null) return td; var tr = tdr.TypeRef; - if (!(tr is null)) + if (tr is not null) return tr.Resolve(); } @@ -690,7 +690,7 @@ void WriteFieldOrPropType(TypeSig type) { tdr = ((TypeDefOrRefSig)type).TypeDefOrRef; var enumType = GetEnumTypeDef(type); // If TypeRef => assume it's an enum that couldn't be resolved - if (!(enumType is null) || tdr is TypeRef) { + if (enumType is not null || tdr is TypeRef) { writer.WriteByte((byte)SerializationType.Enum); WriteType(tdr); } @@ -751,7 +751,7 @@ void WriteUTF8String(UTF8String s) { public void Dispose() { if (!disposeStream) return; - if (!(outStream is null)) + if (outStream is not null) outStream.Dispose(); } } diff --git a/src/DotNet/Writer/DeclSecurityWriter.cs b/src/DotNet/Writer/DeclSecurityWriter.cs index 56b978e42..10c41eaa5 100644 --- a/src/DotNet/Writer/DeclSecurityWriter.cs +++ b/src/DotNet/Writer/DeclSecurityWriter.cs @@ -52,7 +52,7 @@ byte[] Write(IList secAttrs) { secAttrs = Array2.Empty(); var xml = DeclSecurity.GetNet1xXmlStringInternal(secAttrs); - if (!(xml is null)) + if (xml is not null) return WriteFormat1(xml); return WriteFormat2(secAttrs); } diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 221d9b33c..8f9bdf87a 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -119,7 +119,7 @@ public ManagedExportsWriter(string moduleName, Machine machine, RelocDirectory r internal void AddTextChunks(PESection textSection) { textSection.Add(vtableFixups, DEFAULT_VTBL_FIXUPS_ALIGNMENT); - if (!(cpuArch is null)) + if (cpuArch is not null) textSection.Add(stubsChunk, cpuArch.GetStubAlignment(stubType)); } @@ -182,7 +182,7 @@ void Initialize(List methods, uint timestamp) { uint stubSize = cpuArch.GetStubSize(stubType); foreach (var method in methods) { var exportInfo = method.ExportInfo; - Debug.Assert(!(exportInfo is null)); + Debug.Assert(exportInfo is not null); if (exportInfo is null) continue; @@ -282,7 +282,7 @@ uint GetOffset(string name, out byte[] bytes) { // If this method gets updated, also update the reader (MethodExportInfoProvider) static byte[] GetNameASCIIZ(string name) { - Debug.Assert(!(name is null)); + Debug.Assert(name is not null); int size = Encoding.UTF8.GetByteCount(name); var bytes = new byte[size + 1]; Encoding.UTF8.GetBytes(name, 0, name.Length, bytes, 0); @@ -339,7 +339,7 @@ void WriteSdataBlob(uint timestamp) { var exportInfo = info.Method.ExportInfo; var name = exportInfo.Name; if (name is null) { - if (!(exportInfo.Ordinal is null)) { + if (exportInfo.Ordinal is not null) { sortedOrdinalMethodInfos.Add(info); continue; } diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 9ad8caa8d..550c0dcab 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -114,7 +114,7 @@ byte[] Write(MarshalType marshalType) { case NativeType.RawBlob: var data = ((RawMarshalType)marshalType).Data; - if (!(data is null)) + if (data is not null) writer.WriteBytes(data); break; diff --git a/src/DotNet/Writer/MaxStackCalculator.cs b/src/DotNet/Writer/MaxStackCalculator.cs index 5d0f783b8..621d97f0a 100644 --- a/src/DotNet/Writer/MaxStackCalculator.cs +++ b/src/DotNet/Writer/MaxStackCalculator.cs @@ -70,13 +70,13 @@ internal bool Calculate(out uint maxStack) { if (eh is null) continue; Instruction instr; - if (!((instr = eh.TryStart) is null)) + if ((instr = eh.TryStart) is not null) stackHeights[instr] = 0; - if (!((instr = eh.FilterStart) is null)) { + if ((instr = eh.FilterStart) is not null) { stackHeights[instr] = 1; currentMaxStack = 1; } - if (!((instr = eh.HandlerStart) is null)) { + if ((instr = eh.HandlerStart) is not null) { bool pushed = eh.HandlerType == ExceptionHandlerType.Catch || eh.HandlerType == ExceptionHandlerType.Filter; if (pushed) { stackHeights[instr] = 1; diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 4d8022340..541d60626 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -1529,7 +1529,7 @@ void Create() { AddExportedTypes(); InitializeEntryPoint(); - if (!(module.Assembly is null)) + if (module.Assembly is not null) AddAssembly(module.Assembly, AssemblyPublicKey); OnMetadataEvent(Writer.MetadataEvent.BeforeSortTables); @@ -1617,7 +1617,7 @@ void InitializeTypeDefsAndMemberDefs() { Error("Method is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); continue; } - if (!(method.ExportInfo is null)) + if (method.ExportInfo is not null) ExportedMethods.Add(method); uint rid = GetRid(method); var row = tablesHeap.MethodTable[rid]; @@ -1924,7 +1924,7 @@ void InitializeCustomAttributeAndCustomDebugInfoTables() { foreach (var info in customAttributeInfos.infos) tablesHeap.CustomAttributeTable.Create(info.row); - if (!(debugMetadata is null)) { + if (debugMetadata is not null) { debugMetadata.stateMachineMethodInfos.Sort((a, b) => a.row.MoveNextMethod.CompareTo(b.row.MoveNextMethod)); debugMetadata.tablesHeap.StateMachineMethodTable.IsSorted = true; foreach (var info in debugMetadata.stateMachineMethodInfos.infos) @@ -1997,7 +1997,7 @@ void WriteMethodBodies() { uint localVarSigTok = 0; var cilBody = method.Body; - if (!(cilBody is null)) { + if (cilBody is not null) { if (!(cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0)) { writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); writer.Write(); @@ -2010,18 +2010,18 @@ void WriteMethodBodies() { } else { var nativeBody = method.NativeBody; - if (!(nativeBody is null)) + if (nativeBody is not null) methodToNativeBody[method] = nativeBody; - else if (!(method.MethodBody is null)) + else if (method.MethodBody is not null) Error("Unsupported method body"); } - if (!(debugMetadata is null)) { + if (debugMetadata is not null) { uint rid = GetRid(method); - if (!(cilBody is null)) { + if (cilBody is not null) { var pdbMethod = cilBody.PdbMethod; - if (!(pdbMethod is null)) { + if (pdbMethod is not null) { // We don't need to write empty scopes if (!IsEmptyRootScope(cilBody, pdbMethod.Scope)) { serializerMethodContext.SetBody(method); @@ -2048,7 +2048,7 @@ void WriteMethodBodies() { } } } - if (!(debugMetadata is null)) { + if (debugMetadata is not null) { methodScopeDebugInfos.Sort((a, b) => { int c = a.MethodRid.CompareTo(b.MethodRid); if (c != 0) @@ -2084,7 +2084,7 @@ void WriteMethodBodies() { foreach (var info in debugMetadata.localScopeInfos.infos) debugMetadata.tablesHeap.LocalScopeTable.Create(info.row); } - if (!(serializerMethodContext is null)) + if (serializerMethodContext is not null) Free(ref serializerMethodContext); } @@ -2095,13 +2095,13 @@ static bool IsEmptyRootScope(CilBody cilBody, PdbScope scope) { return false; if (scope.Namespaces.Count != 0) return false; - if (!(scope.ImportScope is null)) + if (scope.ImportScope is not null) return false; if (scope.Scopes.Count != 0) return false; if (scope.CustomDebugInfos.Count != 0) return false; - if (!(scope.End is null)) + if (scope.End is not null) return false; if (cilBody.Instructions.Count != 0 && cilBody.Instructions[0] != scope.Start) return false; @@ -2120,7 +2120,7 @@ protected static bool IsEmpty(IList list) where T : class { return true; int count = list.Count; for (int i = 0; i < count; i++) { - if (!(list[i] is null)) + if (list[i] is not null) return false; } return true; @@ -2198,7 +2198,7 @@ protected virtual uint AddStandAloneSig(FieldSig fieldSig, uint origToken) { } uint AddMDTokenProvider(IMDTokenProvider tp) { - if (!(tp is null)) { + if (tp is not null) { switch (tp.MDToken.Table) { case Table.Module: return AddModule((ModuleDef)tp); @@ -2519,7 +2519,7 @@ protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { return rid; var asmAttrs = asm.Attributes; - if (!(publicKey is null)) + if (publicKey is not null) asmAttrs |= AssemblyAttributes.PublicKey; else publicKey = PublicKeyBase.GetRawData(asm.PublicKeyOrToken); @@ -3112,7 +3112,7 @@ protected uint GetSignature(CallingConventionSig sig) { } void AppendExtraData(ref byte[] blob, byte[] extraData) { - if (PreserveExtraSignatureData && !(extraData is null) && extraData.Length > 0) { + if (PreserveExtraSignatureData && extraData is not null && extraData.Length > 0) { int blen = blob is null ? 0 : blob.Length; Array.Resize(ref blob, blen + extraData.Length); Array.Copy(extraData, 0, blob, blen, extraData.Length); @@ -3153,7 +3153,7 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { } void AddCustomDebugInformationList(MethodDef method, uint rid, uint localVarSigToken) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (debugMetadata is null) return; var serializerMethodContext = AllocSerializerMethodContext(); @@ -3165,7 +3165,7 @@ void AddCustomDebugInformationList(MethodDef method, uint rid, uint localVarSigT } void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); var body = method.Body; if (body is null) return; @@ -3253,7 +3253,7 @@ void AddMethodDebugInformation(MethodDef method, uint rid, uint localVarSigToken } uint VerifyGetRid(PdbDocument doc) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (!debugMetadata.pdbDocumentInfos.TryGetRid(doc, out uint rid)) { Error("PDB document has been removed"); return 0; @@ -3318,7 +3318,7 @@ void AddCustomDebugInformationList(Table table, uint rid, IList cdis) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); Debug.Assert(cdis.Count != 0); var token = new MDToken(table, rid); @@ -3339,7 +3339,7 @@ void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodConte } void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, uint token, uint encodedToken, PdbCustomDebugInfo cdi) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); switch (cdi.Kind) { case PdbCustomDebugInfoKind.UsingGroups: @@ -3386,7 +3386,7 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, MethodDef kickoffMethod) { Debug.Assert(new MDToken(moveNextMethodToken).Table == Table.Method); - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (kickoffMethod is null) { Error("KickoffMethod is null"); return; @@ -3396,7 +3396,7 @@ void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, Met } void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodContext, uint encodedToken, PdbCustomDebugInfo cdi, Guid cdiGuid) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); var bwctx = AllocBinaryWriterContext(); var cdiBlob = PortablePdbCustomDebugInfoWriter.Write(this, serializerMethodContext, this, cdi, bwctx); @@ -3424,7 +3424,7 @@ void AddPdbDocuments() { } uint AddPdbDocument(PdbDocument doc) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (doc is null) { Error("PdbDocument is null"); return 0; @@ -3442,7 +3442,7 @@ uint AddPdbDocument(PdbDocument doc) { } uint GetDocumentNameBlobOffset(string name) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (name is null) { Error("Document name is null"); name = string.Empty; @@ -3472,7 +3472,7 @@ uint GetDocumentNameBlobOffset(string name) { static readonly char[] directorySeparatorCharArray = new char[] { Path.DirectorySeparatorChar }; uint AddImportScope(PdbImportScope scope) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (scope is null) return 0; if (debugMetadata.importScopeInfos.TryGetRid(scope, out uint rid)) { @@ -3500,7 +3500,7 @@ uint AddImportScope(PdbImportScope scope) { } void AddLocalVariable(PdbLocal local) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (local is null) { Error("PDB local is null"); return; @@ -3512,7 +3512,7 @@ void AddLocalVariable(PdbLocal local) { } void AddLocalConstant(PdbConstant constant) { - Debug.Assert(!(debugMetadata is null)); + Debug.Assert(debugMetadata is not null); if (constant is null) { Error("PDB constant is null"); return; diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index 6c3871d87..b6c4cfef0 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -53,7 +53,7 @@ public sealed class MethodBody : IChunk { /// /// true if there's an extra section /// - public bool HasExtraSections => !(extraSections is null) && extraSections.Length > 0; + public bool HasExtraSections => extraSections is not null && extraSections.Length > 0; /// /// Constructor @@ -90,7 +90,7 @@ public MethodBody(byte[] code, byte[] extraSections, uint localVarSigTok) { /// public int GetApproximateSizeOfMethodBody() { int len = code.Length; - if (!(extraSections is null)) { + if (extraSections is not null) { len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); len += extraSections.Length; len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index 379103535..bb5198613 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -118,7 +118,7 @@ public byte[] GetFullMethodBody() { int padding = Utils.AlignUp(code.Length, 4) - code.Length; var bytes = new byte[code.Length + (extraSections is null ? 0 : padding + extraSections.Length)]; Array.Copy(code, 0, bytes, 0, code.Length); - if (!(extraSections is null)) + if (extraSections is not null) Array.Copy(extraSections, 0, bytes, code.Length + padding, extraSections.Length); return bytes; } diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index 09107b82c..d4ade9ae9 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -173,7 +173,7 @@ void CreateSections() { sections.Add(mvidSection = new PESection(".mvid", 0x42000040)); sections.Add(textSection = new PESection(".text", 0x60000020)); sections.Add(sdataSection = new PESection(".sdata", 0xC0000040)); - if (!(GetWin32Resources() is null)) + if (GetWin32Resources() is not null) sections.Add(rsrcSection = new PESection(".rsrc", 0x40000040)); // Should be last so any data in a previous section can add relocations sections.Add(relocSection = new PESection(".reloc", 0x42000040)); @@ -209,7 +209,7 @@ void AddChunksToSections() { bool is64bit = machine.Is64Bit(); uint pointerAlignment = is64bit ? 8U : 4; - if (!(mvidSection is null)) + if (mvidSection is not null) mvidSection.Add(new ByteArrayChunk((module.Mvid ?? Guid.Empty).ToByteArray()), MVID_ALIGNMENT); textSection.Add(importAddressTable, pointerAlignment); textSection.Add(imageCor20Header, DEFAULT_COR20HEADER_ALIGNMENT); @@ -223,7 +223,7 @@ void AddChunksToSections() { textSection.Add(importDirectory, pointerAlignment); textSection.Add(startupStub, startupStub.Alignment); managedExportsWriter.AddSdataChunks(sdataSection); - if (!(GetWin32Resources() is null)) + if (GetWin32Resources() is not null) rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); relocSection.Add(relocDirectory, DEFAULT_RELOC_ALIGNMENT); } @@ -268,7 +268,7 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.EndWriteChunks); OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); - if (!(Options.StrongNameKey is null)) + if (Options.StrongNameKey is not null) StrongNameSign((long)strongNameSignature.FileOffset); OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index d796560ef..89af5c372 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -368,10 +368,10 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PEHeadersOptions.NumberOfRvaAndSizes = 0x10; Cor20HeaderOptions.Flags = module.Cor20HeaderFlags; - if (!(module.Assembly is null) && !PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey)) + if (module.Assembly is not null && !PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey)) Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; - if (!(module.Cor20HeaderRuntimeVersion is null)) { + if (module.Cor20HeaderRuntimeVersion is not null) { Cor20HeaderOptions.MajorRuntimeVersion = (ushort)(module.Cor20HeaderRuntimeVersion.Value >> 16); Cor20HeaderOptions.MinorRuntimeVersion = (ushort)module.Cor20HeaderRuntimeVersion.Value; } @@ -384,7 +384,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { Cor20HeaderOptions.MinorRuntimeVersion = 5; } - if (!(module.TablesHeaderVersion is null)) { + if (module.TablesHeaderVersion is not null) { MetadataOptions.TablesHeapOptions.MajorVersion = (byte)(module.TablesHeaderVersion.Value >> 8); MetadataOptions.TablesHeapOptions.MinorVersion = (byte)module.TablesHeaderVersion.Value; } @@ -403,7 +403,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { MetadataOptions.Flags |= MetadataFlags.AlwaysCreateGuidHeap; var modDefMD = module as ModuleDefMD; - if (!(modDefMD is null)) { + if (modDefMD is not null) { var ntHeaders = modDefMD.Metadata.PEImage.ImageNTHeaders; PEHeadersOptions.TimeDateStamp = ntHeaders.FileHeader.TimeDateStamp; PEHeadersOptions.MajorLinkerVersion = ntHeaders.OptionalHeader.MajorLinkerVersion; @@ -496,7 +496,7 @@ static bool TryGetPdbChecksumAlgorithm(ref DataReader reader, out ChecksumAlgori public void InitializeStrongNameSigning(ModuleDef module, StrongNameKey signatureKey) { StrongNameKey = signatureKey; StrongNamePublicKey = null; - if (!(module.Assembly is null)) + if (module.Assembly is not null) module.Assembly.CustomAttributes.RemoveAll("System.Reflection.AssemblySignatureKeyAttribute"); } @@ -526,7 +526,7 @@ public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey signatureKey, StrongNamePublicKey signaturePubKey, StrongNameKey identityKey, StrongNamePublicKey identityPubKey) { StrongNameKey = signatureKey.WithHashAlgorithm(signaturePubKey.HashAlgorithm); StrongNamePublicKey = identityPubKey; - if (!(module.Assembly is null)) + if (module.Assembly is not null) module.Assembly.UpdateOrCreateAssemblySignatureKeyAttribute(identityPubKey, identityKey, signaturePubKey); } } @@ -685,13 +685,13 @@ static void DeleteFileNoThrow(string fileName) { /// /// Destination stream public void Write(Stream dest) { - pdbState = TheOptions.WritePdb && !(Module.PdbState is null) ? Module.PdbState : null; + pdbState = TheOptions.WritePdb && Module.PdbState is not null ? Module.PdbState : null; if (TheOptions.DelaySign) { - Debug.Assert(!(TheOptions.StrongNamePublicKey is null), "Options.StrongNamePublicKey must be initialized when delay signing the assembly"); + Debug.Assert(TheOptions.StrongNamePublicKey is not null, "Options.StrongNamePublicKey must be initialized when delay signing the assembly"); Debug.Assert(TheOptions.StrongNameKey is null, "Options.StrongNameKey must be null when delay signing the assembly"); TheOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.StrongNameSigned; } - else if (!(TheOptions.StrongNameKey is null) || !(TheOptions.StrongNamePublicKey is null)) + else if (TheOptions.StrongNameKey is not null || TheOptions.StrongNamePublicKey is not null) TheOptions.Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; destStream = dest; @@ -719,13 +719,13 @@ public void Write(Stream dest) { /// set or wants to sign the assembly. /// protected void CreateStrongNameSignature() { - if (TheOptions.DelaySign && !(TheOptions.StrongNamePublicKey is null)) { + if (TheOptions.DelaySign && TheOptions.StrongNamePublicKey is not null) { int len = TheOptions.StrongNamePublicKey.CreatePublicKey().Length - 0x20; strongNameSignature = new StrongNameSignature(len > 0 ? len : 0x80); } - else if (!(TheOptions.StrongNameKey is null)) + else if (TheOptions.StrongNameKey is not null) strongNameSignature = new StrongNameSignature(TheOptions.StrongNameKey.SignatureSize); - else if (!(Module.Assembly is null) && !PublicKeyBase.IsNullOrEmpty2(Module.Assembly.PublicKey)) { + else if (Module.Assembly is not null && !PublicKeyBase.IsNullOrEmpty2(Module.Assembly.PublicKey)) { int len = Module.Assembly.PublicKey.Data.Length - 0x20; strongNameSignature = new StrongNameSignature(len > 0 ? len : 0x80); } @@ -744,7 +744,7 @@ protected void CreateMetadataChunks(ModuleDef module) { netResources = new NetResources(DEFAULT_NETRESOURCES_ALIGNMENT); DebugMetadataKind debugKind; - if (!(pdbState is null) && (pdbState.PdbFileKind == PdbFileKind.PortablePDB || pdbState.PdbFileKind == PdbFileKind.EmbeddedPortablePDB)) + if (pdbState is not null && (pdbState.PdbFileKind == PdbFileKind.PortablePDB || pdbState.PdbFileKind == PdbFileKind.EmbeddedPortablePDB)) debugKind = DebugMetadataKind.Standalone; else debugKind = DebugMetadataKind.None; @@ -756,13 +756,13 @@ protected void CreateMetadataChunks(ModuleDef module) { // StrongNamePublicKey is used if the user wants to override the assembly's // public key or when enhanced strong naming the assembly. var pk = TheOptions.StrongNamePublicKey; - if (!(pk is null)) + if (pk is not null) metadata.AssemblyPublicKey = pk.CreatePublicKey(); - else if (!(TheOptions.StrongNameKey is null)) + else if (TheOptions.StrongNameKey is not null) metadata.AssemblyPublicKey = TheOptions.StrongNameKey.PublicKey; var w32Resources = GetWin32Resources(); - if (!(w32Resources is null)) + if (w32Resources is not null) win32Resources = new Win32ResourcesChunk(w32Resources); } @@ -825,7 +825,7 @@ protected void StrongNameSign(long snSigOffset) { snSigner.WriteSignature(TheOptions.StrongNameKey, snSigOffset); } - bool CanWritePdb() => !(pdbState is null); + bool CanWritePdb() => pdbState is not null; /// /// Creates the debug directory if a PDB file should be written @@ -942,7 +942,7 @@ protected uint GetTimeDateStamp() { } SymbolWriter GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbFilename) { - if (!(TheOptions.PdbStream is null)) { + if (TheOptions.PdbStream is not null) { return Pdb.Dss.SymbolReaderWriterFactory.Create(options, TheOptions.PdbStream, pdbFilename = TheOptions.PdbFileName ?? GetStreamName(TheOptions.PdbStream) ?? @@ -1045,14 +1045,14 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, timeDateStamp: codeViewTimestamp); - if (!(checksumBytes is null)) + if (checksumBytes is not null) AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm); if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0) AddReproduciblePdbDebugDirectoryEntry(); if (isEmbeddedPortablePdb) { - Debug.Assert(!(embeddedMemoryStream is null)); + Debug.Assert(embeddedMemoryStream is not null); debugDirectory.Add(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream), type: ImageDebugType.EmbeddedPortablePdb, majorVersion: PortablePdbConstants.FormatVersion, @@ -1061,7 +1061,7 @@ void WritePortablePdb(PdbState pdbState, bool isEmbeddedPortablePdb) { } } finally { - if (ownsStream && !(pdbStream is null)) + if (ownsStream && pdbStream is not null) pdbStream.Dispose(); } } @@ -1100,7 +1100,7 @@ static byte[] GetCodeViewData(Guid guid, uint age, string filename) { } Stream GetStandalonePortablePdbStream(out bool ownsStream) { - if (!(TheOptions.PdbStream is null)) { + if (TheOptions.PdbStream is not null) { ownsStream = false; return TheOptions.PdbStream; } diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index b0820b073..df61a815f 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -194,7 +194,7 @@ protected override long WriteImpl() { return Write(); } finally { - if (!(origSections is null)) { + if (origSections is not null) { foreach (var section in origSections) section.Dispose(); } @@ -247,7 +247,7 @@ void AddChunksToSections() { textSection.Add(netResources, DEFAULT_NETRESOURCES_ALIGNMENT); textSection.Add(metadata, DEFAULT_METADATA_ALIGNMENT); textSection.Add(debugDirectory, DebugDirectory.DEFAULT_DEBUGDIRECTORY_ALIGNMENT); - if (!(rsrcSection is null)) + if (rsrcSection is not null) rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); } @@ -263,7 +263,7 @@ protected override Win32Resources GetWin32Resources() { void CreatePESections() { sections = new List(); sections.Add(textSection = new PESection(".text", 0x60000020)); - if (!(GetWin32Resources() is null)) + if (GetWin32Resources() is not null) sections.Add(rsrcSection = new PESection(".rsrc", 0x40000040)); } @@ -392,7 +392,7 @@ long WriteFile() { ReuseIfPossible(textSection, metadata, mdDataDir.VirtualAddress, mdDataDir.Size, DEFAULT_METADATA_ALIGNMENT); var resourceDataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[2]; - if (!(win32Resources is null) && resourceDataDir.VirtualAddress != 0 && resourceDataDir.Size != 0) { + if (win32Resources is not null && resourceDataDir.VirtualAddress != 0 && resourceDataDir.Size != 0) { var win32ResourcesOffset = peImage.ToFileOffset(resourceDataDir.VirtualAddress); if (win32Resources.CheckValidOffset(win32ResourcesOffset)) { win32Resources.SetOffset(win32ResourcesOffset, resourceDataDir.VirtualAddress); @@ -418,7 +418,7 @@ long WriteFile() { textSection.Remove(netResources); if (textSection.IsEmpty) sections.Remove(textSection); - if (!(rsrcSection is null) && rsrcSection.IsEmpty) { + if (rsrcSection is not null && rsrcSection.IsEmpty) { sections.Remove(rsrcSection); rsrcSection = null; } @@ -426,7 +426,7 @@ long WriteFile() { var headerSection = CreateHeaderSection(out var extraHeaderData); var chunks = new List(); uint headerLen; - if (!(extraHeaderData is null)) { + if (extraHeaderData is not null) { var list = new ChunkList(); list.Add(headerSection, 1); list.Add(extraHeaderData, 1); @@ -441,7 +441,7 @@ long WriteFile() { chunks.Add(origSection.Chunk); foreach (var section in sections) chunks.Add(section); - if (!(extraData is null)) + if (extraData is not null) chunks.Add(extraData); CalculateRvasAndFileOffsets(chunks, 0, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); @@ -480,7 +480,7 @@ long WriteFile() { OnWriterEvent(ModuleWriterEvent.EndWriteChunks); OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); - if (!(Options.StrongNameKey is null)) + if (Options.StrongNameKey is not null) StrongNameSign((long)strongNameSignature.FileOffset); OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); @@ -626,7 +626,7 @@ void UpdateHeaderFields(DataWriter writer, bool entryPointIsManagedOrNoEntryPoin } // Update Win32 resources data directory, if we wrote a new one - if (!(win32Resources is null)) { + if (win32Resources is not null) { writer.Position = dataDirOffset + 2 * 8; writer.WriteDataDirectory(win32Resources); } @@ -727,7 +727,7 @@ static void WriteUInt64(DataWriter writer, ulong? value) { ComImageFlags GetComImageFlags(bool isManagedEntryPoint) { var flags = Options.Cor20HeaderOptions.Flags ?? module.Cor20HeaderFlags; - if (!(Options.Cor20HeaderOptions.EntryPoint is null)) + if (Options.Cor20HeaderOptions.EntryPoint is not null) return flags; if (isManagedEntryPoint) return flags & ~ComImageFlags.NativeEntryPoint; @@ -824,7 +824,7 @@ uint GetMethodToken(IMethod method) { /// false if it's a native entry point bool GetEntryPoint(out uint ep) { var tok = Options.Cor20HeaderOptions.EntryPoint; - if (!(tok is null)) { + if (tok is not null) { ep = tok.Value; return ep == 0 || ((Options.Cor20HeaderOptions.Flags ?? 0) & ComImageFlags.NativeEntryPoint) == 0; } diff --git a/src/DotNet/Writer/PreserveTokensMetadata.cs b/src/DotNet/Writer/PreserveTokensMetadata.cs index 42d5611c8..db4a71dc7 100644 --- a/src/DotNet/Writer/PreserveTokensMetadata.cs +++ b/src/DotNet/Writer/PreserveTokensMetadata.cs @@ -990,7 +990,7 @@ void InitializeParamList() { var row = tablesHeap.MethodTable[methodRid]; row = new RawMethodRow(row.RVA, row.ImplFlags, row.Flags, row.Name, row.Signature, ridList); tablesHeap.MethodTable[methodRid] = row; - if (!(methodInfo is null)) + if (methodInfo is not null) ridList += (uint)methodInfo.Def.ParamDefs.Count; } } diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index a2f8e1bf1..ab3c332b1 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -50,7 +50,7 @@ public void SetOffset(FileOffset offset, RVA rva) { var allRvas = new List(allRelocRvas.Count); foreach (var info in allRelocRvas) { uint relocRva; - if (!(info.Chunk is null)) + if (info.Chunk is not null) relocRva = (uint)info.Chunk.RVA + info.OffsetOrRva; else relocRva = info.OffsetOrRva; @@ -64,14 +64,14 @@ public void SetOffset(FileOffset offset, RVA rva) { uint page = relocRva & ~0xFFFU; if (page != prevPage) { prevPage = page; - if (!(pageList is null)) + if (pageList is not null) totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); pageList = new List(); relocSections.Add(pageList); } pageList.Add(relocRva); } - if (!(pageList is null)) + if (pageList is not null) totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); } diff --git a/src/DotNet/Writer/SerializerMethodContext.cs b/src/DotNet/Writer/SerializerMethodContext.cs index b1ebbb10a..42671ec14 100644 --- a/src/DotNet/Writer/SerializerMethodContext.cs +++ b/src/DotNet/Writer/SerializerMethodContext.cs @@ -13,7 +13,7 @@ sealed class SerializerMethodContext { uint bodySize; bool dictInitd; - public bool HasBody => !(body is null); + public bool HasBody => body is not null; public SerializerMethodContext(IWriterError helper) { toOffset = new Dictionary(); @@ -31,7 +31,7 @@ internal void SetBody(MethodDef method) { public uint GetOffset(Instruction instr) { if (!dictInitd) { - Debug.Assert(!(body is null)); + Debug.Assert(body is not null); if (body is null) return 0; InitializeDict(); @@ -47,7 +47,7 @@ public uint GetOffset(Instruction instr) { public bool IsSameMethod(MethodDef method) => this.method == method; void InitializeDict() { - Debug.Assert(!(body is null)); + Debug.Assert(body is not null); Debug.Assert(toOffset.Count == 0); uint offset = 0; var instrs = body.Instructions; diff --git a/src/DotNet/Writer/SignatureWriter.cs b/src/DotNet/Writer/SignatureWriter.cs index f74531cc2..b0454616d 100644 --- a/src/DotNet/Writer/SignatureWriter.cs +++ b/src/DotNet/Writer/SignatureWriter.cs @@ -234,13 +234,13 @@ void Write(CallingConventionSig sig) { LocalSig ls; GenericInstMethodSig gim; - if (!((mbs = sig as MethodBaseSig) is null)) + if ((mbs = sig as MethodBaseSig) is not null) Write(mbs); - else if (!((fs = sig as FieldSig) is null)) + else if ((fs = sig as FieldSig) is not null) Write(fs); - else if (!((ls = sig as LocalSig) is null)) + else if ((ls = sig as LocalSig) is not null) Write(ls); - else if (!((gim = sig as GenericInstMethodSig) is null)) + else if ((gim = sig as GenericInstMethodSig) is not null) Write(gim); else { helper.Error("Unknown calling convention sig"); @@ -265,7 +265,7 @@ void Write(MethodBaseSig sig) { WriteCompressedUInt32(sig.GenParamCount); uint numParams = (uint)sig.Params.Count; - if (!(sig.ParamsAfterSentinel is null)) + if (sig.ParamsAfterSentinel is not null) numParams += (uint)sig.ParamsAfterSentinel.Count; uint count = WriteCompressedUInt32(numParams); @@ -273,7 +273,7 @@ void Write(MethodBaseSig sig) { for (uint i = 0; i < count && i < (uint)sig.Params.Count; i++) Write(sig.Params[(int)i]); - if (!(sig.ParamsAfterSentinel is null) && sig.ParamsAfterSentinel.Count > 0) { + if (sig.ParamsAfterSentinel is not null && sig.ParamsAfterSentinel.Count > 0) { writer.WriteByte((byte)ElementType.Sentinel); for (uint i = 0, j = (uint)sig.Params.Count; i < (uint)sig.ParamsAfterSentinel.Count && j < count; i++, j++) Write(sig.ParamsAfterSentinel[(int)i]); @@ -342,7 +342,7 @@ void Write(GenericInstMethodSig sig) { public void Dispose() { if (!disposeStream) return; - if (!(outStream is null)) + if (outStream is not null) outStream.Dispose(); } } diff --git a/src/DotNet/Writer/StringsHeap.cs b/src/DotNet/Writer/StringsHeap.cs index b27bd78d2..5f6c7be47 100644 --- a/src/DotNet/Writer/StringsHeap.cs +++ b/src/DotNet/Writer/StringsHeap.cs @@ -45,7 +45,7 @@ public StringsOffsetInfo(UTF8String value, uint stringsId) { public void Populate(StringsStream stringsStream) { if (isReadOnly) throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); - if (!(originalData is null)) + if (originalData is not null) throw new InvalidOperationException("Can't call method twice"); if (nextOffset != 1) throw new InvalidOperationException("Add() has already been called"); @@ -85,7 +85,7 @@ internal void AddOptimizedStringsAndSetReadOnly() { StringsOffsetInfo prevInfo = null; foreach (var info in stringsOffsetInfos) { - if (!(prevInfo is null) && EndsWith(prevInfo.Value, info.Value)) + if (prevInfo is not null && EndsWith(prevInfo.Value, info.Value)) info.StringsOffset = prevInfo.StringsOffset + (uint)(prevInfo.Value.Data.Length - info.Value.Data.Length); else info.StringsOffset = AddToCache(info.Value); @@ -199,14 +199,14 @@ uint AddToCache(UTF8String s) { /// protected override void WriteToImpl(DataWriter writer) { - if (!(originalData is null)) + if (originalData is not null) writer.WriteBytes(originalData); else writer.WriteByte(0); - uint offset = !(originalData is null) ? (uint)originalData.Length : 1; + uint offset = originalData is not null ? (uint)originalData.Length : 1; foreach (var s in cached) { - if (!(userRawData is null) && userRawData.TryGetValue(offset, out var rawData)) { + if (userRawData is not null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != s.Data.Length + 1) throw new InvalidOperationException("Invalid length of raw data"); writer.WriteBytes(rawData); @@ -231,7 +231,7 @@ public void SetRawData(uint offset, byte[] rawData) { /// public IEnumerable> GetAllRawData() { - uint offset = !(originalData is null) ? (uint)originalData.Length : 1; + uint offset = originalData is not null ? (uint)originalData.Length : 1; foreach (var s in cached) { var rawData = new byte[s.Data.Length + 1]; Array.Copy(s.Data, rawData, s.Data.Length); diff --git a/src/DotNet/Writer/USHeap.cs b/src/DotNet/Writer/USHeap.cs index f6b7f0a6e..31e8636ed 100644 --- a/src/DotNet/Writer/USHeap.cs +++ b/src/DotNet/Writer/USHeap.cs @@ -26,7 +26,7 @@ public sealed class USHeap : HeapBase, IOffsetHeap { /// /// The #US stream with the original content public void Populate(USStream usStream) { - if (!(originalData is null)) + if (originalData is not null) throw new InvalidOperationException("Can't call method twice"); if (nextOffset != 1) throw new InvalidOperationException("Add() has already been called"); @@ -103,15 +103,15 @@ uint AddToCache(string s) { /// protected override void WriteToImpl(DataWriter writer) { - if (!(originalData is null)) + if (originalData is not null) writer.WriteBytes(originalData); else writer.WriteByte(0); - uint offset = !(originalData is null) ? (uint)originalData.Length : 1; + uint offset = originalData is not null ? (uint)originalData.Length : 1; foreach (var s in cached) { int rawLen = GetRawDataSize(s); - if (!(userRawData is null) && userRawData.TryGetValue(offset, out var rawData)) { + if (userRawData is not null && userRawData.TryGetValue(offset, out var rawData)) { if (rawData.Length != rawLen) throw new InvalidOperationException("Invalid length of raw data"); writer.WriteBytes(rawData); @@ -148,7 +148,7 @@ public void SetRawData(uint offset, byte[] rawData) { public IEnumerable> GetAllRawData() { var memStream = new MemoryStream(); var writer = new DataWriter(memStream); - uint offset = !(originalData is null) ? (uint)originalData.Length : 1; + uint offset = originalData is not null ? (uint)originalData.Length : 1; foreach (var s in cached) { memStream.Position = 0; memStream.SetLength(0); diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 92d97179c..3898d9cd3 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -277,7 +277,7 @@ public void SetOffset(FileOffset offset, RVA rva) { uint rsrcOffset = 0; var maxAlignment = GetMaxAlignment(offset, out var error); - if (!(error is null)) + if (error is not null) throw new ModuleWriterException(error); foreach (var dir in dirList) { diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index c6f0bd99a..33a99b7fe 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -86,7 +86,7 @@ public uint Position { /// Start offset of data /// Length of data public DataReader(DataStream stream, uint offset, uint length) { - Debug.Assert(!(stream is null) || (offset == 0 && length == 0)); + Debug.Assert(stream is not null || (offset == 0 && length == 0)); Debug.Assert(offset + length >= offset); this.stream = stream; startOffset = offset; diff --git a/src/IO/DataReaderFactoryFactory.cs b/src/IO/DataReaderFactoryFactory.cs index 134dfb5db..f8ad7e618 100644 --- a/src/IO/DataReaderFactoryFactory.cs +++ b/src/IO/DataReaderFactoryFactory.cs @@ -16,7 +16,7 @@ static DataReaderFactoryFactory() { public static DataReaderFactory Create(string fileName, bool mapAsImage) { var creator = CreateDataReaderFactory(fileName, mapAsImage); - if (!(creator is null)) + if (creator is not null) return creator; return ByteArrayDataReaderFactory.Create(File.ReadAllBytes(fileName), fileName); diff --git a/src/IO/MemoryMappedDataReaderFactory.cs b/src/IO/MemoryMappedDataReaderFactory.cs index a510f7c65..dc1a64f64 100644 --- a/src/IO/MemoryMappedDataReaderFactory.cs +++ b/src/IO/MemoryMappedDataReaderFactory.cs @@ -279,7 +279,7 @@ void Dispose(bool disposing) { /// trying to access the memory since that could lead to an exception. /// internal void UnsafeDisableMemoryMappedIO() { - if (!(dataAry is null)) + if (dataAry is not null) return; var newAry = new byte[length]; Marshal.Copy(data, newAry, 0, newAry.Length); diff --git a/src/PE/PEImage.cs b/src/PE/PEImage.cs index 3a4048788..023f7ac8d 100644 --- a/src/PE/PEImage.cs +++ b/src/PE/PEImage.cs @@ -97,7 +97,7 @@ public Win32Resources Win32Resources { } win32Resources.Value = value; - if (!(origValue is null)) + if (origValue is not null) origValue.Dispose(); } } @@ -306,7 +306,7 @@ public PEImage(IntPtr baseAddr) /// public void Dispose() { IDisposable id; - if (win32Resources.IsValueInitialized && !((id = win32Resources.Value) is null)) + if (win32Resources.IsValueInitialized && (id = win32Resources.Value) is not null) id.Dispose(); dataReaderFactory?.Dispose(); win32Resources.Value = null; diff --git a/src/PE/PEInfo.cs b/src/PE/PEInfo.cs index afbd5c995..db1760406 100644 --- a/src/PE/PEInfo.cs +++ b/src/PE/PEInfo.cs @@ -91,7 +91,7 @@ public ImageSectionHeader ToImageSectionHeader(RVA rva) { /// The RVA public RVA ToRVA(FileOffset offset) { var section = ToImageSectionHeader(offset); - if (!(section is null)) + if (section is not null) return (uint)(offset - section.PointerToRawData) + section.VirtualAddress; return (RVA)offset; } @@ -103,7 +103,7 @@ public RVA ToRVA(FileOffset offset) { /// The file offset public FileOffset ToFileOffset(RVA rva) { var section = ToImageSectionHeader(rva); - if (!(section is null)) + if (section is not null) return (FileOffset)(rva - section.VirtualAddress + section.PointerToRawData); return (FileOffset)rva; } diff --git a/src/Utils/LazyList.cs b/src/Utils/LazyList.cs index a915c53ea..31a4d1036 100644 --- a/src/Utils/LazyList.cs +++ b/src/Utils/LazyList.cs @@ -157,7 +157,7 @@ public TValue this[int index] { internal TValue Get_NoLock(int index) => list[index].GetValue_NoLock(index); void Set_NoLock(int index, TValue value) { - if (!(listener is null)) { + if (listener is not null) { listener.OnRemove(index, list[index].GetValue_NoLock(index)); listener.OnAdd(index, value); } @@ -217,10 +217,10 @@ public void Insert(int index, TValue item) { } void Insert_NoLock(int index, TValue item) { - if (!(listener is null)) + if (listener is not null) listener.OnAdd(index, item); list.Insert(index, new Element(item)); - if (!(listener is null)) + if (listener is not null) listener.OnResize(index); id++; } @@ -237,10 +237,10 @@ public void RemoveAt(int index) { } void RemoveAt_NoLock(int index) { - if (!(listener is null)) + if (listener is not null) listener.OnRemove(index, list[index].GetValue_NoLock(index)); list.RemoveAt(index); - if (!(listener is null)) + if (listener is not null) listener.OnResize(index); id++; } @@ -258,10 +258,10 @@ public void Add(TValue item) { void Add_NoLock(TValue item) { int index = list.Count; - if (!(listener is null)) + if (listener is not null) listener.OnAdd(index, item); list.Add(new Element(item)); - if (!(listener is null)) + if (listener is not null) listener.OnResize(index); id++; } @@ -278,10 +278,10 @@ public void Clear() { } void Clear_NoLock() { - if (!(listener is null)) + if (listener is not null) listener.OnClear(); list.Clear(); - if (!(listener is null)) + if (listener is not null) listener.OnResize(0); id++; } @@ -448,7 +448,7 @@ sealed class LazyElement : Element { /// public override TValue GetValue_NoLock(int index) { - if (!(lazyList is null)) { + if (lazyList is not null) { value = lazyList.ReadOriginalValue_NoLock(index, origIndex); lazyList = null; } @@ -473,7 +473,7 @@ public LazyElement(int origIndex, LazyList lazyList) { /// public override string ToString() { - if (!(lazyList is null)) { + if (lazyList is not null) { value = lazyList.ReadOriginalValue_NoLock(this); lazyList = null; } diff --git a/src/W32Resources/ResourceName.cs b/src/W32Resources/ResourceName.cs index 4ca8c4533..d5f36dddf 100644 --- a/src/W32Resources/ResourceName.cs +++ b/src/W32Resources/ResourceName.cs @@ -18,7 +18,7 @@ namespace dnlib.W32Resources { /// /// true if is valid /// - public bool HasName => !(name is null); + public bool HasName => name is not null; /// /// The ID. It's only valid if is true diff --git a/src/W32Resources/Win32Resources.cs b/src/W32Resources/Win32Resources.cs index 89fd7cf4a..d02f8a437 100644 --- a/src/W32Resources/Win32Resources.cs +++ b/src/W32Resources/Win32Resources.cs @@ -189,7 +189,7 @@ public Win32ResourcesPE(IPEImage peImage, DataReaderFactory rsrcReader_factory, dataReader_factory = peImage.DataReaderFactory; dataReader_offset = 0; dataReader_length = dataReader_factory.Length; - if (!(rsrcReader_factory is null)) { + if (rsrcReader_factory is not null) { this.rsrcReader_factory = rsrcReader_factory; this.rsrcReader_offset = rsrcReader_offset; this.rsrcReader_length = rsrcReader_length; From 1b7087fe89191b3c25ae87f3b8090aaa2ecc5c8d Mon Sep 17 00:00:00 2001 From: wtfsck Date: Wed, 23 Jun 2021 12:25:57 +0200 Subject: [PATCH 397/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 7f2c17d0b..7b4bda17d 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.3.2 + 3.3.3 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 634db70a06aeb152bc06c46b07561350699b0c85 Mon Sep 17 00:00:00 2001 From: Markus Szumovski Date: Thu, 22 Jul 2021 21:57:23 +0200 Subject: [PATCH 398/511] ResolutionScope now actually can be null/0 in .NET 5 reference assemblies (#415) * Found out that ResolutionScope now actually can be null in .NET 5 reference assemblies, so just return 0 instead of throwing an error * Removed unnecessary comment from fix --- src/DotNet/Writer/Metadata.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 541d60626..eacb25b41 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2325,7 +2325,6 @@ protected uint AddTypeDefOrRef(ITypeDefOrRef tdr) { /// Its encoded token protected uint AddResolutionScope(IResolutionScope rs) { if (rs is null) { - Error("ResolutionScope is null"); return 0; } From 1787cd5529bc5a0635659c580390bf1cd3f65c0f Mon Sep 17 00:00:00 2001 From: ElektroKill <37494960+ElektroKill@users.noreply.github.com> Date: Fri, 30 Jul 2021 10:58:34 +0000 Subject: [PATCH 399/511] Preserve Log2Rid value when rewriting a module. (#416) * Preserve Log2Rid value when rewriting a module. Also allows for the user to specify the value. * Address feedback --- src/DotNet/Writer/ModuleWriterBase.cs | 9 +++++---- src/DotNet/Writer/TablesHeap.cs | 8 +++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 89af5c372..6096871ee 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -113,28 +113,28 @@ public enum PdbWriterOptions { /// Don't use Microsoft.DiaSymReader.Native. This is a NuGet package with an updated Windows PDB reader/writer implementation, /// and if it's available at runtime, dnlib will try to use it. If this option is set, dnlib won't use it. /// You have to add a reference to the NuGet package if you want to use it, dnlib has no reference to the NuGet package. - /// + /// /// This is only used if it's a Windows PDB file. /// NoDiaSymReader = 0x00000001, /// /// Don't use diasymreader.dll's PDB writer that is shipped with .NET Framework. - /// + /// /// This is only used if it's a Windows PDB file. /// NoOldDiaSymReader = 0x00000002, /// /// Create a deterministic PDB file and add a debug directory entry to the PE file. - /// + /// /// It's ignored if the PDB writer doesn't support it. /// Deterministic = 0x00000004, /// /// Hash the PDB file and add a PDB checksum debug directory entry to the PE file. - /// + /// /// It's ignored if the PDB writer doesn't support it. /// PdbChecksum = 0x00000008, @@ -424,6 +424,7 @@ protected ModuleWriterOptionsBase(ModuleDef module) { PdbOptions |= PdbWriterOptions.PdbChecksum; if (TryGetPdbChecksumAlgorithm(modDefMD.Metadata.PEImage, modDefMD.Metadata.PEImage.ImageDebugDirectories, out var pdbChecksumAlgorithm)) PdbChecksumAlgorithm = pdbChecksumAlgorithm; + MetadataOptions.TablesHeapOptions.Log2Rid = modDefMD.TablesStream.Log2Rid; } if (Is64Bit) { diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 7b8363ee2..727977f8e 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -39,6 +39,11 @@ public sealed class TablesHeapOptions { /// public uint? ExtraData; + /// + /// Log2Rid to write + /// + public byte? Log2Rid; + /// /// true if there are deleted s, s, /// s, s, s and/or @@ -57,6 +62,7 @@ public static TablesHeapOptions CreatePortablePdbV1_0() => MinorVersion = 0, UseENC = null, ExtraData = null, + Log2Rid = null, HasDeletedRows = null, }; } @@ -469,7 +475,7 @@ MDStreamFlags GetMDStreamFlags() { byte GetLog2Rid() { //TODO: Sometimes this is 16. Probably when at least one of the table indexes requires 4 bytes. - return 1; + return options.Log2Rid ?? 1; } ulong GetValidMask() { From cfcdf54693016a3a6dd1d7bb74563eeb7f9fec8c Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 30 Jul 2021 19:56:13 +0200 Subject: [PATCH 400/511] Improve CAArgument analysis in MemberFinder --- src/DotNet/MemberFinder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index 89564d731..5e301a24f 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -272,6 +272,10 @@ void Add(IEnumerable args) { void Add(CAArgument arg) { // It's a struct so can't be null Add(arg.Type); + if (arg.Value is TypeSig typeSig) + Add(typeSig); + else if (arg.Value is IList args) + Add(args); } void Add(IEnumerable args) { From 75dc4d21e384fc59ffeb4d382a1b332adbc300d8 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 2 Aug 2021 21:35:19 +0200 Subject: [PATCH 401/511] Add writing support for CAs and CDIs on manifest resources Reading is yet to be implemented --- src/DotNet/Resource.cs | 49 ++++++++++++++++++++++++++++++++++- src/DotNet/Writer/Metadata.cs | 12 ++++----- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Resource.cs b/src/DotNet/Resource.cs index 4f48033b9..f8eaa935d 100644 --- a/src/DotNet/Resource.cs +++ b/src/DotNet/Resource.cs @@ -1,8 +1,11 @@ // dnlib: See LICENSE.txt for more info using System; +using System.Collections.Generic; +using System.Threading; using dnlib.IO; using dnlib.DotNet.MD; +using dnlib.DotNet.Pdb; namespace dnlib.DotNet { /// @@ -28,7 +31,7 @@ public enum ResourceType { /// /// Resource base class /// - public abstract class Resource : IMDTokenProvider { + public abstract class Resource : IMDTokenProvider, IHasCustomAttribute, IHasCustomDebugInformation { uint rid; uint? offset; UTF8String name; @@ -90,6 +93,50 @@ public ManifestResourceAttributes Visibility { /// public bool IsPrivate => (flags & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private; + /// + public int HasCustomAttributeTag => 18; + + /// + /// Gets all custom attributes + /// + public CustomAttributeCollection CustomAttributes { + get { + if (customAttributes is null) + InitializeCustomAttributes(); + return customAttributes; + } + } + /// + protected CustomAttributeCollection customAttributes; + /// Initializes + protected virtual void InitializeCustomAttributes() => + Interlocked.CompareExchange(ref customAttributes, new CustomAttributeCollection(), null); + + /// + public bool HasCustomAttributes => CustomAttributes.Count > 0; + + /// + public int HasCustomDebugInformationTag => 18; + + /// + /// Gets all custom debug infos + /// + public IList CustomDebugInfos { + get { + if (customDebugInfos is null) + InitializeCustomDebugInfos(); + return customDebugInfos; + } + } + /// + protected IList customDebugInfos; + /// Initializes + protected virtual void InitializeCustomDebugInfos() => + Interlocked.CompareExchange(ref customDebugInfos, new List(), null); + + /// + public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; + /// /// Constructor /// diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index eacb25b41..f6d4ca802 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2980,8 +2980,8 @@ uint AddEmbeddedResource(EmbeddedResource er) { rid = tablesHeap.ManifestResourceTable.Add(row); manifestResourceInfos.Add(er, rid); embeddedResourceToByteArray[er] = netResources.Add(er.CreateReader()); - //TODO: Add custom attributes - //TODO: Add custom debug infos + AddCustomAttributes(Table.ManifestResource, rid, er); + AddCustomDebugInformationList(Table.ManifestResource, rid, er); return rid; } @@ -2999,8 +2999,8 @@ uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { AddImplementation(alr.Assembly)); rid = tablesHeap.ManifestResourceTable.Add(row); manifestResourceInfos.Add(alr, rid); - //TODO: Add custom attributes - //TODO: Add custom debug infos + AddCustomAttributes(Table.ManifestResource, rid, alr); + AddCustomDebugInformationList(Table.ManifestResource, rid, alr); return rid; } @@ -3018,8 +3018,8 @@ uint AddLinkedResource(LinkedResource lr) { AddImplementation(lr.File)); rid = tablesHeap.ManifestResourceTable.Add(row); manifestResourceInfos.Add(lr, rid); - //TODO: Add custom attributes - //TODO: Add custom debug infos + AddCustomAttributes(Table.ManifestResource, rid, lr); + AddCustomDebugInformationList(Table.ManifestResource, rid, lr); return rid; } From 9bb0af3d0d9f86f299ce58bae5ddff09d4a941a9 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 3 Aug 2021 14:22:30 +0200 Subject: [PATCH 402/511] Add Resource.CustomAttributes to ModuleLoader --- src/DotNet/ModuleLoader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DotNet/ModuleLoader.cs b/src/DotNet/ModuleLoader.cs index f723d9b20..16ba05561 100644 --- a/src/DotNet/ModuleLoader.cs +++ b/src/DotNet/ModuleLoader.cs @@ -542,6 +542,7 @@ void Load(Resource obj) { Add(obj.Offset); Add(obj.Name); Add(obj.Attributes); + Add(obj.CustomAttributes); switch (obj.ResourceType) { case ResourceType.Embedded: From cd6e42be7e535ea38c2b7e89bf8c13ee02ac1fac Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 3 Aug 2021 20:04:44 +0200 Subject: [PATCH 403/511] Added support for reading CAs and CDIs on resources --- src/DotNet/ModuleDefMD.cs | 10 ++-- src/DotNet/Resource.cs | 105 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 10 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 99c194cf9..2918b4b8b 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1478,17 +1478,17 @@ Resource CreateResource(uint rid) { if (token.Rid == 0) { if (TryCreateResourceStream(mr.Offset, out var dataReaderFactory, out uint resourceOffset, out uint resourceLength)) - return new EmbeddedResource(mr.Name, dataReaderFactory, resourceOffset, resourceLength, mr.Flags) { Rid = rid, Offset = mr.Offset }; - return new EmbeddedResource(mr.Name, Array2.Empty(), mr.Flags) { Rid = rid, Offset = mr.Offset }; + return new EmbeddedResourceMD(this, mr, dataReaderFactory, resourceOffset, resourceLength); + return new EmbeddedResourceMD(this, mr, Array2.Empty()); } if (mr.Implementation is FileDef file) - return new LinkedResource(mr.Name, file, mr.Flags) { Rid = rid, Offset = mr.Offset }; + return new LinkedResourceMD(this, mr, file); if (mr.Implementation is AssemblyRef asmRef) - return new AssemblyLinkedResource(mr.Name, asmRef, mr.Flags) { Rid = rid, Offset = mr.Offset }; + return new AssemblyLinkedResourceMD(this, mr, asmRef); - return new EmbeddedResource(mr.Name, Array2.Empty(), mr.Flags) { Rid = rid, Offset = mr.Offset }; + return new EmbeddedResourceMD(this, mr, Array2.Empty()); } [HandleProcessCorruptedStateExceptions, SecurityCritical] // Req'd on .NET 4.0 diff --git a/src/DotNet/Resource.cs b/src/DotNet/Resource.cs index f8eaa935d..58bb2e11a 100644 --- a/src/DotNet/Resource.cs +++ b/src/DotNet/Resource.cs @@ -32,8 +32,8 @@ public enum ResourceType { /// Resource base class /// public abstract class Resource : IMDTokenProvider, IHasCustomAttribute, IHasCustomDebugInformation { - uint rid; - uint? offset; + private protected uint rid; + private protected uint? offset; UTF8String name; ManifestResourceAttributes flags; @@ -151,7 +151,7 @@ protected Resource(UTF8String name, ManifestResourceAttributes flags) { /// /// A resource that is embedded in a .NET module. This is the most common type of resource. /// - public sealed class EmbeddedResource : Resource { + public class EmbeddedResource : Resource { readonly DataReaderFactory dataReaderFactory; readonly uint resourceStartOffset; readonly uint resourceLength; @@ -199,10 +199,45 @@ public EmbeddedResource(UTF8String name, DataReaderFactory dataReaderFactory, ui public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - size: {(resourceLength)}"; } + sealed class EmbeddedResourceMD : EmbeddedResource, IMDTokenProviderMD { + /// The module where this instance is located + readonly ModuleDefMD readerModule; + + readonly uint origRid; + + /// + public uint OrigRid => origRid; + + /// + protected override void InitializeCustomAttributes() { + var list = readerModule.Metadata.GetCustomAttributeRidList(Table.ManifestResource, origRid); + var tmp = new CustomAttributeCollection(list.Count, list, (list2, index) => readerModule.ReadCustomAttribute(list[index])); + Interlocked.CompareExchange(ref customAttributes, tmp, null); + } + + /// + protected override void InitializeCustomDebugInfos() { + var list = new List(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + + public EmbeddedResourceMD(ModuleDefMD readerModule, ManifestResource mr, byte[] data) + : this(readerModule, mr, ByteArrayDataReaderFactory.Create(data, filename: null), 0, (uint)data.Length) { + } + + public EmbeddedResourceMD(ModuleDefMD readerModule, ManifestResource mr, DataReaderFactory dataReaderFactory, uint offset, uint length) + : base(mr.Name, dataReaderFactory, offset, length, mr.Flags) { + this.readerModule = readerModule; + origRid = rid = mr.Rid; + this.offset = mr.Offset; + } + } + /// /// A reference to a resource in another assembly /// - public sealed class AssemblyLinkedResource : Resource { + public class AssemblyLinkedResource : Resource { AssemblyRef asmRef; /// @@ -229,10 +264,40 @@ public AssemblyLinkedResource(UTF8String name, AssemblyRef asmRef, ManifestResou public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - assembly: {asmRef.FullName}"; } + sealed class AssemblyLinkedResourceMD : AssemblyLinkedResource, IMDTokenProviderMD { + /// The module where this instance is located + readonly ModuleDefMD readerModule; + + readonly uint origRid; + + /// + public uint OrigRid => origRid; + + /// + protected override void InitializeCustomAttributes() { + var list = readerModule.Metadata.GetCustomAttributeRidList(Table.ManifestResource, origRid); + var tmp = new CustomAttributeCollection(list.Count, list, (list2, index) => readerModule.ReadCustomAttribute(list[index])); + Interlocked.CompareExchange(ref customAttributes, tmp, null); + } + + /// + protected override void InitializeCustomDebugInfos() { + var list = new List(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + + public AssemblyLinkedResourceMD(ModuleDefMD readerModule, ManifestResource mr, AssemblyRef asmRef) : base(mr.Name, asmRef, mr.Flags) { + this.readerModule = readerModule; + origRid = rid = mr.Rid; + offset = mr.Offset; + } + } + /// /// A resource that is stored in a file on disk /// - public sealed class LinkedResource : Resource { + public class LinkedResource : Resource { FileDef file; /// @@ -271,4 +336,34 @@ public LinkedResource(UTF8String name, FileDef file, ManifestResourceAttributes /// public override string ToString() => $"{UTF8String.ToSystemStringOrEmpty(Name)} - file: {UTF8String.ToSystemStringOrEmpty(FileName)}"; } + + sealed class LinkedResourceMD : LinkedResource, IMDTokenProviderMD { + /// The module where this instance is located + readonly ModuleDefMD readerModule; + + readonly uint origRid; + + /// + public uint OrigRid => origRid; + + /// + protected override void InitializeCustomAttributes() { + var list = readerModule.Metadata.GetCustomAttributeRidList(Table.ManifestResource, origRid); + var tmp = new CustomAttributeCollection(list.Count, list, (list2, index) => readerModule.ReadCustomAttribute(list[index])); + Interlocked.CompareExchange(ref customAttributes, tmp, null); + } + + /// + protected override void InitializeCustomDebugInfos() { + var list = new List(); + readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), new GenericParamContext(), list); + Interlocked.CompareExchange(ref customDebugInfos, list, null); + } + + public LinkedResourceMD(ModuleDefMD readerModule, ManifestResource mr, FileDef file) : base(mr.Name, file, mr.Flags) { + this.readerModule = readerModule; + origRid = rid = mr.Rid; + offset = mr.Offset; + } + } } From 9814e5e7ffc6f374b2b1f7f7bc846339b6e0edf0 Mon Sep 17 00:00:00 2001 From: ElektroKill <37494960+ElektroKill@users.noreply.github.com> Date: Fri, 6 Aug 2021 14:18:03 +0000 Subject: [PATCH 404/511] Add support for reading V1 resources (#419) * Add support for reading V1 resources * Remove duplicated code * Fix bugs discovered when the code was tested. The test was performed by loading `Microsoft.VisualBasic.Compatibility.dll` extracted from the installation media of VS.NET 2002, reading the resources, writing them, and verifying they are ok. The Regex for checking the resource reader class had to be updated as for some unknown to me reason the version was not included in the name. The code for comparing the type names also had to be updated to seperate the type name from teh assembly name and version. * Address feedback --- src/DotNet/Resources/ResourceReader.cs | 63 +++++++++++++++++++++----- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index f3eb329da..979e43a8d 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -98,7 +98,7 @@ ResourceElementSet Read() { if (!CheckReaders()) throw new ResourceReaderException("Invalid resource reader"); int version = reader.ReadInt32(); - if (version != 2)//TODO: Support version 1 + if (version != 2 && version != 1) throw new ResourceReaderException($"Invalid resource version: {version}"); int numResources = reader.ReadInt32(); if (numResources < 0) @@ -141,7 +141,8 @@ ResourceElementSet Read() { reader.Position = (uint)info.offset; long nextDataOffset = i == infos.Count - 1 ? end : infos[i + 1].offset; int size = (int)(nextDataOffset - info.offset); - element.ResourceData = ReadResourceData(userTypes, size); + element.ResourceData = + version == 1 ? ReadResourceDataV1(userTypes, size) : ReadResourceDataV2(userTypes, size); element.ResourceData.StartOffset = baseFileOffset + (FileOffset)info.offset; element.ResourceData.EndOffset = baseFileOffset + (FileOffset)reader.Position; @@ -161,7 +162,7 @@ public ResourceInfo(string name, long offset) { public override string ToString() => $"{offset:X8} - {name}"; } - IResourceData ReadResourceData(List userTypes, int size) { + IResourceData ReadResourceDataV2(List userTypes, int size) { uint endPos = reader.Position + (uint)size; uint code = ReadUInt32(ref reader); switch ((ResourceTypeCode)code) { @@ -188,14 +189,52 @@ IResourceData ReadResourceData(List userTypes, int size) { int userTypeIndex = (int)(code - (uint)ResourceTypeCode.UserTypes); if (userTypeIndex < 0 || userTypeIndex >= userTypes.Count) throw new ResourceReaderException($"Invalid resource data code: {code}"); - var userType = userTypes[userTypeIndex]; - var serializedData = reader.ReadBytes((int)(endPos - reader.Position)); - if (createResourceDataDelegate is not null) { - var res = createResourceDataDelegate(resourceDataFactory, userType, serializedData); - if (res is not null) - return res; - } - return resourceDataFactory.CreateSerialized(serializedData, userType); + return ReadSerializedObject(endPos, userTypes[userTypeIndex]); + } + } + + IResourceData ReadResourceDataV1(List userTypes, int size) { + uint endPos = reader.Position + (uint)size; + int typeIndex = ReadInt32(ref reader); + if (typeIndex == -1) + return resourceDataFactory.CreateNull(); + if (typeIndex < 0 || typeIndex >= userTypes.Count) + throw new ResourceReaderException($"Invalid resource type index: {typeIndex}"); + var type = userTypes[typeIndex]; + var commaIndex = type.Name.IndexOf(','); + string actualName = commaIndex == -1 ? type.Name : type.Name.Remove(commaIndex); + switch (actualName) { + case "System.String": return resourceDataFactory.Create(reader.ReadSerializedString()); + case "System.Int32": return resourceDataFactory.Create(reader.ReadInt32()); + case "System.Byte": return resourceDataFactory.Create(reader.ReadByte()); + case "System.SByte": return resourceDataFactory.Create(reader.ReadSByte()); + case "System.Int16": return resourceDataFactory.Create(reader.ReadInt16()); + case "System.Int64": return resourceDataFactory.Create(reader.ReadInt64()); + case "System.UInt16": return resourceDataFactory.Create(reader.ReadUInt16()); + case "System.UInt32": return resourceDataFactory.Create(reader.ReadUInt32()); + case "System.UInt64": return resourceDataFactory.Create(reader.ReadUInt64()); + case "System.Single": return resourceDataFactory.Create(reader.ReadSingle()); + case "System.Double": return resourceDataFactory.Create(reader.ReadDouble()); + case "System.DateTime": return resourceDataFactory.Create(new DateTime(reader.ReadInt64())); + case "System.TimeSpan": return resourceDataFactory.Create(new TimeSpan(reader.ReadInt64())); + case "System.Decimal": return resourceDataFactory.Create(reader.ReadDecimal()); + default: + return ReadSerializedObject(endPos, type); + } + } + + IResourceData ReadSerializedObject(uint endPos, UserResourceType type) { + var serializedData = reader.ReadBytes((int)(endPos - reader.Position)); + var res = createResourceDataDelegate?.Invoke(resourceDataFactory, type, serializedData); + return res ?? resourceDataFactory.CreateSerialized(serializedData, type); + } + + static int ReadInt32(ref DataReader reader) { + try { + return reader.Read7BitEncodedInt32(); + } + catch { + throw new ResourceReaderException("Invalid encoded int32"); } } @@ -221,7 +260,7 @@ bool CheckReaders() { for (int i = 0; i < numReaders; i++) { var resourceReaderFullName = reader.ReadSerializedString(); /*var resourceSetFullName = */reader.ReadSerializedString(); - if (Regex.IsMatch(resourceReaderFullName, @"^System\.Resources\.ResourceReader,\s*mscorlib,")) + if (Regex.IsMatch(resourceReaderFullName, @"^System\.Resources\.ResourceReader,\s*mscorlib")) validReader = true; } From c20c7247ef0ea20e7f2b9e551781f2ca8eb85963 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Tue, 24 Aug 2021 07:09:53 +0200 Subject: [PATCH 405/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 7b4bda17d..2ced3d7e7 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.3.3 + 3.3.4 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 08bb3b0042484a6d6edc8d0a30be4065454f23f1 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 30 Aug 2021 14:04:17 +0200 Subject: [PATCH 406/511] Analyze module resources in MemberFinder --- src/DotNet/MemberFinder.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index 5e301a24f..b6f9a25fb 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -177,6 +177,7 @@ void Add(ModuleDef mod) { if (mod.IsManifestModule) Add(mod.Assembly); Add(mod.VTableFixups); + Add(mod.Resources); } void Add(VTableFixups fixups) { @@ -188,6 +189,12 @@ void Add(VTableFixups fixups) { } } + void Add(ResourceCollection resources) { + foreach (var resource in resources) { + Add(resource.CustomAttributes); + } + } + void Add(AssemblyDef asm) { if (asm is null) return; From c25b45517ff261d434dc061cff7b19eacfe9542e Mon Sep 17 00:00:00 2001 From: wtfsck Date: Wed, 20 Oct 2021 21:29:13 +0200 Subject: [PATCH 407/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 2ced3d7e7..fd16a7556 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.3.4 + 3.3.5 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 1386325391fda1e2ca6339bf0e343e812c5fd346 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Mon, 6 Dec 2021 02:42:01 +0800 Subject: [PATCH 408/511] Add ImporterOptions.TryToUseExistingAssemblyRefs option (#422) * add ImporterOptions.TryToUseExistingAssemblyRefs option to use already existing AssemblyRefs whenever possible * remove duplicated code --- src/DotNet/Importer.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index f19f1aa9a..06a533607 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -37,6 +37,11 @@ public enum ImporterOptions { /// TryToUseDefs = TryToUseTypeDefs | TryToUseMethodDefs | TryToUseFieldDefs, + /// + /// Use already existing s whenever possible + /// + TryToUseExistingAssemblyRefs = 8, + /// /// Don't set this flag. For internal use only. /// @@ -79,7 +84,7 @@ public abstract class ImportMapper { /// Overrides default behavior of /// May be used to use reference assemblies for resolution, for example. /// - /// to create for. + /// to create for. is non-generic type or generic type without generic arguments. /// or null to use default 's type resolution public virtual TypeRef Map(Type source) => null; } @@ -98,6 +103,7 @@ public struct Importer { bool TryToUseTypeDefs => (options & ImporterOptions.TryToUseTypeDefs) != 0; bool TryToUseMethodDefs => (options & ImporterOptions.TryToUseMethodDefs) != 0; bool TryToUseFieldDefs => (options & ImporterOptions.TryToUseFieldDefs) != 0; + bool TryToUseExistingAssemblyRefs => (options & ImporterOptions.TryToUseExistingAssemblyRefs) != 0; bool FixSignature { get => (options & ImporterOptions.FixSignature) != 0; @@ -320,7 +326,7 @@ TypeDef GetDeclaringType(MemberRef mr) { bool IsThisModule(TypeRef tr) { if (tr is null) return false; - var scopeType = tr.ScopeType.GetNonNestedTypeRefScope() as TypeRef; + var scopeType = tr.GetNonNestedTypeRefScope() as TypeRef; if (scopeType is null) return false; @@ -374,6 +380,8 @@ IResolutionScope CreateScopeReference(Type type) { var pkt = asmName.GetPublicKeyToken(); if (pkt is null || pkt.Length == 0) pkt = null; + if (TryToUseExistingAssemblyRefs && module.GetAssemblyRef(asmName.Name) is AssemblyRef asmRef) + return asmRef; return module.UpdateRowId(new AssemblyRefUser(asmName.Name, asmName.Version, PublicKeyBase.CreatePublicKeyToken(pkt), asmName.CultureInfo.Name)); } @@ -719,6 +727,8 @@ IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { var pkt = PublicKeyBase.ToPublicKeyToken(defAsm.PublicKeyOrToken); if (PublicKeyBase.IsNullOrEmpty2(pkt)) pkt = null; + if (TryToUseExistingAssemblyRefs && module.GetAssemblyRef(defAsm.Name) is AssemblyRef asmRef) + return asmRef; return module.UpdateRowId(new AssemblyRefUser(defAsm.Name, defAsm.Version, pkt, defAsm.Culture) { Attributes = defAsm.Attributes & ~AssemblyAttributes.PublicKey }); } From ea4bb75b7923f5b4ac02a9ba88748f59cbd14e72 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Mon, 6 Dec 2021 03:47:38 +0800 Subject: [PATCH 409/511] Show method name and token (#421) * Show method name and token * Restore the overload without 'args' * Add IWriterError2 * Fix breaking change --- src/DotNet/Writer/IWriterError.cs | 14 ++++++++++ src/DotNet/Writer/Metadata.cs | 7 +++-- src/DotNet/Writer/MethodBodyWriter.cs | 38 ++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Writer/IWriterError.cs b/src/DotNet/Writer/IWriterError.cs index 4a0fb1881..8575b4fea 100644 --- a/src/DotNet/Writer/IWriterError.cs +++ b/src/DotNet/Writer/IWriterError.cs @@ -13,4 +13,18 @@ public interface IWriterError { /// Error message void Error(string message); } + + /// + /// Gets notified of errors. The default handler should normally throw since the written data + /// will probably be invalid. Any error can be ignored. + /// + public interface IWriterError2 : IWriterError { + /// + /// Called when an error is detected (eg. a null pointer or other invalid value). The error + /// can be ignored but the written data won't be valid. + /// + /// Error message + /// Optional message arguments + void Error(string message, params object[] args); + } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index f6d4ca802..16ee86056 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -438,7 +438,7 @@ public MetadataProgressEventArgs(Metadata metadata, double progress) { /// /// .NET meta data /// - public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenProvider, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper { + public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenProvider, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper, IWriterError2 { uint length; FileOffset offset; RVA rva; @@ -1999,7 +1999,7 @@ void WriteMethodBodies() { var cilBody = method.Body; if (cilBody is not null) { if (!(cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0)) { - writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); + writer.Reset(method, keepMaxStack || cilBody.KeepOldMaxStack); writer.Write(); var origRva = method.RVA; uint origSize = cilBody.MetadataBodySize; @@ -3563,6 +3563,9 @@ internal void WritePortablePdb(Stream output, uint entryPointToken, out long pdb /// void IWriterError.Error(string message) => Error(message); + /// + void IWriterError2.Error(string message, params object[] args) => Error(message, args); + /// bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => FullNameFactory.MustUseAssemblyName(module, type, OptimizeCustomAttributeSerializedTypeNames); diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index bb5198613..f4dabe9b2 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -31,6 +31,7 @@ public interface ITokenProvider : IWriterError { /// public sealed class MethodBodyWriter : MethodBodyWriterBase { readonly ITokenProvider helper; + MethodDef method; CilBody cilBody; bool keepMaxStack; uint codeSize; @@ -57,6 +58,29 @@ public sealed class MethodBodyWriter : MethodBodyWriterBase { /// public uint LocalVarSigTok => localVarSigTok; + /// + /// Constructor + /// + /// Helps this instance + /// The method + public MethodBodyWriter(ITokenProvider helper, MethodDef method) + : this(helper, method, false) { + } + + /// + /// Constructor + /// + /// Helps this instance + /// The method + /// Keep the original max stack value that has been initialized + /// in + public MethodBodyWriter(ITokenProvider helper, MethodDef method, bool keepMaxStack) + : base(method.Body.Instructions, method.Body.ExceptionHandlers) { + this.helper = helper; + this.method = method; + this.keepMaxStack = keepMaxStack; + } + /// /// Constructor /// @@ -84,15 +108,16 @@ internal MethodBodyWriter(ITokenProvider helper) { this.helper = helper; } - internal void Reset(CilBody cilBody, bool keepMaxStack) { - Reset(cilBody.Instructions, cilBody.ExceptionHandlers); - this.cilBody = cilBody; + internal void Reset(MethodDef method, bool keepMaxStack) { + this.method = method; this.keepMaxStack = keepMaxStack; + cilBody = method.Body; codeSize = 0; maxStack = 0; code = null; extraSections = null; localVarSigTok = 0; + Reset(cilBody.Instructions, cilBody.ExceptionHandlers); } /// @@ -299,7 +324,12 @@ byte[] WriteSmallExceptionClauses() { } /// - protected override void ErrorImpl(string message) => helper.Error(message); + protected override void ErrorImpl(string message) { + if (method is not null && helper is IWriterError2 writerError2) + writerError2.Error(message + " At method {0} ({1:X8}).", method, method.MDToken.Raw); + else + helper.Error(message); + } /// protected override void WriteInlineField(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); From f21edfa871bb8e70eee2a7111f00339e53450c82 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Mon, 6 Dec 2021 20:54:35 +0800 Subject: [PATCH 410/511] Improve rva/fileoffset conversion and ReadCilBody (#428) * improve rva/fileoffset conversion, return 0 if fail improve ReadCilBody, return empty body if fileoffset is invalid * update comments format --- src/DotNet/ModuleDefMD.cs | 6 ++++- src/PE/IPEImage.cs | 4 +-- src/PE/IPEType.cs | 4 +-- src/PE/PEInfo.cs | 51 ++++++++++++++++++++++++++++----------- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 2918b4b8b..4647e5dc3 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1296,8 +1296,12 @@ public CilBody ReadCilBody(IList parameters, RVA rva, GenericParamCon // If we create a partial stream starting from rva, then position will be 0 and always // 4-byte aligned. All fat method bodies should be 4-byte aligned, but the CLR doesn't // seem to verify it. We must parse the method exactly the way the CLR parses it. + var offset = metadata.PEImage.ToFileOffset(rva); + if (offset == 0) + return new CilBody(); + var reader = metadata.PEImage.CreateReader(); - reader.Position = (uint)metadata.PEImage.ToFileOffset(rva); + reader.Position = (uint)offset; return MethodBodyReader.CreateCilBody(this, reader, parameters, gpContext, Context); } diff --git a/src/PE/IPEImage.cs b/src/PE/IPEImage.cs index 6f78f6f4e..744c2552e 100644 --- a/src/PE/IPEImage.cs +++ b/src/PE/IPEImage.cs @@ -11,14 +11,14 @@ namespace dnlib.PE { /// public interface IRvaFileOffsetConverter { /// - /// Converts a to an + /// Converts a to an , returns 0 if out of range /// /// The file offset to convert /// The RVA RVA ToRVA(FileOffset offset); /// - /// Converts an to a + /// Converts an to a , returns 0 if out of range /// /// The RVA to convert /// The file offset diff --git a/src/PE/IPEType.cs b/src/PE/IPEType.cs index d4b3ca58b..8846e40a6 100644 --- a/src/PE/IPEType.cs +++ b/src/PE/IPEType.cs @@ -8,7 +8,7 @@ namespace dnlib.PE { /// interface IPEType { /// - /// Converts a to an + /// Converts a to an , returns 0 if out of range /// /// The PEInfo context /// The file offset to convert @@ -16,7 +16,7 @@ interface IPEType { RVA ToRVA(PEInfo peInfo, FileOffset offset); /// - /// Converts an to a + /// Converts an to a , returns 0 if out of range /// /// The PEInfo context /// The RVA to convert diff --git a/src/PE/PEInfo.cs b/src/PE/PEInfo.cs index db1760406..3065c2564 100644 --- a/src/PE/PEInfo.cs +++ b/src/PE/PEInfo.cs @@ -5,7 +5,7 @@ namespace dnlib.PE { /// - /// Reads all PE sections from a PE stream + /// Reads all PE sections from a PE stream, for more information see https://docs.microsoft.com/en-us/windows/win32/debug/pe-format /// sealed class PEInfo { readonly ImageDosHeader imageDosHeader; @@ -64,7 +64,7 @@ public PEInfo(ref DataReader reader, bool verify) { /// public ImageSectionHeader ToImageSectionHeader(FileOffset offset) { foreach (var section in imageSectionHeaders) { - if ((long)offset >= section.PointerToRawData && (long)offset < section.PointerToRawData + section.SizeOfRawData) + if ((uint)offset >= section.PointerToRawData && (uint)offset < section.PointerToRawData + section.SizeOfRawData) return section; } return null; @@ -77,34 +77,58 @@ public ImageSectionHeader ToImageSectionHeader(FileOffset offset) { /// The RVA /// public ImageSectionHeader ToImageSectionHeader(RVA rva) { + uint alignment = imageNTHeaders.OptionalHeader.SectionAlignment; foreach (var section in imageSectionHeaders) { - if (rva >= section.VirtualAddress && rva < section.VirtualAddress + Math.Max(section.VirtualSize, section.SizeOfRawData)) + if (rva >= section.VirtualAddress && rva < section.VirtualAddress + DotNet.Utils.AlignUp(section.VirtualSize, alignment)) return section; } return null; } /// - /// Converts a to an + /// Converts a to an , returns 0 if out of range /// /// The file offset to convert /// The RVA public RVA ToRVA(FileOffset offset) { + // In pe headers + if (imageSectionHeaders.Length == 0) + return (RVA)offset; + + // In pe additional data, like digital signature, won't be loaded into memory + var lastSection = imageSectionHeaders[imageSectionHeaders.Length - 1]; + if ((uint)offset > lastSection.PointerToRawData + lastSection.SizeOfRawData) + return 0; + + // In a section var section = ToImageSectionHeader(offset); if (section is not null) return (uint)(offset - section.PointerToRawData) + section.VirtualAddress; + + // In pe headers return (RVA)offset; } /// - /// Converts an to a + /// Converts an to a , returns 0 if out of range /// /// The RVA to convert /// The file offset public FileOffset ToFileOffset(RVA rva) { + // Check if rva is larger than memory layout size + if ((uint)rva >= imageNTHeaders.OptionalHeader.SizeOfImage) + return 0; + var section = ToImageSectionHeader(rva); - if (section is not null) - return (FileOffset)(rva - section.VirtualAddress + section.PointerToRawData); + if (section is not null) { + uint offset = rva - section.VirtualAddress; + // Virtual size may be bigger than raw size and there may be no corresponding file offset to rva + if (offset < section.SizeOfRawData) + return (FileOffset)offset + section.PointerToRawData; + return 0; + } + + // If not in any section, rva is in pe headers and don't convert it return (FileOffset)rva; } @@ -118,13 +142,12 @@ public FileOffset ToFileOffset(RVA rva) { public uint GetImageSize() { var optHdr = ImageNTHeaders.OptionalHeader; uint alignment = optHdr.SectionAlignment; - ulong length = AlignUp(optHdr.SizeOfHeaders, alignment); - foreach (var section in imageSectionHeaders) { - ulong length2 = AlignUp((ulong)section.VirtualAddress + Math.Max(section.VirtualSize, section.SizeOfRawData), alignment); - if (length2 > length) - length = length2; - } - return (uint)Math.Min(length, uint.MaxValue); + if (imageSectionHeaders.Length == 0) + return (uint)AlignUp(optHdr.SizeOfHeaders, alignment); + + // Section headers must be in ascending order and adjacent + var section = imageSectionHeaders[imageSectionHeaders.Length - 1]; + return (uint)Math.Min(AlignUp((ulong)section.VirtualAddress + section.VirtualSize, alignment), uint.MaxValue); } } } From 22c0f1e95475cba8034f04f6c008ef3feb9054e5 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:57:03 +0100 Subject: [PATCH 411/511] Update `.gitignore` --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4b82ccd91..f6adf54ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vs/ +.vscode/ bin/ obj/ From c03a9e9a0d64df7f21051b6c4fc1201ff24b87d6 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:57:18 +0100 Subject: [PATCH 412/511] Update `.NET` refs to use `.NET Framework` --- src/DotNet/AssemblyResolver.cs | 6 +++--- src/DotNet/DeclSecurity.cs | 2 +- src/DotNet/DeclSecurityReader.cs | 4 ++-- src/DotNet/Emit/DynamicMethodBodyReader.cs | 4 ++-- src/DotNet/Emit/MethodTableToTypeConverter.cs | 6 +++--- src/DotNet/MD/MDHeaderRuntimeVersion.cs | 14 +++++++------- src/DotNet/ModuleDef.cs | 18 +++++++++--------- src/DotNet/ModuleDefMD.cs | 2 +- src/DotNet/SigComparer.cs | 4 ++-- src/DotNet/StrongNameSigner.cs | 2 +- 10 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index 9c194b29e..bf4355d60 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -156,8 +156,8 @@ public bool FindExactMatch { /// /// true if resolved .NET framework assemblies can be redirected to the source - /// module's framework assembly version. Eg. if a resolved .NET 3.5 assembly can be - /// redirected to a .NET 4.0 assembly if the source module is a .NET 4.0 assembly. This is + /// module's framework assembly version. Eg. if a resolved .NET Framework 3.5 assembly can be + /// redirected to a .NET Framework 4.0 assembly if the source module is a .NET Framework 4.0 assembly. This is /// ignored if is true. /// public bool EnableFrameworkRedirect { @@ -585,7 +585,7 @@ IEnumerable FindAssembliesGac(IAssembly assembly, ModuleDef sourceModule IEnumerable GetGacInfos(ModuleDef sourceModule) { int version = sourceModule is null ? int.MinValue : sourceModule.IsClr40 ? 4 : 2; - // Try the correct GAC first (eg. GAC4 if it's a .NET 4 assembly) + // Try the correct GAC first (eg. GAC4 if it's a .NET Framework 4 assembly) foreach (var gacInfo in gacInfos) { if (gacInfo.Version == version) yield return gacInfo; diff --git a/src/DotNet/DeclSecurity.cs b/src/DotNet/DeclSecurity.cs index 76ef83909..ff9a12763 100644 --- a/src/DotNet/DeclSecurity.cs +++ b/src/DotNet/DeclSecurity.cs @@ -109,7 +109,7 @@ protected virtual void InitializeCustomDebugInfos() => public abstract byte[] GetBlob(); /// - /// Returns the .NET 1.x XML string or null if it's not a .NET 1.x format + /// Returns the .NET Framework 1.x XML string or null if it's not a .NET Framework 1.x format /// /// public string GetNet1xXmlString() => GetNet1xXmlStringInternal(SecurityAttributes); diff --git a/src/DotNet/DeclSecurityReader.cs b/src/DotNet/DeclSecurityReader.cs index 7db8c1713..6215237d9 100644 --- a/src/DotNet/DeclSecurityReader.cs +++ b/src/DotNet/DeclSecurityReader.cs @@ -89,7 +89,7 @@ IList Read() { } /// - /// Reads the new (.NET 2.0+) DeclSecurity blob format + /// Reads the new (.NET Framework 2.0+) DeclSecurity blob format /// /// IList ReadBinaryFormat() { @@ -112,7 +112,7 @@ IList ReadBinaryFormat() { } /// - /// Reads the old (.NET 1.x) DeclSecurity blob format + /// Reads the old (.NET Framework 1.x) DeclSecurity blob format /// /// IList ReadXmlFormat() { diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index abaa8efd4..50ff23e25 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -476,13 +476,13 @@ IMethod ImportMethod(uint rid) { SR.MethodInfo GetVarArgMethod(object obj) { if (vamDynamicMethodFieldInfo.Exists(obj)) { - // .NET 4.0+ + // .NET Framework 4.0+ var method = vamMethodFieldInfo.Read(obj) as SR.MethodInfo; var dynMethod = vamDynamicMethodFieldInfo.Read(obj) as DynamicMethod; return dynMethod ?? method; } else { - // .NET 2.0 + // .NET Framework 2.0 // This is either a DynamicMethod or a MethodInfo return vamMethodFieldInfo.Read(obj) as SR.MethodInfo; } diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index dbb01405c..33cd68ea1 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -71,7 +71,7 @@ static Type GetTypeUsingTypeBuilder(IntPtr address) { } } - // .NET 4.5 and later have the documented SetMethodBody() method. + // .NET Framework 4.5 and later have the documented SetMethodBody() method. static Type GetTypeNET45(TypeBuilder tb, MethodBuilder mb, IntPtr address) { var code = new byte[1] { 0x2A }; int maxStack = 8; @@ -86,7 +86,7 @@ static Type GetTypeNET45(TypeBuilder tb, MethodBuilder mb, IntPtr address) { return createdMethod.GetMethodBody().LocalVariables[0].LocalType; } - // This code works with .NET 4.0+ but will throw an exception if .NET 2.0 is used + // This code works with .NET Framework 4.0+ but will throw an exception if .NET Framework 2.0 is used // ("operation could destabilize the runtime") static Type GetTypeNET40(TypeBuilder tb, MethodBuilder mb, IntPtr address) { var ilg = mb.GetILGenerator(); @@ -109,7 +109,7 @@ static Type GetTypeNET40(TypeBuilder tb, MethodBuilder mb, IntPtr address) { return createdMethod.GetMethodBody().LocalVariables[0].LocalType; } - // .NET 2.0 - 3.5 + // .NET Framework 2.0 - 3.5 static Type GetTypeNET20(IntPtr address) { if (ptrFieldInfo is null) return null; diff --git a/src/DotNet/MD/MDHeaderRuntimeVersion.cs b/src/DotNet/MD/MDHeaderRuntimeVersion.cs index 054e0d6b2..ab16a77a4 100644 --- a/src/DotNet/MD/MDHeaderRuntimeVersion.cs +++ b/src/DotNet/MD/MDHeaderRuntimeVersion.cs @@ -6,37 +6,37 @@ namespace dnlib.DotNet.MD { /// public static class MDHeaderRuntimeVersion { /// - /// MS CLR 1.0 version string (.NET 1.0) + /// MS CLR 1.0 version string (.NET Framework 1.0) /// public const string MS_CLR_10 = "v1.0.3705"; /// - /// MS CLR 1.0 version string (.NET 1.0). This is an incorrect version that shouldn't be used. + /// MS CLR 1.0 version string (.NET Framework 1.0). This is an incorrect version that shouldn't be used. /// public const string MS_CLR_10_X86RETAIL = "v1.x86ret"; /// - /// MS CLR 1.0 version string (.NET 1.0). This is an incorrect version that shouldn't be used. + /// MS CLR 1.0 version string (.NET Framework 1.0). This is an incorrect version that shouldn't be used. /// public const string MS_CLR_10_RETAIL = "retail"; /// - /// MS CLR 1.0 version string (.NET 1.0). This is an incorrect version that shouldn't be used. + /// MS CLR 1.0 version string (.NET Framework 1.0). This is an incorrect version that shouldn't be used. /// public const string MS_CLR_10_COMPLUS = "COMPLUS"; /// - /// MS CLR 1.1 version string (.NET 1.1) + /// MS CLR 1.1 version string (.NET Framework 1.1) /// public const string MS_CLR_11 = "v1.1.4322"; /// - /// MS CLR 2.0 version string (.NET 2.0-3.5) + /// MS CLR 2.0 version string (.NET Framework 2.0-3.5) /// public const string MS_CLR_20 = "v2.0.50727"; /// - /// MS CLR 4.0 version string (.NET 4.0-4.5) + /// MS CLR 4.0 version string (.NET Framework 4.0-4.5) /// public const string MS_CLR_40 = "v4.0.30319"; diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 881b888a9..51bc5c6cc 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -764,7 +764,7 @@ public ComImageFlags Cor20HeaderFlags { /// /// Gets/sets the runtime version number in the COR20 header. The major version is /// in the high 16 bits. The minor version is in the low 16 bits. This is normally 2.5 - /// (0x00020005), but if it's .NET 1.x, it should be 2.0 (0x00020000). If this is + /// (0x00020005), but if it's .NET Framework 1.x, it should be 2.0 (0x00020000). If this is /// null, the default value will be used when saving the module (2.0 if CLR 1.x, /// and 2.5 if not CLR 1.x). /// @@ -772,12 +772,12 @@ public ComImageFlags Cor20HeaderFlags { /// /// Gets the tables header version. The major version is in the upper 8 bits and the - /// minor version is in the lower 8 bits. .NET 1.0/1.1 use version 1.0 (0x0100) and - /// .NET 2.x and later use version 2.0 (0x0200). 1.0 has no support for generics, + /// minor version is in the lower 8 bits. .NET Framework 1.0/1.1 use version 1.0 (0x0100) and + /// .NET Framework 2.x and later use version 2.0 (0x0200). 1.0 has no support for generics, /// 1.1 has support for generics (GenericParam rows have an extra Kind column), /// and 2.0 has support for generics (GenericParam rows have the standard 4 columns). /// No other version is supported. If this is null, the default version is - /// used (1.0 if .NET 1.x, else 2.0). + /// used (1.0 if .NET Framework 1.x, else 2.0). /// public ushort? TablesHeaderVersion { get; set; } @@ -1137,7 +1137,7 @@ public int GetPointerSize(int defaultPointerSize, int prefer32bitPointerSize) { if ((flags & ComImageFlags.ILOnly) == 0) return 4; - // 32-bit Preferred flag is new in .NET 4.5. See CorHdr.h in Windows SDK for more info + // 32-bit Preferred flag is new in .NET Framework 4.5. See CorHdr.h in Windows SDK for more info switch (flags & (ComImageFlags.Bit32Required | ComImageFlags.Bit32Preferred)) { case 0: // Machine and ILOnly flag should be checked @@ -1449,8 +1449,8 @@ public ModuleDefUser(UTF8String name, Guid? mvid, AssemblyRef corLibAssemblyRef) RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; Machine = Machine.I386; cor20HeaderFlags = (int)ComImageFlags.ILOnly; - Cor20HeaderRuntimeVersion = 0x00020005; // .NET 2.0 or later should use 2.5 - TablesHeaderVersion = 0x0200; // .NET 2.0 or later should use 2.0 + Cor20HeaderRuntimeVersion = 0x00020005; // .NET Framework 2.0 or later should use 2.5 + TablesHeaderVersion = 0x0200; // .NET Framework 2.0 or later should use 2.0 types = new LazyList(this); exportedTypes = new LazyList(); resources = new ResourceCollection(); @@ -1527,8 +1527,8 @@ internal ModuleDefMD2(ModuleDefMD readerModule, uint rid) { RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; Machine = Machine.I386; cor20HeaderFlags = (int)ComImageFlags.ILOnly; - Cor20HeaderRuntimeVersion = 0x00020005; // .NET 2.0 or later should use 2.5 - TablesHeaderVersion = 0x0200; // .NET 2.0 or later should use 2.0 + Cor20HeaderRuntimeVersion = 0x00020005; // .NET Framework 2.0 or later should use 2.5 + TablesHeaderVersion = 0x0200; // .NET Framework 2.0 or later should use 2.0 corLibTypes = new CorLibTypes(this); location = string.Empty; InitializeFromRawRow(); diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index 4647e5dc3..f265b435c 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1495,7 +1495,7 @@ Resource CreateResource(uint rid) { return new EmbeddedResourceMD(this, mr, Array2.Empty()); } - [HandleProcessCorruptedStateExceptions, SecurityCritical] // Req'd on .NET 4.0 + [HandleProcessCorruptedStateExceptions, SecurityCritical] // Req'd on .NET Framework 4.0 bool TryCreateResourceStream(uint offset, out DataReaderFactory dataReaderFactory, out uint resourceOffset, out uint resourceLength) { dataReaderFactory = null; resourceOffset = 0; diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 15ebc8d50..7d0f4ae85 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -465,7 +465,7 @@ public enum SigComparerOptions : uint { /// /// By default, all module and assembly compares when they're both the system library /// (eg. mscorlib or System.Runtime.dll) return true, even if they're really different, - /// eg. mscorlib (.NET 2.0) vs mscorlib (Windows CE). If this flag is set, the system + /// eg. mscorlib (.NET Framework 2.0) vs mscorlib (Windows CE). If this flag is set, the system /// library is compared just like any other module/assembly. /// MscorlibIsNotSpecial = 0x100000, @@ -476,7 +476,7 @@ public enum SigComparerOptions : uint { DontProjectWinMDRefs = 0x200000, /// - /// Don't check type equivalence when comparing types. Starting with .NET 4.0, two different + /// Don't check type equivalence when comparing types. Starting with .NET Framework 4.0, two different /// types can be considered equivalent if eg. a TypeIdentifierAttribute is used. /// DontCheckTypeEquivalence = 0x400000, diff --git a/src/DotNet/StrongNameSigner.cs b/src/DotNet/StrongNameSigner.cs index c30f017f9..75e93792e 100644 --- a/src/DotNet/StrongNameSigner.cs +++ b/src/DotNet/StrongNameSigner.cs @@ -7,7 +7,7 @@ namespace dnlib.DotNet { /// /// Strong name signs an assembly. It supports normal strong name signing and the new - /// (.NET 4.5) enhanced strong name signing. + /// (.NET Framework 4.5) enhanced strong name signing. /// public readonly struct StrongNameSigner { readonly Stream stream; From 983710999c0b7171192df70487e1289c7cf03995 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:57:33 +0100 Subject: [PATCH 413/511] Add `s390x` to `Machine` enum; add some props/methods --- src/DotNet/ModuleDef.cs | 5 +++++ src/PE/Machine.cs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/DotNet/ModuleDef.cs b/src/DotNet/ModuleDef.cs index 51bc5c6cc..4fe5bbc61 100644 --- a/src/DotNet/ModuleDef.cs +++ b/src/DotNet/ModuleDef.cs @@ -751,6 +751,11 @@ public bool IsClr10 { /// public bool IsARM64 => Machine.IsARM64(); + /// + /// true if is s390x, , ... + /// + public bool IsS390x => Machine.IsS390x(); + /// /// Gets/sets the (from .NET header) /// diff --git a/src/PE/Machine.cs b/src/PE/Machine.cs index d3911c607..7cacdd0de 100644 --- a/src/PE/Machine.cs +++ b/src/PE/Machine.cs @@ -75,26 +75,31 @@ public enum Machine : ushort { AMD64_Native_Apple = AMD64 ^ 0x4644, ARMNT_Native_Apple = ARMNT ^ 0x4644, ARM64_Native_Apple = ARM64 ^ 0x4644, + S390X_Native_Apple = Unknown ^ 0x4644, I386_Native_FreeBSD = I386 ^ 0xADC4, AMD64_Native_FreeBSD = AMD64 ^ 0xADC4, ARMNT_Native_FreeBSD = ARMNT ^ 0xADC4, ARM64_Native_FreeBSD = ARM64 ^ 0xADC4, + S390X_Native_FreeBSD = Unknown ^ 0xADC4, I386_Native_Linux = I386 ^ 0x7B79, AMD64_Native_Linux = AMD64 ^ 0x7B79, ARMNT_Native_Linux = ARMNT ^ 0x7B79, ARM64_Native_Linux = ARM64 ^ 0x7B79, + S390X_Native_Linux = Unknown ^ 0x7B79, I386_Native_NetBSD = I386 ^ 0x1993, AMD64_Native_NetBSD = AMD64 ^ 0x1993, ARMNT_Native_NetBSD = ARMNT ^ 0x1993, ARM64_Native_NetBSD = ARM64 ^ 0x1993, + S390X_Native_NetBSD = Unknown ^ 0x1993, I386_Native_Sun = I386 ^ 0x1992, AMD64_Native_Sun = AMD64 ^ 0x1992, ARMNT_Native_Sun = ARMNT ^ 0x1992, ARM64_Native_Sun = ARM64 ^ 0x1992, + S390X_Native_Sun = Unknown ^ 0x1992, #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } @@ -126,6 +131,15 @@ public static bool Is64Bit(this Machine machine) { case Machine.ARM64_Native_Sun: return true; + // It uses value 0==Unknown but we can't assume it's always s390x + //case Machine.Unknown: + case Machine.S390X_Native_Apple: + case Machine.S390X_Native_FreeBSD: + case Machine.S390X_Native_Linux: + case Machine.S390X_Native_NetBSD: + case Machine.S390X_Native_Sun: + return true; + default: return false; } @@ -206,5 +220,25 @@ public static bool IsARM64(this Machine machine) { return false; } } + + /// + /// Checks if is s390x, , etc... + /// + /// Machine + /// + public static bool IsS390x(this Machine machine) { + switch (machine) { + // It uses value 0==Unknown but we can't assume it's always s390x + //case Machine.Unknown: + case Machine.S390X_Native_Apple: + case Machine.S390X_Native_FreeBSD: + case Machine.S390X_Native_Linux: + case Machine.S390X_Native_NetBSD: + case Machine.S390X_Native_Sun: + return true; + default: + return false; + } + } } } From 76ab5265f2a54ac3fd48df312e5b5ae808bfb18f Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:57:43 +0100 Subject: [PATCH 414/511] Add `PA_ARM64` to `AssemblyAttributes`, closes #425 --- src/DotNet/AssemblyAttributes.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/AssemblyAttributes.cs b/src/DotNet/AssemblyAttributes.cs index 7d2b2dbec..c4a687f43 100644 --- a/src/DotNet/AssemblyAttributes.cs +++ b/src/DotNet/AssemblyAttributes.cs @@ -27,6 +27,8 @@ public enum AssemblyAttributes : uint { PA_AMD64 = 0x0040, /// Processor Architecture: ARM (PE32) PA_ARM = 0x0050, + /// Processor Architecture: ARM64 (PE32+) + PA_ARM64 = 0x0060, /// applies to any platform but cannot run on any (e.g. reference assembly), should not have "specified" set PA_NoPlatform = 0x0070, /// Propagate PA flags to AssemblyRef record From b9cfa620fd2a1eb7c20e1f473aa68a2d2f292366 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:57:52 +0100 Subject: [PATCH 415/511] Update exception handler type checks --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 10 +++++----- src/DotNet/Emit/ExceptionHandler.cs | 22 +++++++++++++++++++++- src/DotNet/Emit/MethodBodyReader.cs | 8 ++++---- src/DotNet/Emit/MethodBodyReaderBase.cs | 2 +- src/DotNet/Writer/MaxStackCalculator.cs | 2 +- src/DotNet/Writer/MethodBodyWriter.cs | 8 ++++---- 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 50ff23e25..26ff4641f 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -326,9 +326,9 @@ void CreateExceptionHandlers() { eh.HandlerStart = GetInstructionThrow((uint)offs); eh.HandlerEnd = GetInstruction((uint)(reader.ReadByte() + offs)); - if (eh.HandlerType == ExceptionHandlerType.Catch) + if (eh.IsCatch) eh.CatchType = ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; - else if (eh.HandlerType == ExceptionHandlerType.Filter) + else if (eh.IsFilter) eh.FilterStart = GetInstruction(reader.ReadUInt32()); else reader.ReadUInt32(); @@ -351,9 +351,9 @@ void CreateExceptionHandlers() { eh.HandlerStart = GetInstructionThrow((uint)offs); eh.HandlerEnd = GetInstruction((uint)(reader.ReadUInt32() + offs)); - if (eh.HandlerType == ExceptionHandlerType.Catch) + if (eh.IsCatch) eh.CatchType = ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; - else if (eh.HandlerType == ExceptionHandlerType.Filter) + else if (eh.IsFilter) eh.FilterStart = GetInstruction(reader.ReadUInt32()); else reader.ReadUInt32(); @@ -371,7 +371,7 @@ void CreateExceptionHandlers() { var eh = new ExceptionHandler(); eh.HandlerType = (ExceptionHandlerType)ehInfo.Type[i]; eh.TryStart = tryStart; - eh.TryEnd = eh.HandlerType == ExceptionHandlerType.Finally ? endFinally : tryEnd; + eh.TryEnd = eh.IsFinally ? endFinally : tryEnd; eh.FilterStart = null; // not supported by DynamicMethod.ILGenerator eh.HandlerStart = GetInstructionThrow((uint)ehInfo.CatchAddr[i]); eh.HandlerEnd = GetInstruction((uint)ehInfo.CatchEndAddr[i]); diff --git a/src/DotNet/Emit/ExceptionHandler.cs b/src/DotNet/Emit/ExceptionHandler.cs index 48b10936c..e98f6bc3d 100644 --- a/src/DotNet/Emit/ExceptionHandler.cs +++ b/src/DotNet/Emit/ExceptionHandler.cs @@ -34,7 +34,7 @@ public sealed class ExceptionHandler { public Instruction HandlerEnd; /// - /// The catch type if is + /// The catch type if is /// public ITypeDefOrRef CatchType; @@ -43,6 +43,26 @@ public sealed class ExceptionHandler { /// public ExceptionHandlerType HandlerType; + /// + /// Checks if it's a `catch` handler + /// + public bool IsCatch => ((uint)HandlerType & 7) == (uint)ExceptionHandlerType.Catch; + + /// + /// Checks if it's a `filter` handler + /// + public bool IsFilter => (HandlerType & ExceptionHandlerType.Filter) != 0; + + /// + /// Checks if it's a `finally` handler + /// + public bool IsFinally => (HandlerType & ExceptionHandlerType.Finally) != 0; + + /// + /// Checks if it's a `fault` handler + /// + public bool IsFault => (HandlerType & ExceptionHandlerType.Fault) != 0; + /// /// Default constructor /// diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index 01950f8f6..8a2c68625 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -494,9 +494,9 @@ void ReadFatExceptionHandlers(ref DataReader ehReader) { offs = ehReader.ReadUInt32(); eh.HandlerStart = GetInstruction(offs); eh.HandlerEnd = GetInstruction(offs + ehReader.ReadUInt32()); - if (eh.HandlerType == ExceptionHandlerType.Catch) + if (eh.IsCatch) eh.CatchType = opResolver.ResolveToken(ehReader.ReadUInt32(), gpContext) as ITypeDefOrRef; - else if (eh.HandlerType == ExceptionHandlerType.Filter) + else if (eh.IsFilter) eh.FilterStart = GetInstruction(ehReader.ReadUInt32()); else ehReader.ReadUInt32(); @@ -515,9 +515,9 @@ void ReadSmallExceptionHandlers(ref DataReader ehReader) { offs = ehReader.ReadUInt16(); eh.HandlerStart = GetInstruction(offs); eh.HandlerEnd = GetInstruction(offs + ehReader.ReadByte()); - if (eh.HandlerType == ExceptionHandlerType.Catch) + if (eh.IsCatch) eh.CatchType = opResolver.ResolveToken(ehReader.ReadUInt32(), gpContext) as ITypeDefOrRef; - else if (eh.HandlerType == ExceptionHandlerType.Filter) + else if (eh.IsFilter) eh.FilterStart = GetInstruction(ehReader.ReadUInt32()); else ehReader.ReadUInt32(); diff --git a/src/DotNet/Emit/MethodBodyReaderBase.cs b/src/DotNet/Emit/MethodBodyReaderBase.cs index dc2aee896..fd81be924 100644 --- a/src/DotNet/Emit/MethodBodyReaderBase.cs +++ b/src/DotNet/Emit/MethodBodyReaderBase.cs @@ -513,7 +513,7 @@ protected bool Add(ExceptionHandler eh) { if (handlerEnd <= handlerStart) return false; - if (eh.HandlerType == ExceptionHandlerType.Filter) { + if (eh.IsFilter) { if (eh.FilterStart is null) return false; if (eh.FilterStart.Offset >= handlerStart) diff --git a/src/DotNet/Writer/MaxStackCalculator.cs b/src/DotNet/Writer/MaxStackCalculator.cs index 621d97f0a..ea745e2d6 100644 --- a/src/DotNet/Writer/MaxStackCalculator.cs +++ b/src/DotNet/Writer/MaxStackCalculator.cs @@ -77,7 +77,7 @@ internal bool Calculate(out uint maxStack) { currentMaxStack = 1; } if ((instr = eh.HandlerStart) is not null) { - bool pushed = eh.HandlerType == ExceptionHandlerType.Catch || eh.HandlerType == ExceptionHandlerType.Filter; + bool pushed = eh.IsCatch || eh.IsFilter; if (pushed) { stackHeights[instr] = 1; currentMaxStack = 1; diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index f4dabe9b2..dcdafb88e 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -265,9 +265,9 @@ byte[] WriteFatExceptionClauses() { writer.WriteUInt32(offs1); writer.WriteUInt32(offs2 - offs1); - if (eh.HandlerType == ExceptionHandlerType.Catch) + if (eh.IsCatch) writer.WriteUInt32(helper.GetToken(eh.CatchType).Raw); - else if (eh.HandlerType == ExceptionHandlerType.Filter) + else if (eh.IsFilter) writer.WriteUInt32(GetOffset2(eh.FilterStart)); else writer.WriteInt32(0); @@ -310,9 +310,9 @@ byte[] WriteSmallExceptionClauses() { writer.WriteUInt16((ushort)offs1); writer.WriteByte((byte)(offs2 - offs1)); - if (eh.HandlerType == ExceptionHandlerType.Catch) + if (eh.IsCatch) writer.WriteUInt32(helper.GetToken(eh.CatchType).Raw); - else if (eh.HandlerType == ExceptionHandlerType.Filter) + else if (eh.IsFilter) writer.WriteUInt32(GetOffset2(eh.FilterStart)); else writer.WriteInt32(0); From c2845c6b2922be9297deea16b27aa052b3d650f9 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:58:02 +0100 Subject: [PATCH 416/511] Update `CustomAttributeType` coded token table --- src/DotNet/MD/CodedToken.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DotNet/MD/CodedToken.cs b/src/DotNet/MD/CodedToken.cs index 3e3f7495e..a77f4f452 100644 --- a/src/DotNet/MD/CodedToken.cs +++ b/src/DotNet/MD/CodedToken.cs @@ -64,8 +64,8 @@ public sealed class CodedToken { }); /// CustomAttributeType coded token - public static readonly CodedToken CustomAttributeType = new CodedToken(3, new Table[4] { - 0, 0, Table.Method, Table.MemberRef, + public static readonly CodedToken CustomAttributeType = new CodedToken(3, new Table[5] { + 0, 0, Table.Method, Table.MemberRef, 0, }); /// ResolutionScope coded token From 92c17da091c16b6614f7d1f19b65fe94a5397b2a Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:58:14 +0100 Subject: [PATCH 417/511] Add `Metadata.GetLocal{Variable,Constant}RidList()` --- src/DotNet/MD/CompressedMetadata.cs | 6 ++++++ src/DotNet/MD/ENCMetadata.cs | 14 ++++++-------- src/DotNet/MD/Metadata.cs | 14 ++++++++++++++ src/DotNet/MD/MetadataBase.cs | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index 50f2b0f7f..18c78cd59 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -118,6 +118,12 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui /// public override RidList GetPropertyRidList(uint propertyMapRid) => GetRidList(tablesStream.PropertyMapTable, propertyMapRid, 1, tablesStream.PropertyTable); + /// + public override RidList GetLocalVariableRidList(uint localScopeRid) => GetRidList(tablesStream.LocalScopeTable, localScopeRid, 2, tablesStream.LocalVariableTable); + + /// + public override RidList GetLocalConstantRidList(uint localScopeRid) => GetRidList(tablesStream.LocalScopeTable, localScopeRid, 3, tablesStream.LocalConstantTable); + /// /// Gets a rid list (eg. field list) /// diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index ed8b4ccf9..6d7e7f4af 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -401,6 +401,12 @@ public override RidList GetPropertyRidList(uint propertyMapRid) { return RidList.Create(newList); } + /// + public override RidList GetLocalVariableRidList(uint localScopeRid) => GetRidList(tablesStream.LocalScopeTable, localScopeRid, 2, tablesStream.LocalVariableTable); + + /// + public override RidList GetLocalConstantRidList(uint localScopeRid) => GetRidList(tablesStream.LocalScopeTable, localScopeRid, 3, tablesStream.LocalConstantTable); + /// /// Gets a rid list (eg. field list) /// @@ -447,14 +453,6 @@ protected override uint BinarySearch(MDTable tableSource, int keyColIndex, uint return 0; } - /// - /// Linear searches the table (O(n)) for a rid whose key column at index - /// is equal to . - /// - /// Table to search - /// Key column index - /// Key - /// The rid of the found row, or 0 if none found uint LinearSearch(MDTable tableSource, int keyColIndex, uint key) { if (tableSource is null) return 0; diff --git a/src/DotNet/MD/Metadata.cs b/src/DotNet/MD/Metadata.cs index 7359cad75..6d2501198 100644 --- a/src/DotNet/MD/Metadata.cs +++ b/src/DotNet/MD/Metadata.cs @@ -334,6 +334,20 @@ public abstract class Metadata : IDisposable { /// A instance containing the valid LocalScope rids public abstract RidList GetLocalScopeRidList(uint methodRid); + /// + /// Finds all LocalVariable rids owned by + /// + /// Owner LocalScope rid + /// A instance containing the valid LocalVariable rids + public abstract RidList GetLocalVariableRidList(uint localScopeRid); + + /// + /// Finds all LocalConstant rids owned by + /// + /// Owner LocalScope rid + /// A instance containing the valid LocalConstant rids + public abstract RidList GetLocalConstantRidList(uint localScopeRid); + /// /// Gets the StateMachineMethod rid or 0 if it's not a state machine method /// diff --git a/src/DotNet/MD/MetadataBase.cs b/src/DotNet/MD/MetadataBase.cs index c770c2e9a..9e6e11530 100644 --- a/src/DotNet/MD/MetadataBase.cs +++ b/src/DotNet/MD/MetadataBase.cs @@ -361,7 +361,7 @@ public override uint GetClassLayoutRid(uint typeDefRid) { return list.Count == 0 ? 0 : list[0]; } - override public uint GetFieldLayoutRid(uint fieldRid) { + public override uint GetFieldLayoutRid(uint fieldRid) { var list = FindAllRowsUnsorted(tablesStream.FieldLayoutTable, 1, fieldRid); return list.Count == 0 ? 0 : list[0]; } From abb9fd67f91f9f2d6b2b74d9552024590d9d93a0 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:58:31 +0100 Subject: [PATCH 418/511] `TypeDef` with rid 1 can't be a deleted type --- src/DotNet/MD/ENCMetadata.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 6d7e7f4af..986e94975 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -195,7 +195,8 @@ public override RidList GetTypeDefRidList() { // RTSpecialName is ignored by the CLR. It's only the name that indicates // whether it's been deleted. - if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) + // It's not possible to delete the global type () + if (rid != 1 && stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) continue; // ignore this deleted row list.Add(rid); } From 9a7f7f7a3ee7cfa14c19d3644ddf6dd397759474 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:58:46 +0100 Subject: [PATCH 419/511] Support `#JTD` heap, closes #424 --- src/DotNet/MD/CompressedMetadata.cs | 12 +++++++++-- src/DotNet/MD/DotNetTableSizes.cs | 32 +++++++++++++++++++++-------- src/DotNet/MD/ENCMetadata.cs | 13 ++++++++++-- src/DotNet/MD/TablesStream.cs | 12 +++++++++-- src/DotNet/Writer/TablesHeap.cs | 11 +++++++++- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/DotNet/MD/CompressedMetadata.cs b/src/DotNet/MD/CompressedMetadata.cs index 18c78cd59..680620558 100644 --- a/src/DotNet/MD/CompressedMetadata.cs +++ b/src/DotNet/MD/CompressedMetadata.cs @@ -31,6 +31,7 @@ internal CompressedMetadata(MetadataHeader mdHeader, bool isStandalonePortablePd protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset) { DotNetStream dns = null; var newAllStreams = new List(allStreams); + bool forceAllBig = false; try { for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--) { var sh = mdHeader.StreamHeaders[i]; @@ -82,6 +83,13 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui continue; } break; + + case "#JTD": + if (runtime == CLRRuntimeReaderKind.Mono) { + forceAllBig = true; + continue; + } + break; } dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(dns); @@ -98,9 +106,9 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui throw new BadImageFormatException("Missing MD stream"); if (pdbStream is not null) - tablesStream.Initialize(pdbStream.TypeSystemTableRows); + tablesStream.Initialize(pdbStream.TypeSystemTableRows, forceAllBig); else - tablesStream.Initialize(null); + tablesStream.Initialize(null, forceAllBig); } /// diff --git a/src/DotNet/MD/DotNetTableSizes.cs b/src/DotNet/MD/DotNetTableSizes.cs index 562451079..26ea002c7 100644 --- a/src/DotNet/MD/DotNetTableSizes.cs +++ b/src/DotNet/MD/DotNetTableSizes.cs @@ -11,6 +11,7 @@ public sealed class DotNetTableSizes { bool bigStrings; bool bigGuid; bool bigBlob; + bool forceAllBig; TableInfo[] tableInfos; internal static bool IsSystemTable(Table table) => table < Table.Document; @@ -23,10 +24,23 @@ public sealed class DotNetTableSizes { /// true if #Blob size >= 0x10000 /// Count of rows in each table /// Count of rows in each table (debug tables) - public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList systemRowCounts, IList debugRowCounts) { - this.bigStrings = bigStrings; - this.bigGuid = bigGuid; - this.bigBlob = bigBlob; + public void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList systemRowCounts, IList debugRowCounts) => + InitializeSizes(bigStrings, bigGuid, bigBlob, systemRowCounts, debugRowCounts, false); + + /// + /// Initializes the table sizes + /// + /// true if #Strings size >= 0x10000 + /// true if #GUID size >= 0x10000 + /// true if #Blob size >= 0x10000 + /// Count of rows in each table + /// Count of rows in each table (debug tables) + /// Force all columns to 4 bytes instead of 2 or 4 bytes + internal void InitializeSizes(bool bigStrings, bool bigGuid, bool bigBlob, IList systemRowCounts, IList debugRowCounts, bool forceAllBig) { + this.bigStrings = bigStrings || forceAllBig; + this.bigGuid = bigGuid || forceAllBig; + this.bigBlob = bigBlob || forceAllBig; + this.forceAllBig = forceAllBig; foreach (var tableInfo in tableInfos) { var rowCounts = IsSystemTable(tableInfo.Table) ? systemRowCounts : debugRowCounts; int colOffset = 0; @@ -44,7 +58,7 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { if (ColumnSize.Module <= columnSize && columnSize <= ColumnSize.CustomDebugInformation) { int table = (int)(columnSize - ColumnSize.Module); uint count = table >= rowCounts.Count ? 0 : rowCounts[table]; - return count > 0xFFFF ? 4 : 2; + return forceAllBig || count > 0xFFFF ? 4 : 2; } else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.HasCustomDebugInformation) { var info = columnSize switch { @@ -73,7 +87,7 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { } // Can't overflow since maxRows <= 0x00FFFFFF and info.Bits < 8 uint finalRows = maxRows << info.Bits; - return finalRows > 0xFFFF ? 4 : 2; + return forceAllBig || finalRows > 0xFFFF ? 4 : 2; } else { switch (columnSize) { @@ -82,9 +96,9 @@ int GetSize(ColumnSize columnSize, IList rowCounts) { case ColumnSize.UInt16: return 2; case ColumnSize.Int32: return 4; case ColumnSize.UInt32: return 4; - case ColumnSize.Strings:return bigStrings ? 4 : 2; - case ColumnSize.GUID: return bigGuid ? 4 : 2; - case ColumnSize.Blob: return bigBlob ? 4 : 2; + case ColumnSize.Strings:return forceAllBig || bigStrings ? 4 : 2; + case ColumnSize.GUID: return forceAllBig || bigGuid ? 4 : 2; + case ColumnSize.Blob: return forceAllBig || bigBlob ? 4 : 2; } } throw new InvalidOperationException($"Invalid ColumnSize: {columnSize}"); diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 986e94975..701e49cce 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -39,6 +39,7 @@ internal ENCMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb, CLRR /// protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset) { DotNetStream dns = null; + bool forceAllBig = false; try { if (runtime == CLRRuntimeReaderKind.Mono) { var newAllStreams = new List(allStreams); @@ -93,6 +94,10 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui continue; } break; + + case "#JTD": + forceAllBig = true; + continue; } dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); newAllStreams.Add(dns); @@ -155,6 +160,10 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui continue; } break; + + case "#JTD": + forceAllBig = true; + continue; } dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); allStreams.Add(dns); @@ -170,9 +179,9 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui throw new BadImageFormatException("Missing MD stream"); if (pdbStream is not null) - tablesStream.Initialize(pdbStream.TypeSystemTableRows); + tablesStream.Initialize(pdbStream.TypeSystemTableRows, forceAllBig); else - tablesStream.Initialize(null); + tablesStream.Initialize(null, forceAllBig); // The pointer tables are used iff row count != 0 hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty; diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 0f52e1289..1d22dd5a8 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -198,7 +198,15 @@ public TablesStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, /// Initializes MD tables /// /// Type system table rows (from #Pdb stream) - public void Initialize(uint[] typeSystemTableRows) { + public void Initialize(uint[] typeSystemTableRows) => + Initialize(typeSystemTableRows, false); + + /// + /// Initializes MD tables + /// + /// Type system table rows (from #Pdb stream) + /// Force all columns to 4 bytes instead of 2 or 4 bytes + internal void Initialize(uint[] typeSystemTableRows, bool forceAllBig) { if (initialized) throw new Exception("Initialize() has already been called"); initialized = true; @@ -245,7 +253,7 @@ public void Initialize(uint[] typeSystemTableRows) { } } - dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes, debugSizes); + dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes, debugSizes, forceAllBig); mdTablesPos = reader.Position; InitializeMdTableReaders(); diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index 727977f8e..c79ac83a8 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -34,6 +34,15 @@ public sealed class TablesHeapOptions { /// public bool? UseENC; + /// + /// All columns that can be 2 or 4 bytes are forced to be 4 bytes. + /// Set this to true if you add a #JTD heap and (if CLR) a #- tables heap is used + /// or (if Mono/Unity) a #~ or #- tables heap is used. + /// dnlib won't try to auto detect this from your added heaps since the CLR/CoreCLR vs Mono/Unity behavior + /// is a little bit different. You may need to set to true if you target CLR/CoreCLR. + /// + public bool? ForceBigColumns; + /// /// Extra data to write /// @@ -341,7 +350,7 @@ public void CalculateLength() { var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion); var rowCounts = GetRowCounts(); - dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, systemTables ?? rowCounts, rowCounts); + dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, systemTables ?? rowCounts, rowCounts, options.ForceBigColumns ?? false); for (int i = 0; i < Tables.Length; i++) Tables[i].TableInfo = tableInfos[i]; From 2d1a918d2af9d5231f232f99a326a9c5729423e4 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:58:55 +0100 Subject: [PATCH 420/511] Better mono support --- src/DotNet/MD/ENCMetadata.cs | 53 +++++++++++++++++++++++++---------- src/DotNet/MD/TablesStream.cs | 11 +++++++- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/DotNet/MD/ENCMetadata.cs b/src/DotNet/MD/ENCMetadata.cs index 701e49cce..5e8645f1e 100644 --- a/src/DotNet/MD/ENCMetadata.cs +++ b/src/DotNet/MD/ENCMetadata.cs @@ -14,7 +14,8 @@ namespace dnlib.DotNet.MD { sealed class ENCMetadata : MetadataBase { static readonly UTF8String DeletedName = "_Deleted"; bool hasMethodPtr, hasFieldPtr, hasParamPtr, hasEventPtr, hasPropertyPtr; - bool hasDeletedRows; + bool hasDeletedFields; + bool hasDeletedNonFields; readonly CLRRuntimeReaderKind runtime; readonly Dictionary sortedTables = new Dictionary(); #if THREAD_SAFE @@ -189,12 +190,26 @@ protected override void InitializeInternal(DataReaderFactory mdReaderFactory, ui hasParamPtr = !tablesStream.ParamPtrTable.IsEmpty; hasEventPtr = !tablesStream.EventPtrTable.IsEmpty; hasPropertyPtr = !tablesStream.PropertyPtrTable.IsEmpty; - hasDeletedRows = tablesStream.HasDelete; + + switch (runtime) { + case CLRRuntimeReaderKind.CLR: + hasDeletedFields = tablesStream.HasDelete; + hasDeletedNonFields = tablesStream.HasDelete; + break; + + case CLRRuntimeReaderKind.Mono: + hasDeletedFields = true; + hasDeletedNonFields = false; + break; + + default: + throw new InvalidOperationException(); + } } /// public override RidList GetTypeDefRidList() { - if (!hasDeletedRows) + if (!hasDeletedNonFields) return base.GetTypeDefRidList(); uint rows = tablesStream.TypeDefTable.Rows; var list = new List((int)rows); @@ -214,7 +229,7 @@ public override RidList GetTypeDefRidList() { /// public override RidList GetExportedTypeRidList() { - if (!hasDeletedRows) + if (!hasDeletedNonFields) return base.GetExportedTypeRidList(); uint rows = tablesStream.ExportedTypeTable.Rows; var list = new List((int)rows); @@ -289,7 +304,7 @@ uint ToPropertyRid(uint listRid) { /// public override RidList GetFieldRidList(uint typeDefRid) { var list = GetRidList(tablesStream.TypeDefTable, typeDefRid, 4, tablesStream.FieldTable); - if (list.Count == 0 || (!hasFieldPtr && !hasDeletedRows)) + if (list.Count == 0 || (!hasFieldPtr && !hasDeletedFields)) return list; var destTable = tablesStream.FieldTable; @@ -298,13 +313,21 @@ public override RidList GetFieldRidList(uint typeDefRid) { var rid = ToFieldRid(list[i]); if (destTable.IsInvalidRID(rid)) continue; - if (hasDeletedRows) { + if (hasDeletedFields) { // It's a deleted row if RTSpecialName is set and name is "_Deleted" if (!tablesStream.TryReadFieldRow(rid, out var row)) continue; // Should never happen since rid is valid - if ((row.Flags & (uint)FieldAttributes.RTSpecialName) != 0) { - if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) - continue; // ignore this deleted row + if (runtime == CLRRuntimeReaderKind.CLR) { + if ((row.Flags & (uint)FieldAttributes.RTSpecialName) != 0) { + if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) + continue; // ignore this deleted row + } + } + else { + if ((row.Flags & (uint)(FieldAttributes.SpecialName | FieldAttributes.RTSpecialName)) == (uint)(FieldAttributes.SpecialName | FieldAttributes.RTSpecialName)) { + if (stringsStream.ReadNoNull(row.Name) == DeletedName) + continue; // ignore this deleted row + } } } // It's a valid non-deleted rid so add it @@ -316,7 +339,7 @@ public override RidList GetFieldRidList(uint typeDefRid) { /// public override RidList GetMethodRidList(uint typeDefRid) { var list = GetRidList(tablesStream.TypeDefTable, typeDefRid, 5, tablesStream.MethodTable); - if (list.Count == 0 || (!hasMethodPtr && !hasDeletedRows)) + if (list.Count == 0 || (!hasMethodPtr && !hasDeletedNonFields)) return list; var destTable = tablesStream.MethodTable; @@ -325,7 +348,7 @@ public override RidList GetMethodRidList(uint typeDefRid) { var rid = ToMethodRid(list[i]); if (destTable.IsInvalidRID(rid)) continue; - if (hasDeletedRows) { + if (hasDeletedNonFields) { // It's a deleted row if RTSpecialName is set and name is "_Deleted" if (!tablesStream.TryReadMethodRow(rid, out var row)) continue; // Should never happen since rid is valid @@ -360,7 +383,7 @@ public override RidList GetParamRidList(uint methodRid) { /// public override RidList GetEventRidList(uint eventMapRid) { var list = GetRidList(tablesStream.EventMapTable, eventMapRid, 1, tablesStream.EventTable); - if (list.Count == 0 || (!hasEventPtr && !hasDeletedRows)) + if (list.Count == 0 || (!hasEventPtr && !hasDeletedNonFields)) return list; var destTable = tablesStream.EventTable; @@ -369,7 +392,7 @@ public override RidList GetEventRidList(uint eventMapRid) { var rid = ToEventRid(list[i]); if (destTable.IsInvalidRID(rid)) continue; - if (hasDeletedRows) { + if (hasDeletedNonFields) { // It's a deleted row if RTSpecialName is set and name is "_Deleted" if (!tablesStream.TryReadEventRow(rid, out var row)) continue; // Should never happen since rid is valid @@ -387,7 +410,7 @@ public override RidList GetEventRidList(uint eventMapRid) { /// public override RidList GetPropertyRidList(uint propertyMapRid) { var list = GetRidList(tablesStream.PropertyMapTable, propertyMapRid, 1, tablesStream.PropertyTable); - if (list.Count == 0 || (!hasPropertyPtr && !hasDeletedRows)) + if (list.Count == 0 || (!hasPropertyPtr && !hasDeletedNonFields)) return list; var destTable = tablesStream.PropertyTable; @@ -396,7 +419,7 @@ public override RidList GetPropertyRidList(uint propertyMapRid) { var rid = ToPropertyRid(list[i]); if (destTable.IsInvalidRID(rid)) continue; - if (hasDeletedRows) { + if (hasDeletedNonFields) { // It's a deleted row if RTSpecialName is set and name is "_Deleted" if (!tablesStream.TryReadPropertyRow(rid, out var row)) continue; // Should never happen since rid is valid diff --git a/src/DotNet/MD/TablesStream.cs b/src/DotNet/MD/TablesStream.cs index 1d22dd5a8..3e291ef2b 100644 --- a/src/DotNet/MD/TablesStream.cs +++ b/src/DotNet/MD/TablesStream.cs @@ -219,9 +219,18 @@ internal void Initialize(uint[] typeSystemTableRows, bool forceAllBig) { log2Rid = reader.ReadByte(); validMask = reader.ReadUInt64(); sortedMask = reader.ReadUInt64(); + // Mono assumes everything is sorted + if (runtime == CLRRuntimeReaderKind.Mono) + sortedMask = ulong.MaxValue; var dnTableSizes = new DotNetTableSizes(); - var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out int maxPresentTables); + byte tmpMajor = majorVersion, tmpMinor = minorVersion; + // It ignores the version so use 2.0 + if (runtime == CLRRuntimeReaderKind.Mono) { + tmpMajor = 2; + tmpMinor = 0; + } + var tableInfos = dnTableSizes.CreateTables(tmpMajor, tmpMinor, out int maxPresentTables); if (typeSystemTableRows is not null) maxPresentTables = DotNetTableSizes.normalMaxTables; mdTables = new MDTable[tableInfos.Length]; From b656bf922a57c6a39a7f50b8c07a8d424013c15c Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 16:59:02 +0100 Subject: [PATCH 421/511] Update `InterfaceImpl` sorting, closes #426 --- src/DotNet/Writer/Metadata.cs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 16ee86056..15fdd4092 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2,16 +2,16 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.Linq; using System.Text; -using dnlib.IO; -using dnlib.PE; -using dnlib.DotNet.MD; using dnlib.DotNet.Emit; -using System.Diagnostics; +using dnlib.DotNet.MD; using dnlib.DotNet.Pdb; using dnlib.DotNet.Pdb.Portable; -using System.Linq; +using dnlib.IO; +using dnlib.PE; namespace dnlib.DotNet.Writer { /// @@ -158,6 +158,7 @@ public enum MetadataFlags : uint { AlwaysCreateBlobHeap = 0x80000, /// + /// DEPRECATED: /// Sort the InterfaceImpl table the same way Roslyn sorts it. Roslyn doesn't sort it /// according to the ECMA spec, see https://github.com/dotnet/roslyn/issues/3905 /// @@ -1822,15 +1823,7 @@ void SortTables() { return a.row.Owner.CompareTo(b.row.Owner); return a.row.Number.CompareTo(b.row.Number); }); - if (RoslynSortInterfaceImpl) - interfaceImplInfos.Sort((a, b) => a.row.Class.CompareTo(b.row.Class)); - else { - interfaceImplInfos.Sort((a, b) => { - if (a.row.Class != b.row.Class) - return a.row.Class.CompareTo(b.row.Class); - return a.row.Interface.CompareTo(b.row.Interface); - }); - } + interfaceImplInfos.Sort((a, b) => a.row.Class.CompareTo(b.row.Class)); tablesHeap.ClassLayoutTable.IsSorted = true; tablesHeap.ConstantTable.IsSorted = true; From 873ba1a77e58a5d60767c66ce9e55f442fbdfff5 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 17:00:08 +0100 Subject: [PATCH 422/511] Support arm64 dia sym readers/writers --- src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 8a243ba3b..93097c95d 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -24,6 +24,10 @@ static class SymbolReaderWriterFactory { [DllImport("Microsoft.DiaSymReader.Native.arm.dll", EntryPoint = "CreateSymReader")] static extern void CreateSymReader_arm(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object symReader); + [DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)] + [DllImport("Microsoft.DiaSymReader.Native.arm64.dll", EntryPoint = "CreateSymReader")] + static extern void CreateSymReader_arm64(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object symReader); + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] [DllImport("Microsoft.DiaSymReader.Native.x86.dll", EntryPoint = "CreateSymWriter")] static extern void CreateSymWriter_x86(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object symWriter); @@ -36,6 +40,10 @@ static class SymbolReaderWriterFactory { [DllImport("Microsoft.DiaSymReader.Native.arm.dll", EntryPoint = "CreateSymWriter")] static extern void CreateSymWriter_arm(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object symWriter); + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] + [DllImport("Microsoft.DiaSymReader.Native.arm64.dll", EntryPoint = "CreateSymWriter")] + static extern void CreateSymWriter_arm64(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object symWriter); + static readonly Guid CLSID_CorSymReader_SxS = new Guid("0A3976C5-4529-4ef8-B0B0-42EED37082CD"); static Type CorSymReader_Type; @@ -116,6 +124,10 @@ static ISymUnmanagedReader CreateSymUnmanagedReader(PdbReaderOptions options) { CreateSymReader_arm(ref guid, out symReaderObj); break; + case Machine.ARM64: + CreateSymReader_arm64(ref guid, out symReaderObj); + break; + default: Debug.Fail($"Microsoft.DiaSymReader.Native doesn't support this CPU arch: {machine}"); symReaderObj = null; @@ -160,6 +172,10 @@ static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2(PdbWriterOptions options) CreateSymWriter_arm(ref guid, out symWriterObj); break; + case Machine.ARM64: + CreateSymWriter_arm64(ref guid, out symWriterObj); + break; + default: Debug.Fail($"Microsoft.DiaSymReader.Native doesn't support this CPU arch: {machine}"); symWriterObj = null; From 49a0384f8bfac5fd405aeb6b7978a1edb206821c Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 19:53:56 +0100 Subject: [PATCH 423/511] Add `allowTypeSpec` arg to `ReadType()` --- src/DotNet/SignatureReader.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 1792bfa4c..3c5caa3cd 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -429,8 +429,8 @@ CallingConventionSig ReadSig() { case CallingConvention.ThisCall: case CallingConvention.FastCall: case CallingConvention.VarArg: - case CallingConvention.NativeVarArg: case CallingConvention.Unmanaged: + case CallingConvention.NativeVarArg: result = ReadMethod(callingConvention); break; @@ -540,8 +540,9 @@ GenericInstMethodSig ReadGenericInstMethod(CallingConvention callingConvention) /// /// Reads the next type /// + /// true if a TypeSpec is allowed if the next type is a class/value-type /// A new instance or null if invalid element type - TypeSig ReadType() { + TypeSig ReadType(bool allowTypeSpec = false) { if (!recursionCounter.Increment()) return null; @@ -569,8 +570,8 @@ TypeSig ReadType() { case ElementType.Ptr: result = new PtrSig(ReadType()); break; case ElementType.ByRef: result = new ByRefSig(ReadType()); break; - case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef(false)); break; - case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef(false)); break; + case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef(allowTypeSpec)); break; + case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef(allowTypeSpec)); break; case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break; case ElementType.SZArray: result = new SZArraySig(ReadType()); break; case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(true), ReadType()); break; From c8b150f527be7d7ec321d7cc209165a287c5cf6f Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 19:54:05 +0100 Subject: [PATCH 424/511] Use `Metadata.GetLocal{Variable,Constant}RidList()` --- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 49 ++++---------------- src/DotNet/Pdb/Portable/SymbolScopeImpl.cs | 14 +++--- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index 105df8038..fc8fdec37 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -245,9 +245,8 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { parent.childrenList.Add(scope); scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext); - GetEndOfLists(rid, out uint variableListEnd, out uint constantListEnd); - ReadVariables(scope, gpContext, row.VariableList, variableListEnd); - ReadConstants(scope, row.ConstantList, constantListEnd); + ReadVariables(scope, gpContext, pdbMetadata.GetLocalVariableRidList(rid)); + ReadConstants(scope, pdbMetadata.GetLocalConstantRidList(rid)); } ListCache.Free(ref stack); @@ -256,18 +255,6 @@ SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext) { return rootScopeOrNull ?? new SymbolScopeImpl(this, null, 0, int.MaxValue, Array2.Empty()); } - void GetEndOfLists(uint scopeRid, out uint variableListEnd, out uint constantListEnd) { - var nextRid = scopeRid + 1; - if (!pdbMetadata.TablesStream.TryReadLocalScopeRow(nextRid, out var row)) { - variableListEnd = pdbMetadata.TablesStream.LocalVariableTable.Rows + 1; - constantListEnd = pdbMetadata.TablesStream.LocalConstantTable.Rows + 1; - } - else { - variableListEnd = row.VariableList; - constantListEnd = row.ConstantList; - } - } - PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope, GenericParamContext gpContext) { if (importScope == 0) return null; @@ -295,21 +282,13 @@ PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReade return result; } - void ReadVariables(SymbolScopeImpl scope, GenericParamContext gpContext, uint variableList, uint variableListEnd) { - if (variableList == 0) - return; - Debug.Assert(variableList <= variableListEnd); - if (variableList >= variableListEnd) + void ReadVariables(SymbolScopeImpl scope, GenericParamContext gpContext, RidList rids) { + if (rids.Count == 0) return; var table = pdbMetadata.TablesStream.LocalVariableTable; - Debug.Assert(table.IsValidRID(variableListEnd - 1)); - if (!table.IsValidRID(variableListEnd - 1)) - return; - Debug.Assert(table.IsValidRID(variableList)); - if (!table.IsValidRID(variableList)) - return; var custInfos = ListCache.AllocList(); - for (uint rid = variableList; rid < variableListEnd; rid++) { + for (int i = 0; i < rids.Count; i++) { + var rid = rids[i]; int token = new MDToken(Table.LocalVariable, rid).ToInt32(); custInfos.Clear(); GetCustomDebugInfos(token, gpContext, custInfos); @@ -330,20 +309,10 @@ static PdbLocalAttributes ToSymbolVariableAttributes(ushort attributes) { return res; } - void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEnd) { - if (constantList == 0) - return; - Debug.Assert(constantList <= constantListEnd); - if (constantList >= constantListEnd) - return; - var table = pdbMetadata.TablesStream.LocalConstantTable; - Debug.Assert(table.IsValidRID(constantListEnd - 1)); - if (!table.IsValidRID(constantListEnd - 1)) - return; - Debug.Assert(table.IsValidRID(constantList)); - if (!table.IsValidRID(constantList)) + void ReadConstants(SymbolScopeImpl scope, RidList rids) { + if (rids.Count == 0) return; - scope.SetConstants(pdbMetadata, constantList, constantListEnd); + scope.SetConstants(pdbMetadata, rids); } internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList result) { diff --git a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs index f93bcf584..cc90eebe1 100644 --- a/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolScopeImpl.cs @@ -54,24 +54,22 @@ public SymbolScopeImpl(PortablePdbReader owner, SymbolScopeImpl parent, int star } Metadata constantsMetadata; - uint constantList; - uint constantListEnd; + RidList constantRidList; - internal void SetConstants(Metadata metadata, uint constantList, uint constantListEnd) { + internal void SetConstants(Metadata metadata, RidList rids) { constantsMetadata = metadata; - this.constantList = constantList; - this.constantListEnd = constantListEnd; + constantRidList = rids; } public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { - if (constantList >= constantListEnd) + if (constantRidList.Count == 0) return Array2.Empty(); Debug.Assert(constantsMetadata is not null); - var res = new PdbConstant[constantListEnd - constantList]; + var res = new PdbConstant[constantRidList.Count]; int w = 0; for (int i = 0; i < res.Length; i++) { - uint rid = constantList + (uint)i; + uint rid = constantRidList[i]; bool b = constantsMetadata.TablesStream.TryReadLocalConstantRow(rid, out var row); Debug.Assert(b); var name = constantsMetadata.StringsStream.Read(row.Name); From 086cda2c737f34b3085f1d30a970e4adfb421ae3 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Mon, 6 Dec 2021 20:00:48 +0100 Subject: [PATCH 425/511] Remove old EH count code --- src/DotNet/Emit/MethodBodyReader.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/DotNet/Emit/MethodBodyReader.cs b/src/DotNet/Emit/MethodBodyReader.cs index 8a2c68625..232c73e6d 100644 --- a/src/DotNet/Emit/MethodBodyReader.cs +++ b/src/DotNet/Emit/MethodBodyReader.cs @@ -478,14 +478,9 @@ void ReadExceptionHandlers(out uint totalBodySize) { totalBodySize = 0; } - static ushort GetNumberOfExceptionHandlers(uint num) { - // The CLR truncates the count so num handlers is always <= FFFFh. - return (ushort)num; - } - void ReadFatExceptionHandlers(ref DataReader ehReader) { ehReader.Position--; - int num = GetNumberOfExceptionHandlers((ehReader.ReadUInt32() >> 8) / 24); + int num = (int)((ehReader.ReadUInt32() >> 8) / 24); for (int i = 0; i < num; i++) { var eh = new ExceptionHandler((ExceptionHandlerType)ehReader.ReadUInt32()); uint offs = ehReader.ReadUInt32(); @@ -505,7 +500,7 @@ void ReadFatExceptionHandlers(ref DataReader ehReader) { } void ReadSmallExceptionHandlers(ref DataReader ehReader) { - int num = GetNumberOfExceptionHandlers((uint)ehReader.ReadByte() / 12); + int num = (int)((uint)ehReader.ReadByte() / 12); ehReader.Position += 2; for (int i = 0; i < num; i++) { var eh = new ExceptionHandler((ExceptionHandlerType)ehReader.ReadUInt16()); From 66e4a912eef4dc000b176db1d693e7f2667d4088 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Tue, 14 Dec 2021 18:05:43 +0100 Subject: [PATCH 426/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index fd16a7556..82b90c200 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.3.5 + 3.4.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 1a117dd1ea2a316be8e0edba8f5ab99fbc75d6f9 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Thu, 16 Dec 2021 16:38:47 +0100 Subject: [PATCH 427/511] Update example to use `net6.0` --- Examples/Examples.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Examples.csproj b/Examples/Examples.csproj index 464ee1e49..3bd7f6613 100644 --- a/Examples/Examples.csproj +++ b/Examples/Examples.csproj @@ -1,7 +1,7 @@ - net5.0;net45 + net6.0;net45 Exe false latest From 78dadffc6557d217bc75d654e504c2996ccba01a Mon Sep 17 00:00:00 2001 From: wtfsck Date: Thu, 16 Dec 2021 16:38:55 +0100 Subject: [PATCH 428/511] Enable deterministic csproj properties --- src/dnlib.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 82b90c200..3e515a707 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -30,8 +30,10 @@ strict;nullablePublicOnly true true + true true snupkg + true Reads and writes .NET assemblies and modules, Windows PDBs and Portable PDBs. @@ -47,6 +49,10 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof true + + true + + From 66e41059fd0860f396e9f3eaa2839b80b8b3441b Mon Sep 17 00:00:00 2001 From: wtfsck Date: Thu, 16 Dec 2021 16:43:21 +0100 Subject: [PATCH 429/511] Use .NET SDK 6.0.100 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 82573751e..19832323d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ on: types: released env: - CI_REQ_DOTNET_SDK_VER: 5.0.100 + CI_REQ_DOTNET_SDK_VER: 6.0.100 jobs: build-windows: From 842fc468f274202fe1a7cb1583202b4fc3d95cc9 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Wed, 29 Dec 2021 01:00:19 +0800 Subject: [PATCH 430/511] Update AssemblyRef.Attributes when updating AssemblyRef.PublicKeyOrToken (#437) * Update AssemblyRef.Attributes when updating AssemblyRef.PublicKeyOrToken * Update attibute outside --- src/DotNet/TypeNameParser.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/TypeNameParser.cs b/src/DotNet/TypeNameParser.cs index d84382004..30c2fa3ac 100644 --- a/src/DotNet/TypeNameParser.cs +++ b/src/DotNet/TypeNameParser.cs @@ -773,6 +773,7 @@ AssemblyRef ReadAssemblyRef() { asmRef.PublicKeyOrToken = new PublicKey(); else asmRef.PublicKeyOrToken = PublicKeyBase.CreatePublicKey(Utils.ParseBytes(value)); + asmRef.Attributes |= AssemblyAttributes.PublicKey; break; case "PUBLICKEYTOKEN": @@ -781,6 +782,7 @@ AssemblyRef ReadAssemblyRef() { asmRef.PublicKeyOrToken = new PublicKeyToken(); else asmRef.PublicKeyOrToken = PublicKeyBase.CreatePublicKeyToken(Utils.ParseBytes(value)); + asmRef.Attributes &= ~AssemblyAttributes.PublicKey; break; case "CULTURE": From 0c2a2dfffad263e45ad6ddb204ccaaf843ead9a0 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Wed, 29 Dec 2021 02:58:46 +0800 Subject: [PATCH 431/511] Fixes https://github.com/0xd4d/dnlib/issues/438 --- src/DotNet/TypeSpec.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/TypeSpec.cs b/src/DotNet/TypeSpec.cs index ec416ed0d..e7e82063f 100644 --- a/src/DotNet/TypeSpec.cs +++ b/src/DotNet/TypeSpec.cs @@ -310,7 +310,7 @@ protected override void InitializeCustomDebugInfos() { Interlocked.CompareExchange(ref customDebugInfos, list, null); } - bool IContainsGenericParameter2.ContainsGenericParameter => !gpContext.IsEmpty && ContainsGenericParameter; + bool IContainsGenericParameter2.ContainsGenericParameter => ContainsGenericParameter; /// /// Constructor From acf49eef8a4c5da892731afb7a75d2ae131d2013 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Wed, 29 Dec 2021 03:07:28 +0800 Subject: [PATCH 432/511] Fixes TypeHelper.ContainsGenericParameter(MethodSpec) --- src/DotNet/TypeHelper.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/DotNet/TypeHelper.cs b/src/DotNet/TypeHelper.cs index 83a670513..ddfe4d47c 100644 --- a/src/DotNet/TypeHelper.cs +++ b/src/DotNet/TypeHelper.cs @@ -13,14 +13,7 @@ struct TypeHelper { internal static bool ContainsGenericParameter(InterfaceImpl ii) => ii is not null && TypeHelper.ContainsGenericParameter(ii.Interface); internal static bool ContainsGenericParameter(GenericParamConstraint gpc) => gpc is not null && ContainsGenericParameter(gpc.Constraint); - internal static bool ContainsGenericParameter(MethodSpec ms) { - if (ms is null) - return false; - - // A normal MethodSpec should always contain generic arguments and thus - // its MethodDef is always a generic method with generic parameters. - return true; - } + internal static bool ContainsGenericParameter(MethodSpec ms) => ms is not null && ContainsGenericParameter(ms.GenericInstMethodSig); internal static bool ContainsGenericParameter(MemberRef mr) { if (mr is null) From 8ed982fc0760adb7597ffbf2f1cecfcd97d819a3 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Thu, 30 Dec 2021 03:01:48 +0800 Subject: [PATCH 433/511] Obfuscator may rename many methods/fields into same name then TryResolveMethod/TryResolveField will return inconsistent method/field. --- src/DotNet/Importer.cs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 06a533607..b453a9874 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -452,6 +452,14 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { if (methodBase is null) return null; + if (TryToUseMethodDefs && IsThisModule(methodBase.Module) && + !methodBase.IsGenericMethod && (methodBase.DeclaringType is null || !methodBase.DeclaringType.IsGenericType) && + module.ResolveToken(methodBase.MetadataToken) is MethodDef md) { + // In same module and method and declaring type are both non-generic, directly resolve method definition. + // Obfuscator may rename many methods into same name then TryResolveMethod will return inconsistent method. + return md; + } + if (forceFixSignature) { //TODO: } @@ -508,6 +516,8 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { } } + bool IsThisModule(Module module2) => module.Name == module2.Name && IsThisAssembly(module2); + MethodSig CreateMethodSig(MethodBase mb) { var sig = new MethodSig(GetCallingConvention(mb)); @@ -567,15 +577,17 @@ GenericInstMethodSig CreateGenericInstMethodSig(MethodBase mb) { } IMemberRefParent GetModuleParent(Module module2) { - // If we have no assembly, assume this is a netmodule in the same assembly as module - var modAsm = module.Assembly; - bool isSameAssembly = modAsm is null || - UTF8String.ToSystemStringOrEmpty(modAsm.Name).Equals(module2.Assembly.GetName().Name, StringComparison.OrdinalIgnoreCase); - if (!isSameAssembly) + if (!IsThisAssembly(module2)) return null; return module.UpdateRowId(new ModuleRefUser(module, module.Name)); } + bool IsThisAssembly(Module module2) { + // If we have no assembly, assume this is a netmodule in the same assembly as module + var modAsm = module.Assembly; + return modAsm is null || UTF8String.ToSystemStringOrEmpty(modAsm.Name).Equals(module2.Assembly.GetName().Name, StringComparison.OrdinalIgnoreCase); + } + /// /// Imports a as a /// @@ -597,6 +609,14 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { if (fieldInfo is null) return null; + if (TryToUseFieldDefs && IsThisModule(fieldInfo.Module) && + (fieldInfo.DeclaringType is null || !fieldInfo.DeclaringType.IsGenericType) && + module.ResolveToken(fieldInfo.MetadataToken) is FieldDef fd) { + // In same module and declaring type is non-generic, directly resolve field definition. + // Obfuscator may rename many fields into same name then TryResolveField will return inconsistent field. + return fd; + } + if (forceFixSignature) { //TODO: } From 217a2ff216d29cb7ba80287e2d115cee4613bafe Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Thu, 30 Dec 2021 13:15:29 +0800 Subject: [PATCH 434/511] Use Module.ScopeName and case insensitive comparison --- src/DotNet/Importer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index b453a9874..481964865 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -516,7 +516,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { } } - bool IsThisModule(Module module2) => module.Name == module2.Name && IsThisAssembly(module2); + bool IsThisModule(Module module2) => UTF8String.ToSystemStringOrEmpty(module.Name).Equals(module2.ScopeName, StringComparison.OrdinalIgnoreCase) && IsThisAssembly(module2); MethodSig CreateMethodSig(MethodBase mb) { var sig = new MethodSig(GetCallingConvention(mb)); From 936bb3b4b12916d897ce3469e0062458f6b1aca2 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Thu, 30 Dec 2021 15:02:13 +0800 Subject: [PATCH 435/511] Fix infinite loop in SigComparer.GetHashCode(TypeSig) --- src/DotNet/SigComparer.cs | 46 +++++++++++++++------------------------ 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 7d0f4ae85..28e739f02 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -1995,7 +1995,9 @@ static bool TokenEquals(ITypeDefOrRef a, ITypeDefOrRef b) { /// /// The type /// The hash code - public int GetHashCode(TypeSig a) { + public int GetHashCode(TypeSig a) => GetHashCode(a, true); + + int GetHashCode(TypeSig a, bool substituteGenericParameters) { // ******************************************** // IMPORTANT: This must match GetHashCode(Type) // ******************************************** @@ -2005,7 +2007,7 @@ public int GetHashCode(TypeSig a) { return 0; int hash; - if (genericArguments is not null) + if (substituteGenericParameters && genericArguments is not null) a = genericArguments.Resolve(a); switch (a.ElementType) { @@ -2039,15 +2041,15 @@ public int GetHashCode(TypeSig a) { break; case ElementType.Ptr: - hash = HASHCODE_MAGIC_ET_PTR + GetHashCode(a.Next); + hash = HASHCODE_MAGIC_ET_PTR + GetHashCode(a.Next, substituteGenericParameters); break; case ElementType.ByRef: - hash = HASHCODE_MAGIC_ET_BYREF + GetHashCode(a.Next); + hash = HASHCODE_MAGIC_ET_BYREF + GetHashCode(a.Next, substituteGenericParameters); break; case ElementType.SZArray: - hash = HASHCODE_MAGIC_ET_SZARRAY + GetHashCode(a.Next); + hash = HASHCODE_MAGIC_ET_SZARRAY + GetHashCode(a.Next, substituteGenericParameters); break; case ElementType.CModReqd: @@ -2055,14 +2057,14 @@ public int GetHashCode(TypeSig a) { case ElementType.Pinned: // When comparing an ExportedType/TypeDef/TypeRef to a ModifierSig/PinnedSig, // the ET is ignored, so we must ignore it when calculating the hash. - hash = GetHashCode(a.Next); + hash = GetHashCode(a.Next, substituteGenericParameters); break; case ElementType.Array: // Don't include sizes and lower bounds since GetHashCode(Type) doesn't (and can't). // Also, if IgnoreMultiDimensionArrayLowerBoundsAndSizes is set, we shouldn't include them either. var ara = (ArraySig)a; - hash = HASHCODE_MAGIC_ET_ARRAY + (int)ara.Rank + GetHashCode(ara.Next); + hash = HASHCODE_MAGIC_ET_ARRAY + (int)ara.Rank + GetHashCode(ara.Next, substituteGenericParameters); break; case ElementType.Var: @@ -2076,15 +2078,8 @@ public int GetHashCode(TypeSig a) { case ElementType.GenericInst: var gia = (GenericInstSig)a; hash = HASHCODE_MAGIC_ET_GENERICINST; - if (SubstituteGenericParameters) { - InitializeGenericArguments(); - genericArguments.PushTypeArgs(gia.GenericArguments); - hash += GetHashCode(gia.GenericType); - genericArguments.PopTypeArgs(); - } - else - hash += GetHashCode(gia.GenericType); - hash += GetHashCode(gia.GenericArguments); + hash += GetHashCode(gia.GenericType, false); + hash += GetHashCode(gia.GenericArguments, false); break; case ElementType.FnPtr: @@ -2092,11 +2087,11 @@ public int GetHashCode(TypeSig a) { break; case ElementType.ValueArray: - hash = HASHCODE_MAGIC_ET_VALUEARRAY + (int)(a as ValueArraySig).Size + GetHashCode(a.Next); + hash = HASHCODE_MAGIC_ET_VALUEARRAY + (int)(a as ValueArraySig).Size + GetHashCode(a.Next, substituteGenericParameters); break; case ElementType.Module: - hash = HASHCODE_MAGIC_ET_MODULE + (int)(a as ModuleSig).Index + GetHashCode(a.Next); + hash = HASHCODE_MAGIC_ET_MODULE + (int)(a as ModuleSig).Index + GetHashCode(a.Next, substituteGenericParameters); break; case ElementType.End: @@ -2146,7 +2141,9 @@ public bool Equals(IList a, IList b) { /// /// The type list /// The hash code - public int GetHashCode(IList a) { + public int GetHashCode(IList a) => GetHashCode(a, false); + + int GetHashCode(IList a, bool substituteGenericParameters) { //************************************************************************ // IMPORTANT: This code must match any other GetHashCode(IList) //************************************************************************ @@ -2156,7 +2153,7 @@ public int GetHashCode(IList a) { return 0; uint hash = 0; for (int i = 0; i < a.Count; i++) { - hash += (uint)GetHashCode(a[i]); + hash += (uint)GetHashCode(a[i], substituteGenericParameters); hash = (hash << 13) | (hash >> 19); } recursionCounter.Decrement(); @@ -3421,14 +3418,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { break; } var gia = (GenericInstSig)a; - if (SubstituteGenericParameters) { - InitializeGenericArguments(); - genericArguments.PushTypeArgs(gia.GenericArguments); - result = Equals(gia.GenericType, b.GetGenericTypeDefinition()); - genericArguments.PopTypeArgs(); - } - else - result = Equals(gia.GenericType, b.GetGenericTypeDefinition()); + result = Equals(gia.GenericType, b.GetGenericTypeDefinition()); result = result && Equals(gia.GenericArguments, b.GetGenericArguments()); break; From 8f0b9cac635b39ccd8a56be19da0ae38f7290c77 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 7 Jan 2022 19:03:46 +0100 Subject: [PATCH 436/511] Use RuntimeInformation class to check environment. --- src/IO/DataReaderFactoryFactory.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/IO/DataReaderFactoryFactory.cs b/src/IO/DataReaderFactoryFactory.cs index f8ad7e618..edc75daee 100644 --- a/src/IO/DataReaderFactoryFactory.cs +++ b/src/IO/DataReaderFactoryFactory.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using System.Runtime.InteropServices; namespace dnlib.IO { static class DataReaderFactoryFactory { @@ -12,6 +13,10 @@ static DataReaderFactoryFactory() { int p = (int)Environment.OSVersion.Platform; if (p == 4 || p == 6 || p == 128) isUnix = true; +#if NETSTANDARD + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + isUnix = true; +#endif } public static DataReaderFactory Create(string fileName, bool mapAsImage) { From f4e084ffd81df228978c92e24bd9d026f9291dbe Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Sat, 8 Jan 2022 13:38:00 -0600 Subject: [PATCH 437/511] Validate data in case allocate too many memory, fix #442 (#448) * Validate data in case allocate too many memory, fix #442 * Check BytesLeft * bgt => bge --- src/DotNet/CustomAttributeReader.cs | 4 +++- src/DotNet/MD/BlobStream.cs | 5 +++-- src/DotNet/SignatureReader.cs | 14 +++++++------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/DotNet/CustomAttributeReader.cs b/src/DotNet/CustomAttributeReader.cs index 46c7db465..85cd4ccd1 100644 --- a/src/DotNet/CustomAttributeReader.cs +++ b/src/DotNet/CustomAttributeReader.cs @@ -277,6 +277,8 @@ CustomAttribute Read(ICustomAttributeType ctor) { } List ReadNamedArguments(int numNamedArgs) { + if ((uint)numNamedArgs >= 0x4000_0000 || numNamedArgs * 4 > reader.BytesLeft) + return null; var namedArgs = new List(numNamedArgs); for (int i = 0; i < numNamedArgs; i++) { if (reader.Position == reader.Length) @@ -528,7 +530,7 @@ CAArgument ReadArrayArgument(SZArraySig arrayType) { int arrayCount = reader.ReadInt32(); if (arrayCount == -1) { // -1 if it's null } - else if (arrayCount < 0) + else if (arrayCount < 0 || arrayCount > reader.BytesLeft) throw new CABlobParserException("Array is too big"); else { var array = new List(arrayCount); diff --git a/src/DotNet/MD/BlobStream.cs b/src/DotNet/MD/BlobStream.cs index 51019276a..984ab0af7 100644 --- a/src/DotNet/MD/BlobStream.cs +++ b/src/DotNet/MD/BlobStream.cs @@ -46,8 +46,9 @@ public byte[] Read(uint offset) { /// Offset of blob /// A new stream public DataReader CreateReader(uint offset) { - TryCreateReader(offset, out var reader); - return reader; + if (TryCreateReader(offset, out var reader)) + return reader; + return default; } /// diff --git a/src/DotNet/SignatureReader.cs b/src/DotNet/SignatureReader.cs index 3c5caa3cd..4d9dba10d 100644 --- a/src/DotNet/SignatureReader.cs +++ b/src/DotNet/SignatureReader.cs @@ -482,12 +482,12 @@ CallingConventionSig ReadSig() { T ReadSig(T methodSig) where T : MethodBaseSig { if (methodSig.Generic) { - if (!reader.TryReadCompressedUInt32(out uint count)) + if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000) return null; methodSig.GenParamCount = count; } - if (!reader.TryReadCompressedUInt32(out uint numParams)) + if (!reader.TryReadCompressedUInt32(out uint numParams) || numParams > 0x10000 || numParams > reader.BytesLeft) return null; methodSig.RetType = ReadType(); @@ -513,7 +513,7 @@ T ReadSig(T methodSig) where T : MethodBaseSig { /// First byte of signature /// A new instance LocalSig ReadLocalSig(CallingConvention callingConvention) { - if (!reader.TryReadCompressedUInt32(out uint count)) + if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000 || count > reader.BytesLeft) return null; var sig = new LocalSig(callingConvention, count); var locals = sig.Locals; @@ -528,7 +528,7 @@ LocalSig ReadLocalSig(CallingConvention callingConvention) { /// First byte of signature /// A new instance GenericInstMethodSig ReadGenericInstMethod(CallingConvention callingConvention) { - if (!reader.TryReadCompressedUInt32(out uint count)) + if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000 || count > reader.BytesLeft) return null; var sig = new GenericInstMethodSig(callingConvention, count); var args = sig.GenericArguments; @@ -606,7 +606,7 @@ TypeSig ReadType(bool allowTypeSpec = false) { case ElementType.GenericInst: nextType = ReadType(); - if (!reader.TryReadCompressedUInt32(out num)) + if (!reader.TryReadCompressedUInt32(out num) || num > 0x10000 || num > reader.BytesLeft) break; var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); var args = genericInstSig.GenericArguments; @@ -628,7 +628,7 @@ TypeSig ReadType(bool allowTypeSpec = false) { } if (!reader.TryReadCompressedUInt32(out num)) break; - if (num > MaxArrayRank) + if (num > rank) break; var sizes = new List((int)num); for (i = 0; i < num; i++) { @@ -638,7 +638,7 @@ TypeSig ReadType(bool allowTypeSpec = false) { } if (!reader.TryReadCompressedUInt32(out num)) break; - if (num > MaxArrayRank) + if (num > rank) break; var lowerBounds = new List((int)num); for (i = 0; i < num; i++) { From b59cf33f297da6623428183ab33d26b7be34504f Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Sat, 22 Jan 2022 17:53:33 +0800 Subject: [PATCH 438/511] Don't resolve 'T' which is already resolved --- src/DotNet/SigComparer.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 28e739f02..9c87f7e0b 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -2007,8 +2007,11 @@ int GetHashCode(TypeSig a, bool substituteGenericParameters) { return 0; int hash; - if (substituteGenericParameters && genericArguments is not null) + if (substituteGenericParameters && genericArguments is not null) { + var t = a; a = genericArguments.Resolve(a); + substituteGenericParameters = t == a; + } switch (a.ElementType) { case ElementType.Void: @@ -2078,8 +2081,8 @@ int GetHashCode(TypeSig a, bool substituteGenericParameters) { case ElementType.GenericInst: var gia = (GenericInstSig)a; hash = HASHCODE_MAGIC_ET_GENERICINST; - hash += GetHashCode(gia.GenericType, false); - hash += GetHashCode(gia.GenericArguments, false); + hash += GetHashCode(gia.GenericType, substituteGenericParameters); + hash += GetHashCode(gia.GenericArguments, substituteGenericParameters); break; case ElementType.FnPtr: @@ -2141,7 +2144,7 @@ public bool Equals(IList a, IList b) { /// /// The type list /// The hash code - public int GetHashCode(IList a) => GetHashCode(a, false); + public int GetHashCode(IList a) => GetHashCode(a, true); int GetHashCode(IList a, bool substituteGenericParameters) { //************************************************************************ From 18d6c486a827de130f4f453f5c8fd96582461f1d Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Sun, 23 Jan 2022 23:53:37 +0800 Subject: [PATCH 439/511] Fix 'Importer.Import(FieldInfo)' and 'Importer.ImportDeclaringType(Type)' --- src/DotNet/Importer.cs | 26 +++++--------------------- src/DotNet/ReflectionExtensions.cs | 12 ++++++++++-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 06a533607..238e26e00 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -180,7 +180,7 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g /// /// The type /// - public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericTypeDefinition).ToTypeDefOrRef()); + public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericButNotGenericTypeDefinition()).ToTypeDefOrRef()); /// /// Imports a as a @@ -621,26 +621,10 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { origField = fieldInfo; } - MemberRef fieldRef; - if (origField.FieldType.ContainsGenericParameters) { - var origDeclType = origField.DeclaringType; - var asm = module.Context.AssemblyResolver.Resolve(origDeclType.Module.Assembly.GetName(), module); - if (asm is null || asm.FullName != origDeclType.Assembly.FullName) - throw new Exception("Couldn't resolve the correct assembly"); - var mod = asm.FindModule(origDeclType.Module.ScopeName) as ModuleDefMD; - if (mod is null) - throw new Exception("Couldn't resolve the correct module"); - var fieldDef = mod.ResolveField((uint)(origField.MetadataToken & 0x00FFFFFF)); - if (fieldDef is null) - throw new Exception("Couldn't resolve the correct field"); - - var fieldSig = new FieldSig(Import(fieldDef.FieldSig.GetFieldType())); - fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); - } - else { - var fieldSig = new FieldSig(ImportAsTypeSig(fieldInfo.FieldType, fieldInfo.GetRequiredCustomModifiers(), fieldInfo.GetOptionalCustomModifiers())); - fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); - } + bool treatAsGenericInst = fieldInfo.DeclaringType.MustTreatTypeAsGenericInstType(origField.FieldType); + var fieldSig = new FieldSig(ImportAsTypeSig(origField.FieldType, origField.GetRequiredCustomModifiers(), origField.GetOptionalCustomModifiers(), treatAsGenericInst)); + var fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); + var field = TryResolveField(fieldRef); if (FixSignature && !forceFixSignature) { //TODO: diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index 3cf1fad50..5e29bac64 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -79,6 +79,14 @@ public static ElementType GetElementType2(this Type a) { return a.IsValueType ? ElementType.ValueType : ElementType.Class; } + /// + /// Returns true if is a generic type, but + /// not a generic type definition, i.e., a TypeSpec. + /// + /// The type + public static bool IsGenericButNotGenericTypeDefinition(this Type type) => + type is not null && !type.IsGenericTypeDefinition && type.IsGenericType; + /// /// Returns true if is a generic method, but /// not a generic method definition, i.e., a MethodSpec. @@ -94,8 +102,8 @@ public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => /// a generic type def. This seems to happen only if the parameter type is exactly the same /// type as the declaring type, eg. a method similar to: MyType<!0> MyType::SomeMethod(). /// - /// Declaring type of method/event/property - /// Parameter/property/event type + /// Declaring type of field/method/event/property + /// Field/parameter/property/event type internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) => declaringType is not null && declaringType.IsGenericTypeDefinition && t == declaringType; From dafe4865a26206d0c498b3bb9b34823611985457 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Thu, 24 Mar 2022 14:52:40 +0800 Subject: [PATCH 440/511] Improve the error output that occurs when saving the module (#447) * Improve the error output that occurs when saving the module * Update * rollback only one '.' changes * rollback deleted MethodBodyWriter constructors * change internal errorContext to private * fix MetadataErrorContext.Source overwritten --- .../Pdb/Portable/ImportScopeBlobWriter.cs | 6 +- .../Portable/LocalConstantSigBlobWriter.cs | 6 +- .../PortablePdbCustomDebugInfoWriter.cs | 4 +- src/DotNet/Writer/IWriterError.cs | 16 ++++ src/DotNet/Writer/MarshalBlobWriter.cs | 2 +- src/DotNet/Writer/Metadata.cs | 82 +++++++++++++------ src/DotNet/Writer/MetadataErrorContext.cs | 72 ++++++++++++++++ src/DotNet/Writer/MethodBodyWriter.cs | 17 ++-- src/DotNet/Writer/NormalMetadata.cs | 16 ++-- src/DotNet/Writer/PreserveTokensMetadata.cs | 20 ++--- 10 files changed, 175 insertions(+), 66 deletions(-) create mode 100644 src/DotNet/Writer/MetadataErrorContext.cs diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs index 29c30d2d2..eac5468e2 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs @@ -36,7 +36,7 @@ void Write(DataWriter writer, IList imports) { for (int i = 0; i < count; i++) { var import = imports[i]; if (!ImportDefinitionKindUtils.ToImportDefinitionKind(import.Kind, out uint rawKind)) { - helper.Error("Unknown import definition kind: " + import.Kind.ToString()); + helper.Error2("Unknown import definition kind: {0}.", import.Kind); return; } writer.WriteCompressedUInt32(rawKind); @@ -94,7 +94,7 @@ void Write(DataWriter writer, IList imports) { break; default: - helper.Error("Unknown import definition kind: " + import.Kind.ToString()); + helper.Error2("Unknown import definition kind: {0}.", import.Kind); return; } } @@ -108,7 +108,7 @@ uint GetTypeDefOrRefEncodedToken(ITypeDefOrRef tdr) { var token = systemMetadata.GetToken(tdr); if (MD.CodedToken.TypeDefOrRef.Encode(token, out uint codedToken)) return codedToken; - helper.Error($"Could not encode token 0x{token.Raw:X8}"); + helper.Error2("Could not encode token 0x{0:X8}.", token.Raw); return 0; } } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs index 3fd0816e9..e39bd502a 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs @@ -79,7 +79,7 @@ void Write(DataWriter writer, TypeSig type, object value) { var tdr = ((ValueTypeSig)type).TypeDefOrRef; var td = tdr.ResolveTypeDef(); if (td is null) - helper.Error($"Couldn't resolve type 0x{tdr?.MDToken.Raw ?? 0:X8}"); + helper.Error2("Couldn't resolve type 0x{0:X8}.", tdr?.MDToken.Raw ?? 0); else if (td.IsEnum) { var underlyingType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers(); switch (underlyingType.GetElementType()) { @@ -135,7 +135,7 @@ void Write(DataWriter writer, TypeSig type, object value) { if (value is byte[]) writer.WriteBytes((byte[])value); else if (value is not null) { - helper.Error("Unsupported constant: " + value.GetType().FullName); + helper.Error2("Unsupported constant: {0}.", value.GetType().FullName); return; } } @@ -176,7 +176,7 @@ void Write(DataWriter writer, TypeSig type, object value) { case ElementType.Sentinel: case ElementType.Pinned: default: - helper.Error("Unsupported element type in LocalConstant sig blob: " + et.ToString()); + helper.Error2("Unsupported element type in LocalConstant sig blob: {0}.", et); return; } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 328382c7d..0729c602e 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -106,7 +106,7 @@ void WriteUTF8Z(string s) { void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi) { if (!methodContext.HasBody) { - helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind); + helper.Error2("Method has no body, can't write custom debug info: {0}.", cdi.Kind); return; } var cdiScopes = cdi.Scopes; @@ -222,7 +222,7 @@ void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { if (!methodContext.HasBody) { - helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind); + helper.Error2("Method has no body, can't write custom debug info: {0}.", cdi.Kind); return; } diff --git a/src/DotNet/Writer/IWriterError.cs b/src/DotNet/Writer/IWriterError.cs index 8575b4fea..c6e3005ec 100644 --- a/src/DotNet/Writer/IWriterError.cs +++ b/src/DotNet/Writer/IWriterError.cs @@ -27,4 +27,20 @@ public interface IWriterError2 : IWriterError { /// Optional message arguments void Error(string message, params object[] args); } + + static partial class Extensions { + /// + /// Called when an error is detected (eg. a null pointer or other invalid value). The error + /// can be ignored but the written data won't be valid. + /// + /// The instance of + /// Error message + /// Optional message arguments + internal static void Error2(this IWriterError helper, string message, params object[] args) { + if (helper is IWriterError2 helper2) + helper2.Error(message, args); + else + helper.Error(string.Format(message, args)); + } + } } diff --git a/src/DotNet/Writer/MarshalBlobWriter.cs b/src/DotNet/Writer/MarshalBlobWriter.cs index 550c0dcab..df5ead840 100644 --- a/src/DotNet/Writer/MarshalBlobWriter.cs +++ b/src/DotNet/Writer/MarshalBlobWriter.cs @@ -128,7 +128,7 @@ byte[] Write(MarshalType marshalType) { bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { if (!canWriteMore) { if (isValid) - helper.Error($"MarshalType field {field} is valid even though a previous field was invalid"); + helper.Error2("MarshalType field {0} is valid even though a previous field was invalid.", field); return canWriteMore; } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 15fdd4092..df93b83e1 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -445,6 +445,7 @@ public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenProv RVA rva; readonly MetadataOptions options; ILogger logger; + readonly MetadataErrorContext errorContext; readonly NormalMetadata debugMetadata; readonly bool isStandaloneDebugMetadata; internal readonly ModuleDef module; @@ -940,6 +941,8 @@ internal Metadata(ModuleDef module, UniqueChunkList constants, M blobHeap = new BlobHeap(); pdbHeap = new PdbHeap(); + errorContext = new MetadataErrorContext(); + this.isStandaloneDebugMetadata = isStandaloneDebugMetadata; switch (debugKind) { case DebugMetadataKind.None: @@ -1403,20 +1406,27 @@ public ByteArrayChunk GetInitialValueChunk(FieldDef fd) { /// /// Error message /// Optional message arguments - protected void Error(string message, params object[] args) => GetLogger().Log(this, LoggerEvent.Error, message, args); + protected void Error(string message, params object[] args) { + errorContext.Append("Error", ref message, ref args); + GetLogger().Log(this, LoggerEvent.Error, message, args); + } /// /// Called to warn of something /// /// Warning message /// Optional message arguments - protected void Warning(string message, params object[] args) => GetLogger().Log(this, LoggerEvent.Warning, message, args); + protected void Warning(string message, params object[] args) { + errorContext.Append("Warning", ref message, ref args); + GetLogger().Log(this, LoggerEvent.Warning, message, args); + } /// /// Raises /// /// Event protected void OnMetadataEvent(MetadataEvent evt) { + errorContext.Event = evt; RaiseProgress(evt, 0); MetadataEvent?.Invoke(this, new MetadataWriterEventArgs(this, evt)); } @@ -1572,6 +1582,8 @@ void InitializeTypeDefsAndMemberDefs() { int notifyAfter = numTypes / numNotifyEvents; foreach (var type in allTypeDefs) { + using var _ = errorContext.SetSource(type); + if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { RaiseProgress(Writer.MetadataEvent.MemberDefRidsAllocated, (double)typeNum / numTypes); notifyNum++; @@ -1597,9 +1609,10 @@ void InitializeTypeDefsAndMemberDefs() { for (int i = 0; i < count; i++) { var field = fields[i]; if (field is null) { - Error("Field is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); + Error("Field is null"); continue; } + using var __ = errorContext.SetSource(field); uint rid = GetRid(field); var row = new RawFieldRow((ushort)field.Attributes, stringsHeap.Add(field.Name), GetSignature(field.Signature)); tablesHeap.FieldTable[rid] = row; @@ -1615,9 +1628,10 @@ void InitializeTypeDefsAndMemberDefs() { for (int i = 0; i < count; i++) { var method = methods[i]; if (method is null) { - Error("Method is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); + Error("Method is null"); continue; } + using var __ = errorContext.SetSource(method); if (method.ExportInfo is not null) ExportedMethods.Add(method); uint rid = GetRid(method); @@ -1633,7 +1647,7 @@ void InitializeTypeDefsAndMemberDefs() { for (int j = 0; j < count2; j++) { var pd = paramDefs[j]; if (pd is null) { - Error("Param is null. Method {0} ({1:X8})", method, method.MDToken.Raw); + Error("Param is null"); continue; } uint pdRid = GetRid(pd); @@ -1649,9 +1663,10 @@ void InitializeTypeDefsAndMemberDefs() { for (int i = 0; i < count; i++) { var evt = events[i]; if (evt is null) { - Error("Event is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); + Error("Event is null"); continue; } + using var __ = errorContext.SetSource(evt); uint rid = GetRid(evt); var row = new RawEventRow((ushort)evt.Attributes, stringsHeap.Add(evt.Name), AddTypeDefOrRef(evt.EventType)); tablesHeap.EventTable[rid] = row; @@ -1663,9 +1678,10 @@ void InitializeTypeDefsAndMemberDefs() { for (int i = 0; i < count; i++) { var prop = properties[i]; if (prop is null) { - Error("Property is null. TypeDef {0} ({1:X8})", type, type.MDToken.Raw); + Error("Property is null"); continue; } + using var __ = errorContext.SetSource(prop); uint rid = GetRid(prop); var row = new RawPropertyRow((ushort)prop.Attributes, stringsHeap.Add(prop.Name), GetSignature(prop.Type)); tablesHeap.PropertyTable[rid] = row; @@ -1689,6 +1705,8 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { uint rid; foreach (var type in allTypeDefs) { + using var _ = errorContext.SetSource(type); + if (typeNum++ == notifyAfter && notifyNum < numNotifyEvents) { RaiseProgress(Writer.MetadataEvent.MostTablesSorted, (double)typeNum / numTypes); notifyNum++; @@ -1722,6 +1740,7 @@ void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { var method = methods[i]; if (method is null) continue; + using var __ = errorContext.SetSource(method); if (method.HasCustomAttributes) { rid = GetRid(method); AddCustomAttributes(Table.Method, rid, method); @@ -1775,6 +1794,7 @@ void InitializeVTableFixups() { if (fixups is null || fixups.VTables.Count == 0) return; + using var _ = errorContext.SetSource("vtable fixups"); foreach (var vtable in fixups) { if (vtable is null) { Error("VTable is null"); @@ -1789,6 +1809,7 @@ void InitializeVTableFixups() { } void AddExportedTypes() { + using var _ = errorContext.SetSource("exported types"); var exportedTypes = module.ExportedTypes; int count = exportedTypes.Count; for (int i = 0; i < count; i++) @@ -1800,6 +1821,7 @@ void AddExportedTypes() { /// a , it will have already been added. /// void InitializeEntryPoint() { + using var _ = errorContext.SetSource("entry point"); if (module.ManagedEntryPoint is FileDef epFile) AddFile(epFile); } @@ -1885,6 +1907,7 @@ void InitializeGenericParamConstraintTable() { foreach (var type in allTypeDefs) { if (type is null) continue; + using var _ = errorContext.SetSource(type); AddGenericParamConstraints(type.GenericParameters); var methods = type.Methods; int count = methods.Count; @@ -1892,6 +1915,7 @@ void InitializeGenericParamConstraintTable() { var method = methods[i]; if (method is null) continue; + using var __ = errorContext.SetSource(method); AddGenericParamConstraints(method.GenericParameters); } } @@ -1975,12 +1999,16 @@ void WriteMethodBodies() { if (type is null) continue; + using var _ = errorContext.SetSource(type); + var methods = type.Methods; for (int i = 0; i < methods.Count; i++) { var method = methods[i]; if (method is null) continue; + using var __ = errorContext.SetSource(method); + if (methodNum++ == notifyAfter && notifyNum < numNotifyEvents) { RaiseProgress(Writer.MetadataEvent.BeginWriteMethodBodies, (double)methodNum / numMethods); notifyNum++; @@ -1992,7 +2020,7 @@ void WriteMethodBodies() { var cilBody = method.Body; if (cilBody is not null) { if (!(cilBody.Instructions.Count == 0 && cilBody.Variables.Count == 0)) { - writer.Reset(method, keepMaxStack || cilBody.KeepOldMaxStack); + writer.Reset(cilBody, keepMaxStack || cilBody.KeepOldMaxStack); writer.Write(); var origRva = method.RVA; uint origSize = cilBody.MetadataBodySize; @@ -2305,7 +2333,7 @@ protected uint AddTypeDefOrRef(ITypeDefOrRef tdr) { var token = new MDToken(tdr.MDToken.Table, AddMDTokenProvider(tdr)); if (!CodedToken.TypeDefOrRef.Encode(token, out uint encodedToken)) { - Error("Can't encode TypeDefOrRef token {0:X8}", token.Raw); + Error("Can't encode TypeDefOrRef token 0x{0:X8}.", token.Raw); encodedToken = 0; } return encodedToken; @@ -2323,7 +2351,7 @@ protected uint AddResolutionScope(IResolutionScope rs) { var token = new MDToken(rs.MDToken.Table, AddMDTokenProvider(rs)); if (!CodedToken.ResolutionScope.Encode(token, out uint encodedToken)) { - Error("Can't encode ResolutionScope token {0:X8}", token.Raw); + Error("Can't encode ResolutionScope token 0x{0:X8}.", token.Raw); encodedToken = 0; } return encodedToken; @@ -2342,7 +2370,7 @@ protected uint AddMethodDefOrRef(IMethodDefOrRef mdr) { var token = new MDToken(mdr.MDToken.Table, AddMDTokenProvider(mdr)); if (!CodedToken.MethodDefOrRef.Encode(token, out uint encodedToken)) { - Error("Can't encode MethodDefOrRef token {0:X8}", token.Raw); + Error("Can't encode MethodDefOrRef token 0x{0:X8}.", token.Raw); encodedToken = 0; } return encodedToken; @@ -2361,7 +2389,7 @@ protected uint AddMemberRefParent(IMemberRefParent parent) { var token = new MDToken(parent.MDToken.Table, AddMDTokenProvider(parent)); if (!CodedToken.MemberRefParent.Encode(token, out uint encodedToken)) { - Error("Can't encode MemberRefParent token {0:X8}", token.Raw); + Error("Can't encode MemberRefParent token 0x{0:X8}.", token.Raw); encodedToken = 0; } return encodedToken; @@ -2380,7 +2408,7 @@ protected uint AddImplementation(IImplementation impl) { var token = new MDToken(impl.MDToken.Table, AddMDTokenProvider(impl)); if (!CodedToken.Implementation.Encode(token, out uint encodedToken)) { - Error("Can't encode Implementation token {0:X8}", token.Raw); + Error("Can't encode Implementation token 0x{0:X8}.", token.Raw); encodedToken = 0; } return encodedToken; @@ -2399,7 +2427,7 @@ protected uint AddCustomAttributeType(ICustomAttributeType cat) { var token = new MDToken(cat.MDToken.Table, AddMDTokenProvider(cat)); if (!CodedToken.CustomAttributeType.Encode(token, out uint encodedToken)) { - Error("Can't encode CustomAttributeType token {0:X8}", token.Raw); + Error("Can't encode CustomAttributeType token 0x{0:X8}.", token.Raw); encodedToken = 0; } return encodedToken; @@ -2432,7 +2460,7 @@ protected uint AddModule(ModuleDef module) { return 0; } if (this.module != module) - Error("Module {0} must be referenced with a ModuleRef, not a ModuleDef", module); + Error("Module '{0}' must be referenced with a ModuleRef, not a ModuleDef.", module); if (moduleDefInfos.TryGetRid(module, out uint rid)) return rid; var row = new RawModuleRow(module.Generation, @@ -2558,7 +2586,7 @@ protected void AddGenericParam(MDToken owner, GenericParam gp) { return; } if (!CodedToken.TypeOrMethodDef.Encode(owner, out uint encodedOwner)) { - Error("Can't encode TypeOrMethodDef token {0:X8}", owner.Raw); + Error("Can't encode TypeOrMethodDef token 0x{0:X8}.", owner.Raw); encodedOwner = 0; } var row = new RawGenericParamRow(gp.Number, @@ -2648,7 +2676,7 @@ protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { return; var fieldMarshal = hfm.MarshalType; if (!CodedToken.HasFieldMarshal.Encode(parent, out uint encodedParent)) { - Error("Can't encode HasFieldMarshal token {0:X8}", parent.Raw); + Error("Can't encode HasFieldMarshal token 0x{0:X8}.", parent.Raw); encodedParent = 0; } var row = new RawFieldMarshalRow(encodedParent, @@ -2674,7 +2702,7 @@ protected void AddFieldRVA(FieldDef field) { return; var ivBytes = field.InitialValue; if (!VerifyFieldSize(field, ivBytes.Length)) - Error("Field {0} ({1:X8}) initial value size != size of field type", field, field.MDToken.Raw); + Error("Field '{0}' (0x{1:X8}) initial value size != size of field type.", field, field.MDToken.Raw); uint rid = GetRid(field); var iv = constants.Add(new ByteArrayChunk(ivBytes), ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT); fieldToInitialValue[field] = iv; @@ -2702,7 +2730,7 @@ protected void AddImplMap(MDToken parent, IMemberForwarded mf) { return; var implMap = mf.ImplMap; if (!CodedToken.MemberForwarded.Encode(parent, out uint encodedParent)) { - Error("Can't encode MemberForwarded token {0:X8}", parent.Raw); + Error("Can't encode MemberForwarded token 0x{0:X8}.", parent.Raw); encodedParent = 0; } var row = new RawImplMapRow((ushort)implMap.Attributes, @@ -2722,7 +2750,7 @@ protected void AddConstant(MDToken parent, IHasConstant hc) { return; var constant = hc.Constant; if (!CodedToken.HasConstant.Encode(parent, out uint encodedParent)) { - Error("Can't encode HasConstant token {0:X8}", parent.Raw); + Error("Can't encode HasConstant token 0x{0:X8}.", parent.Raw); encodedParent = 0; } var row = new RawConstantRow((byte)constant.Type, 0, @@ -2815,7 +2843,7 @@ protected void AddDeclSecurities(MDToken parent, IList declSecurit if (declSecurities is null) return; if (!CodedToken.HasDeclSecurity.Encode(parent, out uint encodedParent)) { - Error("Can't encode HasDeclSecurity token {0:X8}", parent.Raw); + Error("Can't encode HasDeclSecurity token 0x{0:X8}.", parent.Raw); encodedParent = 0; } var bwctx = AllocBinaryWriterContext(); @@ -2884,7 +2912,7 @@ void AddMethodSemantics(MDToken owner, MethodDef method, MethodSemanticsAttribut if (methodRid == 0) return; if (!CodedToken.HasSemantic.Encode(owner, out uint encodedOwner)) { - Error("Can't encode HasSemantic token {0:X8}", owner.Raw); + Error("Can't encode HasSemantic token 0x{0:X8}.", owner.Raw); encodedOwner = 0; } var row = new RawMethodSemanticsRow((ushort)flags, methodRid, encodedOwner); @@ -2895,7 +2923,7 @@ void AddMethodImpls(MethodDef method, IList overrides) { if (overrides is null) return; if (method.DeclaringType is null) { - Error("Method declaring type is null. Method {0} ({1:X8})", method, method.MDToken.Raw); + Error("Method declaring type is null"); return; } if (overrides.Count != 0) { @@ -2954,7 +2982,7 @@ void AddResource(Resource resource) { if (resource is null) Error("Resource is null"); else - Error("Invalid resource type: {0}", resource.GetType()); + Error("Invalid resource type: '{0}'.", resource.GetType()); } uint AddEmbeddedResource(EmbeddedResource er) { @@ -3132,7 +3160,7 @@ void AddCustomAttribute(MDToken token, CustomAttribute ca) { return; } if (!CodedToken.HasCustomAttribute.Encode(token, out uint encodedToken)) { - Error("Can't encode HasCustomAttribute token {0:X8}", token.Raw); + Error("Can't encode HasCustomAttribute token 0x{0:X8}.", token.Raw); encodedToken = 0; } var bwctx = AllocBinaryWriterContext(); @@ -3315,7 +3343,7 @@ void AddCustomDebugInformationCore(SerializerMethodContext serializerMethodConte var token = new MDToken(table, rid); if (!CodedToken.HasCustomDebugInformation.Encode(token, out uint encodedToken)) { - Error("Couldn't encode HasCustomDebugInformation token {0:X8}", token.Raw); + Error("Couldn't encode HasCustomDebugInformation token 0x{0:X8}.", token.Raw); return; } @@ -3371,7 +3399,7 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, break; default: - Error("Unknown custom debug info {0}", cdi.Kind.ToString()); + Error("Unknown custom debug info {0}.", cdi.Kind); break; } } diff --git a/src/DotNet/Writer/MetadataErrorContext.cs b/src/DotNet/Writer/MetadataErrorContext.cs new file mode 100644 index 000000000..dee31d720 --- /dev/null +++ b/src/DotNet/Writer/MetadataErrorContext.cs @@ -0,0 +1,72 @@ +// dnlib: See LICENSE.txt for more info + +using System; +using System.Text; + +namespace dnlib.DotNet.Writer { + sealed class MetadataErrorContext { + sealed class ErrorSource : IDisposable { + MetadataErrorContext context; + readonly ErrorSource originalValue; + + public object Value { get; } + + public ErrorSource(MetadataErrorContext context, object value) { + this.context = context; + Value = value; + originalValue = context.source; + } + + public void Dispose() { + if (context is null) + return; + context.source = originalValue; + context = null; + } + } + + ErrorSource source; + + public MetadataEvent Event { get; set; } + + public IDisposable SetSource(object source) => this.source = new ErrorSource(this, source); + + public void Append(string errorLevel, ref string message, ref object[] args) { + int count = 1; + var stringSource = source?.Value as string; + var tokenSource = source?.Value as IMDTokenProvider; + if (tokenSource is not null) + count += 2; + int ctxArgIndex = args.Length; + + var newMessage = new StringBuilder(message); + var newArgs = new object[args.Length + count]; + Array.Copy(args, 0, newArgs, 0, args.Length); + + if (newMessage.Length != 0 && newMessage[newMessage.Length - 1] != '.') + newMessage.Append('.'); + newMessage.AppendFormat(" {0} occurred after metadata event {{{1}}}", errorLevel, ctxArgIndex); + newArgs[ctxArgIndex] = Event; + + if (tokenSource is not null) { + string sourceType = tokenSource switch { + TypeDef => "type", + FieldDef => "field", + MethodDef => "method", + EventDef => "event", + PropertyDef => "property", + _ => "???" + }; + newMessage.AppendFormat(" during writing {0} '{{{1}}}' (0x{{{2}:X8}})", sourceType, ctxArgIndex + 1, ctxArgIndex + 2); + newArgs[ctxArgIndex + 1] = tokenSource; + newArgs[ctxArgIndex + 2] = tokenSource.MDToken.Raw; + } + else if (stringSource is not null) { + newMessage.AppendFormat(" during writing {0}", stringSource); + } + + message = newMessage.Append('.').ToString(); + args = newArgs; + } + } +} diff --git a/src/DotNet/Writer/MethodBodyWriter.cs b/src/DotNet/Writer/MethodBodyWriter.cs index dcdafb88e..0fad93f32 100644 --- a/src/DotNet/Writer/MethodBodyWriter.cs +++ b/src/DotNet/Writer/MethodBodyWriter.cs @@ -31,7 +31,6 @@ public interface ITokenProvider : IWriterError { /// public sealed class MethodBodyWriter : MethodBodyWriterBase { readonly ITokenProvider helper; - MethodDef method; CilBody cilBody; bool keepMaxStack; uint codeSize; @@ -77,7 +76,7 @@ public MethodBodyWriter(ITokenProvider helper, MethodDef method) public MethodBodyWriter(ITokenProvider helper, MethodDef method, bool keepMaxStack) : base(method.Body.Instructions, method.Body.ExceptionHandlers) { this.helper = helper; - this.method = method; + cilBody = method.Body; this.keepMaxStack = keepMaxStack; } @@ -108,16 +107,15 @@ internal MethodBodyWriter(ITokenProvider helper) { this.helper = helper; } - internal void Reset(MethodDef method, bool keepMaxStack) { - this.method = method; + internal void Reset(CilBody cilBody, bool keepMaxStack) { + Reset(cilBody.Instructions, cilBody.ExceptionHandlers); + this.cilBody = cilBody; this.keepMaxStack = keepMaxStack; - cilBody = method.Body; codeSize = 0; maxStack = 0; code = null; extraSections = null; localVarSigTok = 0; - Reset(cilBody.Instructions, cilBody.ExceptionHandlers); } /// @@ -324,12 +322,7 @@ byte[] WriteSmallExceptionClauses() { } /// - protected override void ErrorImpl(string message) { - if (method is not null && helper is IWriterError2 writerError2) - writerError2.Error(message + " At method {0} ({1:X8}).", method, method.MDToken.Raw); - else - helper.Error(message); - } + protected override void ErrorImpl(string message) => helper.Error(message); /// protected override void WriteInlineField(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); diff --git a/src/DotNet/Writer/NormalMetadata.cs b/src/DotNet/Writer/NormalMetadata.cs index 13ef316d0..1e8443cbb 100644 --- a/src/DotNet/Writer/NormalMetadata.cs +++ b/src/DotNet/Writer/NormalMetadata.cs @@ -149,7 +149,7 @@ public override uint GetRid(TypeDef td) { if (td is null) Error("TypeDef is null"); else - Error("TypeDef {0} ({1:X8}) is not defined in this module ({2}). A type was removed that is still referenced by this module.", td, td.MDToken.Raw, module); + Error("TypeDef '{0}' (0x{1:X8}) is not defined in this module '{2}'. A type was removed that is still referenced by this module.", td, td.MDToken.Raw, module); return 0; } @@ -160,7 +160,7 @@ public override uint GetRid(FieldDef fd) { if (fd is null) Error("Field is null"); else - Error("Field {0} ({1:X8}) is not defined in this module ({2}). A field was removed that is still referenced by this module.", fd, fd.MDToken.Raw, module); + Error("Field '{0}' (0x{1:X8}) is not defined in this module '{2}'. A field was removed that is still referenced by this module.", fd, fd.MDToken.Raw, module); return 0; } @@ -171,7 +171,7 @@ public override uint GetRid(MethodDef md) { if (md is null) Error("Method is null"); else - Error("Method {0} ({1:X8}) is not defined in this module ({2}). A method was removed that is still referenced by this module.", md, md.MDToken.Raw, module); + Error("Method '{0}' (0x{1:X8}) is not defined in this module '{2}'. A method was removed that is still referenced by this module.", md, md.MDToken.Raw, module); return 0; } @@ -182,7 +182,7 @@ public override uint GetRid(ParamDef pd) { if (pd is null) Error("Param is null"); else - Error("Param {0} ({1:X8}) is not defined in this module ({2}). A parameter was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); + Error("Param '{0}' (0x{1:X8}) is not defined in this module '{2}'. A parameter was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); return 0; } @@ -205,7 +205,7 @@ public override uint GetRid(EventDef ed) { if (ed is null) Error("Event is null"); else - Error("Event {0} ({1:X8}) is not defined in this module ({2}). An event was removed that is still referenced by this module.", ed, ed.MDToken.Raw, module); + Error("Event '{0}' (0x{1:X8}) is not defined in this module '{2}'. An event was removed that is still referenced by this module.", ed, ed.MDToken.Raw, module); return 0; } @@ -216,7 +216,7 @@ public override uint GetRid(PropertyDef pd) { if (pd is null) Error("Property is null"); else - Error("Property {0} ({1:X8}) is not defined in this module ({2}). A property was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); + Error("Property '{0}' (0x{1:X8}) is not defined in this module '{2}'. A property was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); return 0; } @@ -240,7 +240,7 @@ protected override uint AddTypeRef(TypeRef tr) { } if (typeRefInfos.TryGetRid(tr, out uint rid)) { if (rid == 0) - Error("TypeRef {0:X8} has an infinite ResolutionScope loop", tr.MDToken.Raw); + Error("TypeRef 0x{0:X8} has an infinite ResolutionScope loop.", tr.MDToken.Raw); return rid; } typeRefInfos.Add(tr, 0); // Prevent inf recursion @@ -262,7 +262,7 @@ protected override uint AddTypeSpec(TypeSpec ts) { } if (typeSpecInfos.TryGetRid(ts, out uint rid)) { if (rid == 0) - Error("TypeSpec {0:X8} has an infinite TypeSig loop", ts.MDToken.Raw); + Error("TypeSpec 0x{0:X8} has an infinite TypeSig loop.", ts.MDToken.Raw); return rid; } typeSpecInfos.Add(ts, 0); // Prevent inf recursion diff --git a/src/DotNet/Writer/PreserveTokensMetadata.cs b/src/DotNet/Writer/PreserveTokensMetadata.cs index db4a71dc7..376adaf89 100644 --- a/src/DotNet/Writer/PreserveTokensMetadata.cs +++ b/src/DotNet/Writer/PreserveTokensMetadata.cs @@ -210,7 +210,7 @@ public override uint GetRid(TypeDef td) { } if (typeToRid.TryGetValue(td, out uint rid)) return rid; - Error("TypeDef {0} ({1:X8}) is not defined in this module ({2}). A type was removed that is still referenced by this module.", td, td.MDToken.Raw, module); + Error("TypeDef '{0}' (0x{1:X8}) is not defined in this module '{2}'. A type was removed that is still referenced by this module.", td, td.MDToken.Raw, module); return 0; } @@ -221,7 +221,7 @@ public override uint GetRid(FieldDef fd) { if (fd is null) Error("Field is null"); else - Error("Field {0} ({1:X8}) is not defined in this module ({2}). A field was removed that is still referenced by this module.", fd, fd.MDToken.Raw, module); + Error("Field '{0}' (0x{1:X8}) is not defined in this module '{2}'. A field was removed that is still referenced by this module.", fd, fd.MDToken.Raw, module); return 0; } @@ -232,7 +232,7 @@ public override uint GetRid(MethodDef md) { if (md is null) Error("Method is null"); else - Error("Method {0} ({1:X8}) is not defined in this module ({2}). A method was removed that is still referenced by this module.", md, md.MDToken.Raw, module); + Error("Method '{0}' (0x{1:X8}) is not defined in this module '{2}'. A method was removed that is still referenced by this module.", md, md.MDToken.Raw, module); return 0; } @@ -243,7 +243,7 @@ public override uint GetRid(ParamDef pd) { if (pd is null) Error("Param is null"); else - Error("Param {0} ({1:X8}) is not defined in this module ({2}). A parameter was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); + Error("Param '{0}' (0x{1:X8}) is not defined in this module '{2}'. A parameter was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); return 0; } @@ -266,7 +266,7 @@ public override uint GetRid(EventDef ed) { if (ed is null) Error("Event is null"); else - Error("Event {0} ({1:X8}) is not defined in this module ({2}). An event was removed that is still referenced by this module.", ed, ed.MDToken.Raw, module); + Error("Event '{0}' (0x{1:X8}) is not defined in this module '{2}'. An event was removed that is still referenced by this module.", ed, ed.MDToken.Raw, module); return 0; } @@ -277,7 +277,7 @@ public override uint GetRid(PropertyDef pd) { if (pd is null) Error("Property is null"); else - Error("Property {0} ({1:X8}) is not defined in this module ({2}). A property was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); + Error("Property '{0}' (0x{1:X8}) is not defined in this module '{2}'. A property was removed that is still referenced by this module.", pd, pd.MDToken.Raw, module); return 0; } @@ -1033,7 +1033,7 @@ protected override uint AddTypeRef(TypeRef tr) { } if (typeRefInfos.TryGetRid(tr, out uint rid)) { if (rid == 0) - Error("TypeRef {0:X8} has an infinite ResolutionScope loop", tr.MDToken.Raw); + Error("TypeRef 0x{0:X8} has an infinite ResolutionScope loop.", tr.MDToken.Raw); return rid; } typeRefInfos.Add(tr, 0); // Prevent inf recursion @@ -1062,7 +1062,7 @@ uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { } if (typeSpecInfos.TryGetRid(ts, out uint rid)) { if (rid == 0) - Error("TypeSpec {0:X8} has an infinite TypeSig loop", ts.MDToken.Raw); + Error("TypeSpec 0x{0:X8} has an infinite TypeSig loop.", ts.MDToken.Raw); return rid; } typeSpecInfos.Add(ts, 0); // Prevent inf recursion @@ -1169,14 +1169,14 @@ uint AddStandAloneSig(CallingConventionSig callConvSig, uint origToken) { if (callConvTokenToSignature.TryGetValue(origToken, out uint otherSig)) { if (sig == otherSig) return MDToken.ToRID(origToken); - Warning("Could not preserve StandAloneSig token {0:X8}", origToken); + Warning("Could not preserve StandAloneSig token 0x{0:X8}", origToken); return 0; } uint rid = MDToken.ToRID(origToken); var sas = mod.ResolveStandAloneSig(rid); if (standAloneSigInfos.Exists(sas)) { - Warning("StandAloneSig {0:X8} already exists", origToken); + Warning("StandAloneSig 0x{0:X8} already exists", origToken); return 0; } From aa403ba424cc5fe7146e7958897cb35b43dd1ddb Mon Sep 17 00:00:00 2001 From: wtfsck Date: Sat, 9 Apr 2022 12:31:45 +0200 Subject: [PATCH 441/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 3e515a707..8d9ef62e1 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.4.0 + 3.5.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 3f856ae7923b7365ba1ac9530ee30b9c5be7b34c Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Sat, 28 May 2022 21:47:36 +0800 Subject: [PATCH 442/511] =?UTF-8?q?Fix=20Importer=20and=20SigComparer?= =?UTF-8?q?=E2=80=98s=20handling=20of=20generic=20when=20must=20treat=20ge?= =?UTF-8?q?neric=20type=20definition=20as=20generic=20instantiation=20type?= =?UTF-8?q?.=20Mark=20Importer.ImportDeclaringType(Type)=20as=20obsolete.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DotNet/Importer.cs | 50 +++++++++++---------- src/DotNet/SigComparer.cs | 93 +++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 66 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 535d481b4..aa0f02b8f 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -167,20 +167,19 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g } /// - /// Imports a as a . If it's a type that should be - /// the declaring type of a field/method reference, call instead. + /// Imports a as a . /// /// The type /// The imported type or null if is invalid public ITypeDefOrRef Import(Type type) => module.UpdateRowId(ImportAsTypeSig(type).ToTypeDefOrRef()); /// - /// Imports a as a . Should be called if it's the - /// declaring type of a method/field reference. See also + /// Imports a as a . See also /// /// The type /// - public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericButNotGenericTypeDefinition()).ToTypeDefOrRef()); + [Obsolete("Use 'Import(Type)' instead.")] + public ITypeDefOrRef ImportDeclaringType(Type type) => Import(type); /// /// Imports a as a @@ -197,12 +196,13 @@ public ITypeDefOrRef Import(Type type, IList requiredModifiers, IList /// The type /// The imported type or null if is invalid - public TypeSig ImportAsTypeSig(Type type) => ImportAsTypeSig(type, false); + public TypeSig ImportAsTypeSig(Type type) => ImportAsTypeSig(type, null, false); - TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { + TypeSig ImportAsTypeSig(Type type, Type declaringType, bool? treatAsGenericInst = null) { if (type is null) return null; - switch (treatAsGenericInst ? ElementType.GenericInst : type.GetElementType2()) { + bool treatAsGenericInst2 = treatAsGenericInst ?? declaringType.MustTreatTypeAsGenericInstType(type); + switch (treatAsGenericInst2 ? ElementType.GenericInst : type.GetElementType2()) { case ElementType.Void: return module.CorLibTypes.Void; case ElementType.Boolean: return module.CorLibTypes.Boolean; case ElementType.Char: return module.CorLibTypes.Char; @@ -220,9 +220,9 @@ TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { case ElementType.TypedByRef:return module.CorLibTypes.TypedReference; case ElementType.U: return module.CorLibTypes.UIntPtr; case ElementType.Object: return module.CorLibTypes.Object; - case ElementType.Ptr: return new PtrSig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst)); - case ElementType.ByRef: return new ByRefSig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst)); - case ElementType.SZArray: return new SZArraySig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst)); + case ElementType.Ptr: return new PtrSig(ImportAsTypeSig(type.GetElementType(), declaringType)); + case ElementType.ByRef: return new ByRefSig(ImportAsTypeSig(type.GetElementType(), declaringType)); + case ElementType.SZArray: return new SZArraySig(ImportAsTypeSig(type.GetElementType(), declaringType)); case ElementType.ValueType: return new ValueTypeSig(CreateTypeRef(type)); case ElementType.Class: return new ClassSig(CreateTypeRef(type)); case ElementType.Var: return new GenericVar((uint)type.GenericParameterPosition, gpContext.Type); @@ -237,13 +237,13 @@ TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) { var lowerBounds = new int[type.GetArrayRank()]; var sizes = Array2.Empty(); FixSignature = true; - return new ArraySig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst), (uint)type.GetArrayRank(), sizes, lowerBounds); + return new ArraySig(ImportAsTypeSig(type.GetElementType(), declaringType), (uint)type.GetArrayRank(), sizes, lowerBounds); case ElementType.GenericInst: var typeGenArgs = type.GetGenericArguments(); - var git = new GenericInstSig(ImportAsTypeSig(type.GetGenericTypeDefinition()) as ClassOrValueTypeSig, (uint)typeGenArgs.Length); + var git = new GenericInstSig(ImportAsTypeSig(type.GetGenericTypeDefinition(), null, false) as ClassOrValueTypeSig, (uint)typeGenArgs.Length); foreach (var ga in typeGenArgs) - git.GenericArguments.Add(ImportAsTypeSig(ga)); + git.GenericArguments.Add(ImportAsTypeSig(ga, declaringType)); return git; case ElementType.Sentinel: @@ -393,16 +393,16 @@ IResolutionScope CreateScopeReference(Type type) { /// A list of all optional modifiers or null /// The imported type or null if is invalid public TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers) => - ImportAsTypeSig(type, requiredModifiers, optionalModifiers, false); + ImportAsTypeSig(type, requiredModifiers, optionalModifiers, null); - TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers, bool treatAsGenericInst) { + TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers, Type declaringType) { if (type is null) return null; if (IsEmpty(requiredModifiers) && IsEmpty(optionalModifiers)) - return ImportAsTypeSig(type, treatAsGenericInst); + return ImportAsTypeSig(type, declaringType); FixSignature = true; // Order of modifiers is unknown - var ts = ImportAsTypeSig(type, treatAsGenericInst); + var ts = ImportAsTypeSig(type, declaringType); // We don't know the original order of the modifiers. // Assume all required modifiers are closer to the real type. @@ -469,11 +469,13 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { IMethodDefOrRef method; var origMethod = methodBase.Module.ResolveMethod(methodBase.MetadataToken); if (methodBase.DeclaringType.GetElementType2() == ElementType.GenericInst) - method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), ImportDeclaringType(methodBase.DeclaringType))); + method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), Import(methodBase.DeclaringType))); else method = ImportInternal(origMethod) as IMethodDefOrRef; method = TryResolveMethod(method); + if (methodBase.ContainsGenericParameters) + return method; // Declaring type is instantiated but method itself is not var gim = CreateGenericInstMethodSig(methodBase); var methodSpec = module.UpdateRowId(new MethodSpecUser(method, gim)); @@ -489,7 +491,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) { parent = GetModuleParent(methodBase.Module); } else - parent = ImportDeclaringType(methodBase.DeclaringType); + parent = Import(methodBase.DeclaringType); if (parent is null) return null; @@ -536,7 +538,7 @@ MethodSig CreateMethodSig(MethodBase mb) { } TypeSig ImportAsTypeSig(ParameterInfo p, Type declaringType) => - ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType.MustTreatTypeAsGenericInstType(p.ParameterType)); + ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType); CallingConvention GetCallingConvention(MethodBase mb) { CallingConvention cc = 0; @@ -627,7 +629,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { parent = GetModuleParent(fieldInfo.Module); } else - parent = ImportDeclaringType(fieldInfo.DeclaringType); + parent = Import(fieldInfo.DeclaringType); if (parent is null) return null; @@ -641,8 +643,8 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { origField = fieldInfo; } - bool treatAsGenericInst = fieldInfo.DeclaringType.MustTreatTypeAsGenericInstType(origField.FieldType); - var fieldSig = new FieldSig(ImportAsTypeSig(origField.FieldType, origField.GetRequiredCustomModifiers(), origField.GetOptionalCustomModifiers(), treatAsGenericInst)); + var fieldSig = new FieldSig(ImportAsTypeSig(origField.FieldType, + origField.GetRequiredCustomModifiers(), origField.GetOptionalCustomModifiers(), origField.DeclaringType)); var fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); var field = TryResolveField(fieldRef); diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 9c87f7e0b..5f22006bc 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -491,7 +491,7 @@ public enum SigComparerOptions : uint { /// Compares types, signatures, methods, fields, properties, events /// public struct SigComparer { - const SigComparerOptions SigComparerOptions_SubstituteGenericParameters = (SigComparerOptions)0x400; + const SigComparerOptions SigComparerOptions_DontSubstituteGenericParameters = (SigComparerOptions)0x400; const int HASHCODE_MAGIC_GLOBAL_TYPE = 1654396648; const int HASHCODE_MAGIC_NESTED_TYPE = -1049070942; @@ -521,7 +521,7 @@ public struct SigComparer { bool CompareAssemblyLocale => (options & SigComparerOptions.CompareAssemblyLocale) != 0; bool TypeRefCanReferenceGlobalType => (options & SigComparerOptions.TypeRefCanReferenceGlobalType) != 0; bool DontCompareReturnType => (options & SigComparerOptions.DontCompareReturnType) != 0; - bool SubstituteGenericParameters => (options & SigComparerOptions_SubstituteGenericParameters) != 0; + bool DontSubstituteGenericParameters => (options & SigComparerOptions_DontSubstituteGenericParameters) != 0; bool CaseInsensitiveTypeNamespaces => (options & SigComparerOptions.CaseInsensitiveTypeNamespaces) != 0; bool CaseInsensitiveTypeNames => (options & SigComparerOptions.CaseInsensitiveTypeNames) != 0; bool CaseInsensitiveMethodFieldNames => (options & SigComparerOptions.CaseInsensitiveMethodFieldNames) != 0; @@ -2700,7 +2700,7 @@ public int GetHashCode(MemberRef a) { int hash = GetHashCode_MethodFieldName(a.Name); GenericInstSig git; - if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { + if (!DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); hash += GetHashCode(a.Signature); @@ -2749,8 +2749,6 @@ public int GetHashCode(MethodSpec a) { if (!recursionCounter.Increment()) return 0; - // We must do this or it won't get the same hash code as some MethodInfos - var oldOptions = SetOptions(SigComparerOptions_SubstituteGenericParameters); var gim = a.GenericInstMethodSig; if (gim is not null) { InitializeGenericArguments(); @@ -2759,7 +2757,6 @@ public int GetHashCode(MethodSpec a) { int hash = GetHashCode(a.Method); if (gim is not null) genericArguments.PopMethodArgs(); - RestoreOptions(oldOptions); recursionCounter.Decrement(); return hash; @@ -3279,11 +3276,11 @@ public bool Equals(TypeSpec a, Type b) { /// Type #1 /// Type #2 /// true if same, false otherwise - public bool Equals(TypeSig a, Type b) => Equals(a, b, false); + public bool Equals(TypeSig a, Type b) => Equals(a, b, null, false); - bool Equals(ITypeDefOrRef a, Type b, bool treatAsGenericInst) { + bool Equals(ITypeDefOrRef a, Type b, Type declaringType) { if (a is TypeSpec ts) - return Equals(ts.TypeSig, b, treatAsGenericInst); + return Equals(ts.TypeSig, b, declaringType); return Equals(a, b); } @@ -3310,10 +3307,12 @@ static bool IsFnPtrElementType(Type a) { /// /// Type #1 /// Type #2 + /// Root declaring type to check if we should + /// treat as a generic instance type /// true if we should treat /// as a generic instance type /// true if same, false otherwise - bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { + bool Equals(TypeSig a, Type b, Type declaringType, bool? treatAsGenericInst = null) { // Global methods and fields have their DeclaringType set to null. Assume // null always means the global type. if (a is null) @@ -3324,6 +3323,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { return false; bool result; + bool treatAsGenericInst2 = treatAsGenericInst ?? declaringType.MustTreatTypeAsGenericInstType(b); if (genericArguments is not null) a = genericArguments.Resolve(a); @@ -3346,7 +3346,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { case ElementType.I: case ElementType.U: case ElementType.Object: - result = Equals(((TypeDefOrRefSig)a).TypeDefOrRef, b, treatAsGenericInst); + result = Equals(((TypeDefOrRefSig)a).TypeDefOrRef, b, declaringType); break; case ElementType.Ptr: @@ -3357,7 +3357,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = a is not null && a.ElementType == ElementType.FnPtr; } else - result = Equals(a.Next, b.GetElementType()); + result = Equals(a.Next, b.GetElementType(), declaringType); break; case ElementType.ByRef: @@ -3368,7 +3368,7 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = a is not null && a.ElementType == ElementType.FnPtr; } else - result = Equals(a.Next, b.GetElementType()); + result = Equals(a.Next, b.GetElementType(), declaringType); break; case ElementType.SZArray: @@ -3379,11 +3379,11 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = a is not null && a.ElementType == ElementType.FnPtr; } else - result = Equals(a.Next, b.GetElementType()); + result = Equals(a.Next, b.GetElementType(), declaringType); break; case ElementType.Pinned: - result = Equals(a.Next, b, treatAsGenericInst); + result = Equals(a.Next, b, declaringType); break; case ElementType.Array: @@ -3394,13 +3394,13 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { result = ara.Rank == b.GetArrayRank() && (IsFnPtrElementType(b) ? (a = a.Next.RemoveModifiers()) is not null && a.ElementType == ElementType.FnPtr : - Equals(a.Next, b.GetElementType())); + Equals(a.Next, b.GetElementType(), declaringType)); } break; case ElementType.ValueType: case ElementType.Class: - result = Equals((a as ClassOrValueTypeSig).TypeDefOrRef, b, treatAsGenericInst); + result = Equals((a as ClassOrValueTypeSig).TypeDefOrRef, b, declaringType); break; case ElementType.Var: @@ -3416,18 +3416,18 @@ bool Equals(TypeSig a, Type b, bool treatAsGenericInst) { break; case ElementType.GenericInst: - if (!(b.IsGenericType && !b.IsGenericTypeDefinition) && !treatAsGenericInst) { + if (!(b.IsGenericType && !b.IsGenericTypeDefinition) && !treatAsGenericInst2) { result = false; break; } var gia = (GenericInstSig)a; - result = Equals(gia.GenericType, b.GetGenericTypeDefinition()); - result = result && Equals(gia.GenericArguments, b.GetGenericArguments()); + result = Equals(gia.GenericType, b.GetGenericTypeDefinition(), null, false); + result = result && Equals(gia.GenericArguments, b.GetGenericArguments(), declaringType); break; case ElementType.CModReqd: case ElementType.CModOpt: - result = Equals(a.Next, b, treatAsGenericInst); + result = Equals(a.Next, b, declaringType); break; case ElementType.FnPtr: @@ -3518,7 +3518,9 @@ public bool Equals(ExportedType a, Type b) { /// true if we should treat /// as a generic instance type /// The hash code - public int GetHashCode(Type a, bool treatAsGenericInst) { + public int GetHashCode(Type a, bool treatAsGenericInst) => GetHashCode(a, null, treatAsGenericInst); + + int GetHashCode(Type a, Type declaringType, bool? treatAsGenericInst = null) { // ************************************************************************** // IMPORTANT: This hash code must match the TypeSig/TypeDef/TypeRef hash code // ************************************************************************** @@ -3528,7 +3530,8 @@ public int GetHashCode(Type a, bool treatAsGenericInst) { return 0; int hash; - switch (treatAsGenericInst ? ElementType.GenericInst : a.GetElementType2()) { + bool treatAsGenericInst2 = treatAsGenericInst ?? declaringType.MustTreatTypeAsGenericInstType(a); + switch (treatAsGenericInst2 ? ElementType.GenericInst : a.GetElementType2()) { case ElementType.Void: case ElementType.Boolean: case ElementType.Char: @@ -3562,30 +3565,30 @@ public int GetHashCode(Type a, bool treatAsGenericInst) { case ElementType.Ptr: hash = HASHCODE_MAGIC_ET_PTR + - (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType())); + (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType(), declaringType)); break; case ElementType.ByRef: hash = HASHCODE_MAGIC_ET_BYREF + - (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType())); + (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType(), declaringType)); break; case ElementType.SZArray: hash = HASHCODE_MAGIC_ET_SZARRAY + - (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType())); + (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType(), declaringType)); break; case ElementType.CModReqd: case ElementType.CModOpt: case ElementType.Pinned: - hash = GetHashCode(a.GetElementType()); + hash = GetHashCode(a.GetElementType(), declaringType); break; case ElementType.Array: // The type doesn't store sizes and lower bounds, so can't use them to // create the hash hash = HASHCODE_MAGIC_ET_ARRAY + a.GetArrayRank() + - (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType())); + (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType(), declaringType)); break; case ElementType.Var: @@ -3597,7 +3600,8 @@ public int GetHashCode(Type a, bool treatAsGenericInst) { break; case ElementType.GenericInst: - hash = HASHCODE_MAGIC_ET_GENERICINST + GetHashCode(a.GetGenericTypeDefinition()) + GetHashCode(a.GetGenericArguments()); + hash = HASHCODE_MAGIC_ET_GENERICINST + GetHashCode(a.GetGenericTypeDefinition(), false) + + GetHashCode(a.GetGenericArguments(), declaringType); break; case ElementType.ValueArray: @@ -3618,8 +3622,10 @@ public int GetHashCode(Type a, bool treatAsGenericInst) { /// Gets the hash code of a type list /// /// The type list + /// Root declaring type to check if we should + /// treat as a generic instance type /// The hash code - int GetHashCode(IList a) { + int GetHashCode(IList a, Type declaringType) { //************************************************************************ // IMPORTANT: This code must match any other GetHashCode(IList) //************************************************************************ @@ -3629,7 +3635,7 @@ int GetHashCode(IList a) { return 0; uint hash = 0; for (int i = 0; i < a.Count; i++) { - hash += (uint)GetHashCode(a[i]); + hash += (uint)GetHashCode(a[i], declaringType); hash = (hash << 13) | (hash >> 19); } recursionCounter.Decrement(); @@ -3684,8 +3690,10 @@ public int GetHashCode_TypeDef(Type a) { /// /// Type list #1 /// Type list #2 + /// Root declaring type to check if we should + /// treat as a generic instance type /// true if same, false otherwise - bool Equals(IList a, IList b) { + bool Equals(IList a, IList b, Type declaringType) { if ((object)a == (object)b) return true; // both are null if (a is null || b is null) @@ -3699,7 +3707,7 @@ bool Equals(IList a, IList b) { else { int i; for (i = 0; i < a.Count; i++) { - if (!Equals(a[i], b[i])) + if (!Equals(a[i], b[i], declaringType)) break; } result = i == a.Count; @@ -4006,6 +4014,7 @@ public bool Equals(MemberRef a, MethodBase b) { result = a.IsMethodRef && a.MethodSig.Generic; var oldOptions = ClearOptions(SigComparerOptions.CompareMethodFieldDeclaringType); + SetOptions(SigComparerOptions_DontSubstituteGenericParameters); result = result && Equals(a, b.Module.ResolveMethod(b.MetadataToken)); RestoreOptions(oldOptions); result = result && DeclaringTypeEquals(a, b); @@ -4020,7 +4029,7 @@ amSig is not null && (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)); GenericInstSig git; - if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { + if (!DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(amSig, b); @@ -4115,12 +4124,13 @@ public bool Equals(MethodSpec a, MethodBase b) { // declaring type (its declaring type is a generic type def). // NOTE: We must not push generic method args when comparing a.Method var oldOptions = ClearOptions(SigComparerOptions.CompareMethodFieldDeclaringType); + SetOptions(SigComparerOptions_DontSubstituteGenericParameters); result = result && Equals(a.Method, b.Module.ResolveMethod(b.MetadataToken)); RestoreOptions(oldOptions); result = result && DeclaringTypeEquals(a.Method, b); var gim = a.GenericInstMethodSig; - result = result && gim is not null && Equals(gim.GenericArguments, b.GetGenericArguments()); + result = result && gim is not null && Equals(gim.GenericArguments, b.GetGenericArguments(), b.DeclaringType); recursionCounter.Decrement(); return result; @@ -4197,8 +4207,7 @@ int GetHashCode_ReturnType(MethodBase a) { return GetHashCode(typeof(void)); } - int GetHashCode(ParameterInfo a, Type declaringType) => GetHashCode(a.ParameterType, declaringType.MustTreatTypeAsGenericInstType(a.ParameterType)); - int GetHashCode(Type a, Type declaringType) => GetHashCode(a, declaringType.MustTreatTypeAsGenericInstType(a)); + int GetHashCode(ParameterInfo a, Type declaringType) => GetHashCode(a.ParameterType, declaringType); /// /// Compares calling conventions @@ -4329,7 +4338,7 @@ bool Equals(TypeSig a, ParameterInfo b, Type declaringType) { return false; bool result = ModifiersEquals(a, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && - Equals(a2, b.ParameterType, declaringType.MustTreatTypeAsGenericInstType(b.ParameterType)); + Equals(a2, b.ParameterType, declaringType); recursionCounter.Decrement(); return result; @@ -4470,7 +4479,7 @@ bool Equals(FieldSig a, FieldInfo b) { return false; bool result = ModifiersEquals(a.Type, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && - Equals(a2, b.FieldType, b.DeclaringType.MustTreatTypeAsGenericInstType(b.FieldType)); + Equals(a2, b.FieldType, b.DeclaringType); recursionCounter.Decrement(); return result; @@ -4501,7 +4510,7 @@ public bool Equals(MemberRef a, FieldInfo b) { bool result = Equals_MethodFieldNames(a.Name, b.Name); GenericInstSig git; - if (SubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { + if (!DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(a.FieldSig, b); @@ -4583,7 +4592,7 @@ bool Equals(PropertySig a, PropertyInfo b) { return false; bool result = ModifiersEquals(a.RetType, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && - Equals(a2, b.PropertyType, b.DeclaringType.MustTreatTypeAsGenericInstType(b.PropertyType)); + Equals(a2, b.PropertyType, b.DeclaringType); recursionCounter.Decrement(); return result; @@ -4627,7 +4636,7 @@ public bool Equals(EventDef a, EventInfo b) { return false; bool result = Equals_EventNames(a.Name, b.Name) && - Equals(a.EventType, b.EventHandlerType, b.DeclaringType.MustTreatTypeAsGenericInstType(b.EventHandlerType)) && + Equals(a.EventType, b.EventHandlerType, b.DeclaringType) && (!CompareEventDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); recursionCounter.Decrement(); From a4afc155a81344b0d7f3ad7c8b9f1f07527abeb1 Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Mon, 30 May 2022 13:48:56 +0800 Subject: [PATCH 443/511] Fix #468 Don't substitute type generic arguments when don't compare declaring type. --- src/DotNet/SigComparer.cs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 5f22006bc..9dabd6826 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -2700,7 +2700,7 @@ public int GetHashCode(MemberRef a) { int hash = GetHashCode_MethodFieldName(a.Name); GenericInstSig git; - if (!DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { + if (CompareMethodFieldDeclaringType && !DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); hash += GetHashCode(a.Signature); @@ -3974,6 +3974,12 @@ public bool Equals(MethodSig a, MethodBase b) { if (!recursionCounter.Increment()) return false; + if (!CompareMethodFieldDeclaringType && b.DeclaringType.IsGenericButNotGenericTypeDefinition()) { + var t = b; + b = b.Module.ResolveMethod(b.MetadataToken); + if (b.IsGenericButNotGenericMethodDefinition()) + b = ((MethodInfo)b).MakeGenericMethod(t.GetGenericArguments()); + } bool result = Equals(a.GetCallingConvention(), b) && (DontCompareReturnType || ReturnTypeEquals(a.RetType, b)) && Equals(a.Params, b.GetParameters(), b.DeclaringType) && @@ -4029,7 +4035,7 @@ amSig is not null && (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)); GenericInstSig git; - if (!DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { + if (CompareMethodFieldDeclaringType && !DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(amSig, b); @@ -4166,6 +4172,12 @@ int GetHashCode_MethodSig(MethodBase a) { return 0; int hash; + if (!CompareMethodFieldDeclaringType && a.DeclaringType.IsGenericButNotGenericTypeDefinition()) { + var t = a; + a = a.Module.ResolveMethod(a.MetadataToken); + if (t.IsGenericButNotGenericMethodDefinition()) + a = ((MethodInfo)a).MakeGenericMethod(t.GetGenericArguments()); + } hash = GetHashCode_CallingConvention(a.CallingConvention, a.IsGenericMethod) + GetHashCode(a.GetParameters(), a.DeclaringType); if (!DontCompareReturnType) @@ -4478,6 +4490,8 @@ bool Equals(FieldSig a, FieldInfo b) { if (!recursionCounter.Increment()) return false; + if (!CompareMethodFieldDeclaringType && b.DeclaringType.IsGenericButNotGenericTypeDefinition()) + b = b.Module.ResolveField(b.MetadataToken); bool result = ModifiersEquals(a.Type, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && Equals(a2, b.FieldType, b.DeclaringType); @@ -4510,7 +4524,7 @@ public bool Equals(MemberRef a, FieldInfo b) { bool result = Equals_MethodFieldNames(a.Name, b.Name); GenericInstSig git; - if (!DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { + if (CompareMethodFieldDeclaringType && !DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { InitializeGenericArguments(); genericArguments.PushTypeArgs(git.GenericArguments); result = result && Equals(a.FieldSig, b); @@ -4555,6 +4569,8 @@ int GetHashCode_FieldSig(FieldInfo a) { return 0; int hash; + if (!CompareMethodFieldDeclaringType && a.DeclaringType.IsGenericButNotGenericTypeDefinition()) + a = a.Module.ResolveField(a.MetadataToken); hash = GetHashCode_CallingConvention(0, false) + GetHashCode(a.FieldType, a.DeclaringType); recursionCounter.Decrement(); From 6f4dc6f0a7f86dbe12449b74d5501daf1192c187 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 17 Jun 2022 21:09:50 +0200 Subject: [PATCH 444/511] Improvements to `DynamicMethodBodyReader` (#470) * Improved `RestoreMethod` behavior for `DynamicMethodBodyReader` * Added support for reading and restoring InitLocals property * Restore max stack * make `initLocals` field not nullable. `DynamicResolver`'s `m_method` field is always a `DynamicMethod` so a type check was unnecessary. --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 26ff4641f..d4ddd8604 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -62,6 +62,7 @@ public class DynamicMethodBodyReader : MethodBodyReaderBase, ISignatureReaderHel readonly MethodDef method; readonly int codeSize; readonly int maxStack; + readonly bool initLocals; readonly List tokens; readonly IList ehInfos; readonly byte[] ehHeader; @@ -172,8 +173,8 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, throw new Exception("RTDynamicMethod.m_owner is null or invalid"); } - if (obj is DynamicMethod) { - methodName = ((DynamicMethod)obj).Name; + if (obj is DynamicMethod dynMethod) { + methodName = dynMethod.Name; obj = dmResolverFieldInfo.Read(obj); if (obj is null) throw new Exception("No resolver found"); @@ -186,9 +187,10 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, if (code is null) throw new Exception("No code"); codeSize = code.Length; - var delMethod = rslvMethodFieldInfo.Read(obj) as SR.MethodBase; + var delMethod = rslvMethodFieldInfo.Read(obj) as DynamicMethod; if (delMethod is null) throw new Exception("No method"); + initLocals = delMethod.InitLocals; maxStack = (int)rslvMaxStackFieldInfo.Read(obj); var scope = rslvDynamicScopeFieldInfo.Read(obj); @@ -387,7 +389,6 @@ void CreateExceptionHandlers() { /// /// A new instance public MethodDef GetMethod() { - bool initLocals = true; var cilBody = new CilBody(initLocals, instructions, exceptionHandlers, locals); cilBody.MaxStack = (ushort)Math.Min(maxStack, ushort.MaxValue); instructions = null; @@ -534,6 +535,15 @@ object Resolve(uint index) { return tokens[(int)index]; } + /// + public override void RestoreMethod(MethodDef method) { + base.RestoreMethod(method); + + var body = method.Body; + body.InitLocals = initLocals; + body.MaxStack = (ushort)Math.Min(maxStack, ushort.MaxValue); + } + ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) return null; From bbbfb3c27c6fc07f5207f62e4f2398afc8ebbbfa Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Sun, 14 Aug 2022 01:01:27 +0800 Subject: [PATCH 445/511] Fix ArgumentOutOfRangeException --- src/DotNet/ICodedToken.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index a592c9ccf..975f95c90 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -613,7 +613,7 @@ static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { /// this /// Normal visible parameter index /// - public static TypeSig GetParam(this IMethod method, int index) => method?.MethodSig?.Params[index]; + public static TypeSig GetParam(this IMethod method, int index) => method?.MethodSig.GetParams() is { } types && index >= 0 && index < types.Count ? types[index] : null; } /// From e58fbfc34ec7d5a78c3f2f229bf6964de7f3bee8 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Sat, 10 Sep 2022 23:33:51 +0800 Subject: [PATCH 446/511] Don't create wrong TypeSig for TypeDef --- src/DotNet/ICodedToken.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index a592c9ccf..b7986c859 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -197,11 +197,11 @@ public static AssemblyRef ToAssemblyRef(this IAssembly asm) { /// Converts to a /// /// The type - /// true if we should try to figure out whether + /// true if we should try to resolve in order to figure out whether /// is a /// A instance or null if /// is invalid - public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType = true) { + public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool resolveToCheckValueType = true) { if (type is null) return null; @@ -214,10 +214,10 @@ public static TypeSig ToTypeSig(this ITypeDefOrRef type, bool checkValueType = t var td = type as TypeDef; if (td is not null) - return CreateClassOrValueType(type, checkValueType ? td.IsValueType : false); + return CreateClassOrValueType(type, td.IsValueType); if (type is TypeRef tr) { - if (checkValueType) + if (resolveToCheckValueType) td = tr.Resolve(); return CreateClassOrValueType(type, td is null ? false : td.IsValueType); } From e68aa72eadd394aa4610547de6c4509926d61b0b Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 11 Nov 2022 19:26:10 +0100 Subject: [PATCH 447/511] Add support for new Roslyn CustomDebugInfo --- src/DotNet/Pdb/CustomDebugInfoGuids.cs | 2 + src/DotNet/Pdb/PdbCustomDebugInfo.cs | 148 +++++++++++++++++- .../PortablePdbCustomDebugInfoReader.cs | 33 ++++ .../PortablePdbCustomDebugInfoWriter.cs | 30 ++++ 4 files changed, 210 insertions(+), 3 deletions(-) diff --git a/src/DotNet/Pdb/CustomDebugInfoGuids.cs b/src/DotNet/Pdb/CustomDebugInfoGuids.cs index 95acf760b..1002f6877 100644 --- a/src/DotNet/Pdb/CustomDebugInfoGuids.cs +++ b/src/DotNet/Pdb/CustomDebugInfoGuids.cs @@ -20,6 +20,8 @@ public static class CustomDebugInfoGuids { public static readonly Guid TupleElementNames = new Guid("ED9FDF71-8879-4747-8ED3-FE5EDE3CE710"); public static readonly Guid CompilationMetadataReferences = new Guid("7E4D4708-096E-4C5C-AEDA-CB10BA6A740D"); public static readonly Guid CompilationOptions = new Guid("B5FEEC05-8CD0-4A83-96DA-466284BB4BD8"); + public static readonly Guid TypeDefinitionDocuments = new Guid("932E74BC-DBA9-4478-8D46-0F32A7BAB3D3"); + public static readonly Guid EncStateMachineStateMap = new Guid("8B78CD68-2EDE-420B-980B-E15884B8AAA3"); #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 55909f8c6..62fdbbb53 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -111,6 +111,16 @@ public enum PdbCustomDebugInfoKind { /// /// CompilationOptions, + + /// + /// + /// + TypeDefinitionDocuments, + + /// + /// + /// + EditAndContinueStateMachineStateMap, } /// @@ -665,7 +675,7 @@ public sealed class PortablePdbTupleElementNamesCustomDebugInfo : PdbCustomDebug /// /// Async method stepping info - /// + /// /// It's internal and translated to a /// sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { @@ -777,9 +787,9 @@ public sealed class PdbEmbeddedSourceCustomDebugInfo : PdbCustomDebugInfo { /// /// Gets the source code blob. - /// + /// /// It's not decompressed and converted to a string because the encoding isn't specified. - /// + /// /// https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#embedded-source-c-and-vb-compilers /// public byte[] SourceCodeBlob { get; set; } @@ -1101,4 +1111,136 @@ public sealed class PdbCompilationOptionsCustomDebugInfo : PdbCustomDebugInfo { /// public PdbCompilationOptionsCustomDebugInfo() => Options = new List>(); } + + /// + /// Links a TypeDef with no method IL with a PDB document. + /// + public sealed class PdbTypeDefinitionDocumentsDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TypeDefinitionDocuments; + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid => CustomDebugInfoGuids.TypeDefinitionDocuments; + + /// + /// Document tokens. Only resolvable in debug metadata. + /// A token like this can be resolved by subtracting 1 from the RID and using it as an index into the + /// PdbState.Documents enumerable. + /// + public List DocumentTokens { get; } + + /// + /// Constructor + /// + public PdbTypeDefinitionDocumentsDebugInfo() => DocumentTokens = new List(); + } + + /// + /// Contains the EnC state machine state mapping + /// + public sealed class PdbEditAndContinueStateMachineStateMapDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap; + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid => CustomDebugInfoGuids.EncStateMachineStateMap; + + /// + /// State machine states + /// + public List StateMachineStates { get; } + + /// + /// Constructor + /// + public PdbEditAndContinueStateMachineStateMapDebugInfo() => StateMachineStates = new List(); + } + + /// + /// State machine state information used by debuggers + /// + public struct StateMachineStateInfo { + /// + /// Syntax offset + /// + public readonly int SyntaxOffset; + + /// + /// State machine state + /// + public readonly StateMachineState State; + + /// + /// Constructor + /// + /// Syntax offset + /// State machine state + public StateMachineStateInfo(int syntaxOffset, StateMachineState state) { + SyntaxOffset = syntaxOffset; + State = state; + } + } + + /// + /// State machine state + /// from Roslyn: StateMachineState.cs + /// + public enum StateMachineState { + /// + /// First state of an async iterator state machine that is used to resume the machine after yield return. + /// Initial state is not used to resume state machine that yielded. State numbers decrease as the iterator makes progress. + /// + FirstResumableAsyncIteratorState = InitialAsyncIteratorState - 1, + + /// + /// Initial iterator state of an async iterator. + /// Distinct from so that DisposeAsync can throw in latter case. + /// + InitialAsyncIteratorState = -3, + + /// + /// First state of an iterator state machine. State numbers decrease for subsequent finalize states. + /// + FirstIteratorFinalizeState = -3, + + /// + /// The last state of a state machine. + /// + FinishedState = -2, + + /// + /// State machine not started or is running + /// + NotStartedOrRunningState = -1, + + /// + /// First unused state + /// + FirstUnusedState = 0, + + /// + /// First state in async state machine that is used to resume the machine after await. + /// State numbers increase as the async computation makes progress. + /// + FirstResumableAsyncState = 0, + + /// + /// Initial iterator state of an iterator. + /// + InitialIteratorState = 0, + + /// + /// First state in iterator state machine that is used to resume the machine after yield return. + /// Initial state is not used to resume state machine that yielded. State numbers increase as the iterator makes progress. + /// + FirstResumableIteratorState = InitialIteratorState + 1, + } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index 68b61ee80..e9e1fa477 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -65,6 +65,10 @@ PdbCustomDebugInfo Read(Guid kind) { return ReadCompilationMetadataReferences(); if (kind == CustomDebugInfoGuids.CompilationOptions) return ReadCompilationOptions(); + if (kind == CustomDebugInfoGuids.TypeDefinitionDocuments) + return ReadTypeDefinitionDocuments(); + if (kind == CustomDebugInfoGuids.EncStateMachineStateMap) + return ReadEncStateMachineStateMap(); Debug.Fail("Unknown custom debug info guid: " + kind.ToString()); return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); } @@ -228,6 +232,35 @@ PdbCustomDebugInfo ReadCompilationOptions() { return cdi; } + PdbCustomDebugInfo ReadTypeDefinitionDocuments() { + var cdi = new PdbTypeDefinitionDocumentsDebugInfo(); + + while (reader.BytesLeft > 0) + cdi.DocumentTokens.Add(new MDToken(Table.Document, reader.ReadCompressedUInt32())); + + return cdi; + } + + PdbCustomDebugInfo ReadEncStateMachineStateMap() { + var cdi = new PdbEditAndContinueStateMachineStateMapDebugInfo(); + + var count = reader.ReadCompressedUInt32(); + if (count > 0) { + long syntaxOffsetBaseline = -reader.ReadCompressedUInt32(); + + while (count > 0) { + int stateNumber = reader.ReadCompressedInt32(); + int syntaxOffset = (int)(syntaxOffsetBaseline + reader.ReadCompressedUInt32()); + + cdi.StateMachineStates.Add(new StateMachineStateInfo(syntaxOffset, (StateMachineState)stateNumber)); + + count--; + } + } + + return cdi; + } + Instruction GetInstruction(uint offset) { var instructions = bodyOpt.Instructions; int lo = 0, hi = instructions.Count - 1; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 0729c602e..780f3ebfb 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -1,6 +1,8 @@ // dnlib: See LICENSE.txt for more info +using System; using System.IO; +using System.Linq; using System.Text; using dnlib.DotNet.Emit; using dnlib.DotNet.Writer; @@ -92,6 +94,14 @@ byte[] Write(PdbCustomDebugInfo cdi) { case PdbCustomDebugInfoKind.CompilationOptions: WriteCompilationOptions((PdbCompilationOptionsCustomDebugInfo)cdi); break; + + case PdbCustomDebugInfoKind.TypeDefinitionDocuments: + WriteTypeDefinitionDocuments((PdbTypeDefinitionDocumentsDebugInfo)cdi); + break; + + case PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap: + WriteEditAndContinueStateMachineStateMap((PdbEditAndContinueStateMachineStateMapDebugInfo)cdi); + break; } return outStream.ToArray(); } @@ -317,5 +327,25 @@ void WriteCompilationOptions(PdbCompilationOptionsCustomDebugInfo cdi) { WriteUTF8Z(kv.Value); } } + + void WriteTypeDefinitionDocuments(PdbTypeDefinitionDocumentsDebugInfo cdi) { + foreach (var docToken in cdi.DocumentTokens) + writer.WriteCompressedUInt32(docToken.Rid); + } + + void WriteEditAndContinueStateMachineStateMap(PdbEditAndContinueStateMachineStateMapDebugInfo cdi) { + writer.WriteCompressedUInt32((uint)cdi.StateMachineStates.Count); + + if (cdi.StateMachineStates.Count <= 0) + return; + + int syntaxOffsetBaseline = Math.Min(cdi.StateMachineStates.Min(state => state.SyntaxOffset), 0); + writer.WriteCompressedUInt32((uint)-syntaxOffsetBaseline); + + foreach (var state in cdi.StateMachineStates) { + writer.WriteCompressedInt32((int)state.State); + writer.WriteCompressedUInt32((uint)(state.SyntaxOffset - syntaxOffsetBaseline)); + } + } } } From 425941359b6fb525fcf1409d91dc0db37ae4266a Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 11 Nov 2022 19:32:30 +0100 Subject: [PATCH 448/511] Add support for boxed custom attribute arguments to `MemberFinder` --- src/DotNet/MemberFinder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/MemberFinder.cs b/src/DotNet/MemberFinder.cs index b6f9a25fb..926f7f324 100644 --- a/src/DotNet/MemberFinder.cs +++ b/src/DotNet/MemberFinder.cs @@ -283,6 +283,8 @@ void Add(CAArgument arg) { Add(typeSig); else if (arg.Value is IList args) Add(args); + else if(arg.Value is CAArgument boxedArgument) + Add(boxedArgument); } void Add(IEnumerable args) { From e666538fd1ec733f0af8c57a3a96f5582ea704c0 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 12 Nov 2022 11:47:56 +0100 Subject: [PATCH 449/511] Add missing switch cases --- src/DotNet/Writer/Metadata.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index df93b83e1..37bcc490a 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3384,6 +3384,8 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, case PdbCustomDebugInfoKind.SourceLink: case PdbCustomDebugInfoKind.CompilationMetadataReferences: case PdbCustomDebugInfoKind.CompilationOptions: + case PdbCustomDebugInfoKind.TypeDefinitionDocuments: + case PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap: AddCustomDebugInformationCore(serializerMethodContext, encodedToken, cdi, cdi.Guid); break; From 45d6e881bb6e2edbab1386d5252dad890e175440 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 15 Nov 2022 19:09:01 +0100 Subject: [PATCH 450/511] Addressed feedback --- src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs | 2 + src/DotNet/Pdb/Managed/DbiDocument.cs | 2 + src/DotNet/Pdb/PdbCustomDebugInfo.cs | 42 +++++++++++++++---- src/DotNet/Pdb/PdbState.cs | 5 ++- .../PortablePdbCustomDebugInfoReader.cs | 7 ++-- .../PortablePdbCustomDebugInfoWriter.cs | 4 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 8 ++-- src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs | 5 ++- src/DotNet/Pdb/Symbols/SymbolDocument.cs | 5 +++ 9 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs index 062f6820d..650797db3 100644 --- a/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolDocumentImpl.cs @@ -89,5 +89,7 @@ public override PdbCustomDebugInfo[] CustomDebugInfos { } } PdbCustomDebugInfo[] customDebugInfos; + + public override MDToken? MDToken => null; } } diff --git a/src/DotNet/Pdb/Managed/DbiDocument.cs b/src/DotNet/Pdb/Managed/DbiDocument.cs index b13f70d6f..fde9e87a3 100644 --- a/src/DotNet/Pdb/Managed/DbiDocument.cs +++ b/src/DotNet/Pdb/Managed/DbiDocument.cs @@ -38,6 +38,8 @@ public override PdbCustomDebugInfo[] CustomDebugInfos { } PdbCustomDebugInfo[] customDebugInfos; + public override MDToken? MDToken => null; + public DbiDocument(string url) { this.url = url; documentType = SymDocumentType.Text; diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 62fdbbb53..d92c25185 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Threading; using dnlib.DotNet.Emit; namespace dnlib.DotNet.Pdb { @@ -1115,7 +1116,7 @@ public sealed class PdbCompilationOptionsCustomDebugInfo : PdbCustomDebugInfo { /// /// Links a TypeDef with no method IL with a PDB document. /// - public sealed class PdbTypeDefinitionDocumentsDebugInfo : PdbCustomDebugInfo { + public class PdbTypeDefinitionDocumentsDebugInfo : PdbCustomDebugInfo { /// /// Returns /// @@ -1127,16 +1128,39 @@ public sealed class PdbTypeDefinitionDocumentsDebugInfo : PdbCustomDebugInfo { public override Guid Guid => CustomDebugInfoGuids.TypeDefinitionDocuments; /// - /// Document tokens. Only resolvable in debug metadata. - /// A token like this can be resolved by subtracting 1 from the RID and using it as an index into the - /// PdbState.Documents enumerable. + /// List of documents associated with the type /// - public List DocumentTokens { get; } + public IList Documents { + get { + if (documents is null) + InitializeDocuments(); + return documents; + } + } + /// + protected IList documents; + /// Initializes + protected virtual void InitializeDocuments() => + Interlocked.CompareExchange(ref documents, new List(), null); + } - /// - /// Constructor - /// - public PdbTypeDefinitionDocumentsDebugInfo() => DocumentTokens = new List(); + class PdbTypeDefinitionDocumentsDebugInfoMD : PdbTypeDefinitionDocumentsDebugInfo { + readonly ModuleDef readerModule; + readonly IList documentTokens; + + protected override void InitializeDocuments() { + var list = new List(documentTokens.Count); + for (var i = 0; i < documentTokens.Count; i++) { + if (readerModule.PdbState.tokenToDocument.TryGetValue(documentTokens[i], out var document)) + list.Add(document); + } + Interlocked.CompareExchange(ref documents, list, null); + } + + public PdbTypeDefinitionDocumentsDebugInfoMD(ModuleDef readerModule, IList documentTokens) { + this.readerModule = readerModule; + this.documentTokens = documentTokens; + } } /// diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 455c24d11..45ab7004c 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -15,6 +15,7 @@ namespace dnlib.DotNet.Pdb { public sealed class PdbState { readonly SymbolReader reader; readonly Dictionary docDict = new Dictionary(); + internal readonly Dictionary tokenToDocument = new Dictionary(); MethodDef userEntryPoint; readonly Compiler compiler; readonly PdbFileKind originalPdbFileKind; @@ -64,7 +65,7 @@ public bool HasDocuments { #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif - + } } @@ -133,6 +134,8 @@ PdbDocument Add_NoLock(SymbolDocument symDoc) { // Expensive part, can read source code etc doc.Initialize(symDoc); docDict.Add(doc, doc); + if (symDoc.MDToken.HasValue) + tokenToDocument.Add(symDoc.MDToken.Value, doc); return doc; } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index e9e1fa477..5a1e1705d 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -233,12 +233,11 @@ PdbCustomDebugInfo ReadCompilationOptions() { } PdbCustomDebugInfo ReadTypeDefinitionDocuments() { - var cdi = new PdbTypeDefinitionDocumentsDebugInfo(); - + var docList = new List(); while (reader.BytesLeft > 0) - cdi.DocumentTokens.Add(new MDToken(Table.Document, reader.ReadCompressedUInt32())); + docList.Add(new MDToken(Table.Document, reader.ReadCompressedUInt32())); - return cdi; + return new PdbTypeDefinitionDocumentsDebugInfoMD(module, docList); } PdbCustomDebugInfo ReadEncStateMachineStateMap() { diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 780f3ebfb..789d3ee4a 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -329,8 +329,8 @@ void WriteCompilationOptions(PdbCompilationOptionsCustomDebugInfo cdi) { } void WriteTypeDefinitionDocuments(PdbTypeDefinitionDocumentsDebugInfo cdi) { - foreach (var docToken in cdi.DocumentTokens) - writer.WriteCompressedUInt32(docToken.Rid); + foreach (var document in cdi.Documents) + writer.WriteCompressedUInt32(systemMetadata.GetRid(document)); } void WriteEditAndContinueStateMachineStateMap(PdbEditAndContinueStateMachineStateMapDebugInfo cdi) { diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index fc8fdec37..bae2ae621 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -61,7 +61,8 @@ SymbolDocument[] ReadDocuments() { var custInfos = ListCache.AllocList(); var gpContext = new GenericParamContext(); for (int i = 0; i < docs.Length; i++) { - bool b = pdbMetadata.TablesStream.TryReadDocumentRow((uint)i + 1, out var row); + uint rid = (uint)i + 1; + bool b = pdbMetadata.TablesStream.TryReadDocumentRow(rid, out var row); Debug.Assert(b); var url = nameReader.ReadDocumentName(row.Name); var language = pdbMetadata.GuidStream.Read(row.Language) ?? Guid.Empty; @@ -70,12 +71,13 @@ SymbolDocument[] ReadDocuments() { var checkSumAlgorithmId = pdbMetadata.GuidStream.Read(row.HashAlgorithm) ?? Guid.Empty; var checkSum = pdbMetadata.BlobStream.ReadNoNull(row.Hash); - var token = new MDToken(Table.Document, i + 1).ToInt32(); + var mdToken = new MDToken(Table.Document, rid); + var token = mdToken.ToInt32(); custInfos.Clear(); GetCustomDebugInfos(token, gpContext, custInfos); var custInfosArray = custInfos.Count == 0 ? Array2.Empty() : custInfos.ToArray(); - docs[i] = new SymbolDocumentImpl(url, language, languageVendor, documentType, checkSumAlgorithmId, checkSum, custInfosArray); + docs[i] = new SymbolDocumentImpl(url, language, languageVendor, documentType, checkSumAlgorithmId, checkSum, custInfosArray, mdToken); } ListCache.Free(ref custInfos); return docs; diff --git a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs index 7168d3c85..dce64fb4a 100644 --- a/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs +++ b/src/DotNet/Pdb/Portable/SymbolDocumentImpl.cs @@ -15,6 +15,7 @@ sealed class SymbolDocumentImpl : SymbolDocument { /*readonly*/ Guid checkSumAlgorithmId; readonly byte[] checkSum; readonly PdbCustomDebugInfo[] customDebugInfos; + MDToken mdToken; string GetDebuggerString() { var sb = new StringBuilder(); @@ -45,8 +46,9 @@ string GetDebuggerString() { public override Guid CheckSumAlgorithmId => checkSumAlgorithmId; public override byte[] CheckSum => checkSum; public override PdbCustomDebugInfo[] CustomDebugInfos => customDebugInfos; + public override MDToken? MDToken => mdToken; - public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum, PdbCustomDebugInfo[] customDebugInfos) { + public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid documentType, Guid checkSumAlgorithmId, byte[] checkSum, PdbCustomDebugInfo[] customDebugInfos, MDToken mdToken) { this.url = url; this.language = language; this.languageVendor = languageVendor; @@ -54,6 +56,7 @@ public SymbolDocumentImpl(string url, Guid language, Guid languageVendor, Guid d this.checkSumAlgorithmId = checkSumAlgorithmId; this.checkSum = checkSum; this.customDebugInfos = customDebugInfos; + this.mdToken = mdToken; } } } diff --git a/src/DotNet/Pdb/Symbols/SymbolDocument.cs b/src/DotNet/Pdb/Symbols/SymbolDocument.cs index ec12ded6b..58509969e 100644 --- a/src/DotNet/Pdb/Symbols/SymbolDocument.cs +++ b/src/DotNet/Pdb/Symbols/SymbolDocument.cs @@ -41,5 +41,10 @@ public abstract class SymbolDocument { /// Gets the custom debug infos /// public abstract PdbCustomDebugInfo[] CustomDebugInfos { get; } + + /// + /// Gets the Metadata token of the document if available. + /// + public abstract MDToken? MDToken { get; } } } From 5ac12c36daa56af996873cbed141381cfd809216 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Thu, 17 Nov 2022 18:54:16 +0100 Subject: [PATCH 451/511] Addressed feedback --- src/DotNet/Pdb/PdbCustomDebugInfo.cs | 10 ++++++---- src/DotNet/Pdb/PdbDocument.cs | 6 ++++++ src/DotNet/Pdb/PdbState.cs | 5 +++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index d92c25185..39f5853cf 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -1144,15 +1144,17 @@ protected virtual void InitializeDocuments() => Interlocked.CompareExchange(ref documents, new List(), null); } - class PdbTypeDefinitionDocumentsDebugInfoMD : PdbTypeDefinitionDocumentsDebugInfo { + sealed class PdbTypeDefinitionDocumentsDebugInfoMD : PdbTypeDefinitionDocumentsDebugInfo { readonly ModuleDef readerModule; readonly IList documentTokens; protected override void InitializeDocuments() { var list = new List(documentTokens.Count); - for (var i = 0; i < documentTokens.Count; i++) { - if (readerModule.PdbState.tokenToDocument.TryGetValue(documentTokens[i], out var document)) - list.Add(document); + if (readerModule.PdbState is not null) { + for (var i = 0; i < documentTokens.Count; i++) { + if (readerModule.PdbState.tokenToDocument.TryGetValue(documentTokens[i], out var document)) + list.Add(document); + } } Interlocked.CompareExchange(ref documents, list, null); } diff --git a/src/DotNet/Pdb/PdbDocument.cs b/src/DotNet/Pdb/PdbDocument.cs index b38fe311c..6f25bbe8c 100644 --- a/src/DotNet/Pdb/PdbDocument.cs +++ b/src/DotNet/Pdb/PdbDocument.cs @@ -53,6 +53,11 @@ public sealed class PdbDocument : IHasCustomDebugInformation { public IList CustomDebugInfos => customDebugInfos; IList customDebugInfos; + /// + /// Gets the Metadata token of the document if available. + /// + public MDToken? MDToken { get; internal set; } + /// /// Default constructor /// @@ -86,6 +91,7 @@ internal void Initialize(SymbolDocument symDoc) { customDebugInfos = new List(); foreach (var cdi in symDoc.CustomDebugInfos) customDebugInfos.Add(cdi); + MDToken = symDoc.MDToken; } /// diff --git a/src/DotNet/Pdb/PdbState.cs b/src/DotNet/Pdb/PdbState.cs index 45ab7004c..39146563f 100644 --- a/src/DotNet/Pdb/PdbState.cs +++ b/src/DotNet/Pdb/PdbState.cs @@ -124,6 +124,8 @@ PdbDocument Add_NoLock(PdbDocument doc) { if (docDict.TryGetValue(doc, out var orig)) return orig; docDict.Add(doc, doc); + if (doc.MDToken.HasValue) + tokenToDocument.Add(doc.MDToken.Value, doc); return doc; } @@ -148,6 +150,8 @@ public bool Remove(PdbDocument doc) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif + if (doc.MDToken.HasValue) + tokenToDocument.Remove(doc.MDToken.Value); return docDict.Remove(doc); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } @@ -189,6 +193,7 @@ public List RemoveAllDocuments(bool returnDocs) { theLock.EnterWriteLock(); try { #endif var docs = returnDocs ? new List(docDict.Values) : null; + tokenToDocument.Clear(); docDict.Clear(); return docs; #if THREAD_SAFE From 97e07a8f1ea0ccbf31231dad0f7cb093805b8eee Mon Sep 17 00:00:00 2001 From: wtfsck Date: Sat, 19 Nov 2022 14:35:54 +0100 Subject: [PATCH 452/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 8d9ef62e1..7445c7b09 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.5.0 + 3.6.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From b07706b9a0a3703b8913fa70ef55e5d53c4a541a Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 10 Jun 2023 22:15:43 +0200 Subject: [PATCH 453/511] Add rudimentary support for `DeserializingResourceReader` --- src/DotNet/Resources/ResourceElementSet.cs | 65 ++++++++++++++++++++++ src/DotNet/Resources/ResourceReader.cs | 31 +++++------ src/DotNet/Resources/ResourceWriter.cs | 12 +++- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index cee357b3e..25f172ac8 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Text.RegularExpressions; namespace dnlib.DotNet.Resources { /// @@ -10,6 +11,37 @@ namespace dnlib.DotNet.Resources { public sealed class ResourceElementSet { readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); + /// + /// The ResourceReader type name used by this set + /// + public string ResourceReaderTypeName { get; internal set; } + + /// + /// Gets whether is a DeserializingResourceReader + /// + public bool UsesDeserializingResourceReader => ResourceReaderTypeName is not null && Regex.IsMatch(ResourceReaderTypeName, @"^System\.Resources\.Extensions\.DeserializingResourceReader,\s*System\.Resources\.Extensions"); + + /// + /// The ResourceSet type name used by this set + /// + public string ResourceSetTypeName { get; internal set; } + + /// + /// Constructor for backwards compatibility only. Use Create methods instead. + /// + public ResourceElementSet() : this(null, null) { + } + + /// + /// Creates a new instance + /// + /// The ResourceReader type name to use + /// The ResourceSet type name to use + public ResourceElementSet(string resourceReaderTypeName, string resourceSetTypeName) { + ResourceReaderTypeName = resourceReaderTypeName; + ResourceSetTypeName = resourceSetTypeName; + } + /// /// Gets the number of elements in the set /// @@ -25,5 +57,38 @@ public sealed class ResourceElementSet { /// /// public void Add(ResourceElement elem) => dict[elem.Name] = elem; + + /// + /// Creates a new instance for a DeserializingResourceReader + /// + /// + public static ResourceElementSet CreateForDeserializingResourceReader(Version extensionAssemblyVersion) { + var extensionAssemblyFullName = $"System.Resources.Extensions, Version={extensionAssemblyVersion.ToString(4)}, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"; + return new ResourceElementSet($"System.Resources.Extensions.DeserializingResourceReader, {extensionAssemblyFullName}", $"System.Resources.Extensions.RuntimeResourceSet, {extensionAssemblyFullName}"); + } + + /// + /// Creates a new instance for a ResourceReader + /// + /// Module in which the set will reside + public static ResourceElementSet CreateForResourceReader(ModuleDef module) { + string mscorlibFullName; + if (module.CorLibTypes.AssemblyRef.Name == "mscorlib") { + // Use mscorlib reference found in module. + mscorlibFullName = module.CorLibTypes.AssemblyRef.FullName; + } + else { + // Use a reference to 4.0.0.0 mscorlib for compatibility with .NET Core and .NET 5 and later. + mscorlibFullName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; + } + return new ResourceElementSet($"System.Resources.ResourceReader, {mscorlibFullName}", "System.Resources.RuntimeResourceSet"); + } + + /// + /// Creates a new instance for a ResourceReader + /// + /// mscorlib assembly version + public static ResourceElementSet CreateForResourceReader(Version mscorlibVersion) => + new ResourceElementSet($"System.Resources.ResourceReader, mscorlib, Version={mscorlibVersion.ToString(4)}, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Resources.RuntimeResourceSet"); } } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 979e43a8d..badc57b93 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -95,7 +95,7 @@ ResourceElementSet Read() { uint sig = reader.ReadUInt32(); if (sig != 0xBEEFCACE) throw new ResourceReaderException($"Invalid resource sig: {sig:X8}"); - if (!CheckReaders()) + if (!CheckReaders(ref resources)) throw new ResourceReaderException("Invalid resource reader"); int version = reader.ReadInt32(); if (version != 2 && version != 1) @@ -247,24 +247,23 @@ static uint ReadUInt32(ref DataReader reader) { } } - bool CheckReaders() { - bool validReader = false; + bool CheckReaders(ref ResourceElementSet resources) { + int headerVersion = reader.ReadInt32(); + if (headerVersion != 1) + throw new ResourceReaderException($"Invalid or unsupported header version: {headerVersion}"); + int headerSize = reader.ReadInt32(); + if (headerSize < 0) + throw new ResourceReaderException($"Invalid header size: {headerSize:X8}"); - int numReaders = reader.ReadInt32(); - if (numReaders < 0) - throw new ResourceReaderException($"Invalid number of readers: {numReaders}"); - int readersSize = reader.ReadInt32(); - if (readersSize < 0) - throw new ResourceReaderException($"Invalid readers size: {readersSize:X8}"); + resources.ResourceReaderTypeName = reader.ReadSerializedString(); + resources.ResourceSetTypeName = reader.ReadSerializedString(); - for (int i = 0; i < numReaders; i++) { - var resourceReaderFullName = reader.ReadSerializedString(); - /*var resourceSetFullName = */reader.ReadSerializedString(); - if (Regex.IsMatch(resourceReaderFullName, @"^System\.Resources\.ResourceReader,\s*mscorlib")) - validReader = true; - } + if (Regex.IsMatch(resources.ResourceReaderTypeName, @"^System\.Resources\.ResourceReader,\s*mscorlib")) + return true; + if (Regex.IsMatch(resources.ResourceReaderTypeName, @"^System\.Resources\.Extensions\.DeserializingResourceReader,\s*System\.Resources\.Extensions")) + return true; - return validReader; + return false; } } } diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index 95944f275..5a3914544 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -120,9 +120,15 @@ void InitializeUserTypes() { void WriteReaderType() { var memStream = new MemoryStream(); var headerWriter = new BinaryWriter(memStream); - var mscorlibFullName = GetMscorlibFullname(); - headerWriter.Write("System.Resources.ResourceReader, " + mscorlibFullName); - headerWriter.Write("System.Resources.RuntimeResourceSet"); + if (resources.ResourceReaderTypeName is not null && resources.ResourceSetTypeName is not null) { + headerWriter.Write(resources.ResourceReaderTypeName); + headerWriter.Write(resources.ResourceSetTypeName); + } + else { + var mscorlibFullName = GetMscorlibFullname(); + headerWriter.Write("System.Resources.ResourceReader, " + mscorlibFullName); + headerWriter.Write("System.Resources.RuntimeResourceSet"); + } writer.Write((int)memStream.Position); writer.Write(memStream.ToArray()); } From 831661a991fafeead1812ea820fc4aa34dae0267 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 10 Jun 2023 22:18:15 +0200 Subject: [PATCH 454/511] Support new `PrimaryConstructorInformationBlob` Roslyn CDI --- src/DotNet/Pdb/CustomDebugInfoGuids.cs | 1 + src/DotNet/Pdb/PdbCustomDebugInfo.cs | 39 ++++++++++++++++++- .../PortablePdbCustomDebugInfoReader.cs | 5 +++ .../PortablePdbCustomDebugInfoWriter.cs | 13 +++++++ src/DotNet/Writer/Metadata.cs | 1 + 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Pdb/CustomDebugInfoGuids.cs b/src/DotNet/Pdb/CustomDebugInfoGuids.cs index 1002f6877..71342b5c8 100644 --- a/src/DotNet/Pdb/CustomDebugInfoGuids.cs +++ b/src/DotNet/Pdb/CustomDebugInfoGuids.cs @@ -22,6 +22,7 @@ public static class CustomDebugInfoGuids { public static readonly Guid CompilationOptions = new Guid("B5FEEC05-8CD0-4A83-96DA-466284BB4BD8"); public static readonly Guid TypeDefinitionDocuments = new Guid("932E74BC-DBA9-4478-8D46-0F32A7BAB3D3"); public static readonly Guid EncStateMachineStateMap = new Guid("8B78CD68-2EDE-420B-980B-E15884B8AAA3"); + public static readonly Guid PrimaryConstructorInformationBlob = new Guid("9D40ACE1-C703-4D0E-BF41-7243060A8FB5"); #pragma warning restore 1591 // Missing XML comment for publicly visible type or member } } diff --git a/src/DotNet/Pdb/PdbCustomDebugInfo.cs b/src/DotNet/Pdb/PdbCustomDebugInfo.cs index 39f5853cf..6b013d0cc 100644 --- a/src/DotNet/Pdb/PdbCustomDebugInfo.cs +++ b/src/DotNet/Pdb/PdbCustomDebugInfo.cs @@ -122,6 +122,11 @@ public enum PdbCustomDebugInfoKind { /// /// EditAndContinueStateMachineStateMap, + + /// + /// + /// + PrimaryConstructorInformationBlob, } /// @@ -1170,7 +1175,7 @@ public PdbTypeDefinitionDocumentsDebugInfoMD(ModuleDef readerModule, IList public sealed class PdbEditAndContinueStateMachineStateMapDebugInfo : PdbCustomDebugInfo { /// - /// Returns + /// Returns /// public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap; @@ -1269,4 +1274,36 @@ public enum StateMachineState { /// FirstResumableIteratorState = InitialIteratorState + 1, } + + /// + /// Primary constructor information blob + /// + public sealed class PrimaryConstructorInformationBlobDebugInfo : PdbCustomDebugInfo { + /// + /// Returns + /// + public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.PrimaryConstructorInformationBlob; + + /// + /// Gets the custom debug info guid, see + /// + public override Guid Guid => CustomDebugInfoGuids.PrimaryConstructorInformationBlob; + + /// + /// Gets the data blob + /// + public byte[] Blob { get; set; } + + /// + /// Constructor + /// + public PrimaryConstructorInformationBlobDebugInfo() { + } + + /// + /// Constructor + /// + /// Source server file contents + public PrimaryConstructorInformationBlobDebugInfo(byte[] blob) => Blob = blob; + } } diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index 5a1e1705d..87e5362f0 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -69,6 +69,8 @@ PdbCustomDebugInfo Read(Guid kind) { return ReadTypeDefinitionDocuments(); if (kind == CustomDebugInfoGuids.EncStateMachineStateMap) return ReadEncStateMachineStateMap(); + if (kind == CustomDebugInfoGuids.PrimaryConstructorInformationBlob) + return ReadPrimaryConstructorInformationBlob(); Debug.Fail("Unknown custom debug info guid: " + kind.ToString()); return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); } @@ -260,6 +262,9 @@ PdbCustomDebugInfo ReadEncStateMachineStateMap() { return cdi; } + PdbCustomDebugInfo ReadPrimaryConstructorInformationBlob() => + new PrimaryConstructorInformationBlobDebugInfo(reader.ReadRemainingBytes()); + Instruction GetInstruction(uint offset) { var instructions = bodyOpt.Instructions; int lo = 0, hi = instructions.Count - 1; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs index 789d3ee4a..27e143164 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs @@ -102,6 +102,10 @@ byte[] Write(PdbCustomDebugInfo cdi) { case PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap: WriteEditAndContinueStateMachineStateMap((PdbEditAndContinueStateMachineStateMapDebugInfo)cdi); break; + + case PdbCustomDebugInfoKind.PrimaryConstructorInformationBlob: + WritePrimaryConstructorInformationBlob((PrimaryConstructorInformationBlobDebugInfo)cdi); + break; } return outStream.ToArray(); } @@ -347,5 +351,14 @@ void WriteEditAndContinueStateMachineStateMap(PdbEditAndContinueStateMachineStat writer.WriteCompressedUInt32((uint)(state.SyntaxOffset - syntaxOffsetBaseline)); } } + + void WritePrimaryConstructorInformationBlob(PrimaryConstructorInformationBlobDebugInfo cdi) { + var d = cdi.Blob; + if (d is null) { + helper.Error("Primary constructor information blob is null"); + return; + } + writer.WriteBytes(d); + } } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 37bcc490a..d683548e9 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3386,6 +3386,7 @@ void AddCustomDebugInformation(SerializerMethodContext serializerMethodContext, case PdbCustomDebugInfoKind.CompilationOptions: case PdbCustomDebugInfoKind.TypeDefinitionDocuments: case PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap: + case PdbCustomDebugInfoKind.PrimaryConstructorInformationBlob: AddCustomDebugInformationCore(serializerMethodContext, encodedToken, cdi, cdi.Guid); break; From 07a11f9ae76791406bd54ba54fbbf7d9aa649476 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 25 Jun 2023 18:46:34 +0200 Subject: [PATCH 455/511] Fixed `Resolver` for `null` `TypeRef.ResolutionScope` --- src/DotNet/Resolver.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/DotNet/Resolver.cs b/src/DotNet/Resolver.cs index 8196d1061..067ff0672 100644 --- a/src/DotNet/Resolver.cs +++ b/src/DotNet/Resolver.cs @@ -64,6 +64,12 @@ public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { ResolveExportedType(new ModuleDef[] { resolvedModule }, typeRef, sourceModule); } + if (nonNestedResolutionScope is null) { + // ECMA II.22.38 states that in this case we should check ExportedTypes only. + // The CLR however checks both TypeDefs and ExportedTypes, with TypeDefs taking precedence. + return nonNestedModule.Find(typeRef) ?? ResolveExportedType(new ModuleDef[] { nonNestedModule }, typeRef, sourceModule); + } + return null; } From ef4dce24823fcf77688b1412001c7ab37f19d5f9 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 8 Jul 2023 11:47:13 +0200 Subject: [PATCH 456/511] Add support for .NET 8.0 to `DynamicMethodBodyReader` --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 4 ++-- src/DotNet/Emit/MethodTableToTypeConverter.cs | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index d4ddd8604..2eb65a5ec 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -32,7 +32,7 @@ public enum DynamicMethodBodyReaderOptions { /// public class DynamicMethodBodyReader : MethodBodyReaderBase, ISignatureReaderHelper { static readonly ReflectionFieldInfo rtdmOwnerFieldInfo = new ReflectionFieldInfo("m_owner"); - static readonly ReflectionFieldInfo dmResolverFieldInfo = new ReflectionFieldInfo("m_resolver"); + static readonly ReflectionFieldInfo dmResolverFieldInfo = new ReflectionFieldInfo("m_resolver", "_resolver"); static readonly ReflectionFieldInfo rslvCodeFieldInfo = new ReflectionFieldInfo("m_code"); static readonly ReflectionFieldInfo rslvDynamicScopeFieldInfo = new ReflectionFieldInfo("m_scope"); static readonly ReflectionFieldInfo rslvMethodFieldInfo = new ReflectionFieldInfo("m_method"); @@ -99,7 +99,7 @@ void InitializeField(Type type) { if (fieldInfo is not null) return; - var flags = SR.BindingFlags.Instance | SR.BindingFlags.Public | SR.BindingFlags.NonPublic; + const SR.BindingFlags flags = SR.BindingFlags.Instance | SR.BindingFlags.Public | SR.BindingFlags.NonPublic; fieldInfo = type.GetField(fieldName1, flags); if (fieldInfo is null && fieldName2 is not null) fieldInfo = type.GetField(fieldName2, flags); diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index 33cd68ea1..744977988 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -34,6 +34,9 @@ static MethodTableToTypeConverter() { #endif moduleBuilder = asmb.DefineDynamicModule("DynMod"); } + + // In .NET 8+, ILGenerator is an abstract class and the actual ILGenerator implementation is found in RuntimeILGenerator. + localSignatureFieldInfo ??= Type.GetType("System.Reflection.Emit.RuntimeILGenerator")?.GetField("m_localSignature", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); } /// From a41b1eb99a9f87bbb4849a352c0fc417360546ab Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 8 Jul 2023 11:48:13 +0200 Subject: [PATCH 457/511] Add support for reading `DynamicMethod`s created using `DynamicILInfo` --- src/DotNet/Emit/DynamicMethodBodyReader.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Emit/DynamicMethodBodyReader.cs b/src/DotNet/Emit/DynamicMethodBodyReader.cs index 2eb65a5ec..a90ff326c 100644 --- a/src/DotNet/Emit/DynamicMethodBodyReader.cs +++ b/src/DotNet/Emit/DynamicMethodBodyReader.cs @@ -55,6 +55,8 @@ public class DynamicMethodBodyReader : MethodBodyReaderBase, ISignatureReaderHel static readonly ReflectionFieldInfo ehEndFinallyFieldInfo = new ReflectionFieldInfo("m_endFinally"); static readonly ReflectionFieldInfo vamMethodFieldInfo = new ReflectionFieldInfo("m_method"); static readonly ReflectionFieldInfo vamDynamicMethodFieldInfo = new ReflectionFieldInfo("m_dynamicMethod"); + static readonly ReflectionFieldInfo dmDynamicILInfoFieldInfo = new ReflectionFieldInfo("m_DynamicILInfo", "_dynamicILInfo"); + static readonly ReflectionFieldInfo dynILInfoMaxStackFieldInfo = new ReflectionFieldInfo("m_maxStackSize"); readonly ModuleDef module; readonly Importer importer; @@ -175,13 +177,15 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, if (obj is DynamicMethod dynMethod) { methodName = dynMethod.Name; - obj = dmResolverFieldInfo.Read(obj); + obj = dmResolverFieldInfo.Read(obj) ?? dmDynamicILInfoFieldInfo.Read(obj);; if (obj is null) throw new Exception("No resolver found"); } - if (obj.GetType().ToString() != "System.Reflection.Emit.DynamicResolver") - throw new Exception("Couldn't find DynamicResolver"); + string objTypeName = obj.GetType().ToString(); + bool isILInfo = objTypeName == "System.Reflection.Emit.DynamicILInfo"; + if (objTypeName != "System.Reflection.Emit.DynamicResolver" && !isILInfo) + throw new Exception("Couldn't find DynamicResolver or DynamicILInfo"); var code = rslvCodeFieldInfo.Read(obj) as byte[]; if (code is null) @@ -191,7 +195,7 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, if (delMethod is null) throw new Exception("No method"); initLocals = delMethod.InitLocals; - maxStack = (int)rslvMaxStackFieldInfo.Read(obj); + maxStack = isILInfo ? (int)dynILInfoMaxStackFieldInfo.Read(obj) : (int)rslvMaxStackFieldInfo.Read(obj); var scope = rslvDynamicScopeFieldInfo.Read(obj); if (scope is null) @@ -203,8 +207,12 @@ public DynamicMethodBodyReader(ModuleDef module, object obj, Importer importer, for (int i = 0; i < tokensList.Count; i++) tokens.Add(tokensList[i]); - ehInfos = (IList)rslvExceptionsFieldInfo.Read(obj); - ehHeader = rslvExceptionHeaderFieldInfo.Read(obj) as byte[]; + if (isILInfo) + ehHeader = rslvExceptionsFieldInfo.Read(obj) as byte[]; + else { + ehInfos = (IList)rslvExceptionsFieldInfo.Read(obj); + ehHeader = rslvExceptionHeaderFieldInfo.Read(obj) as byte[]; + } UpdateLocals(rslvLocalsFieldInfo.Read(obj) as byte[]); reader = ByteArrayDataReaderFactory.CreateReader(code); From 7f916e39ff11f220f0c172417fb949738d99e48d Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 9 Jul 2023 21:49:44 +0200 Subject: [PATCH 458/511] Expose `WinMDHelpers` class --- src/DotNet/WinMDHelpers.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/DotNet/WinMDHelpers.cs b/src/DotNet/WinMDHelpers.cs index 31f0090e5..2211269aa 100644 --- a/src/DotNet/WinMDHelpers.cs +++ b/src/DotNet/WinMDHelpers.cs @@ -14,7 +14,10 @@ enum ClrAssembly { SystemRuntimeWindowsRuntimeUIXaml, } - static class WinMDHelpers { + /// + /// Helper class to project WinMD types to CLR types + /// + public static class WinMDHelpers { readonly struct ClassName : IEquatable { public readonly UTF8String Namespace; public readonly UTF8String Name; From f2b83cf1801ac10394282eb5da8262f112472929 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 9 Jul 2023 22:03:21 +0200 Subject: [PATCH 459/511] Add `DataStream` `Read` methods for signed integer types --- src/IO/DataReader.cs | 48 ++++++++++++++++++++++++++++++++++++++++---- src/IO/DataStream.cs | 28 ++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 33a99b7fe..61925ee14 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -192,7 +192,17 @@ public readonly DataReader Slice(int start) { /// Reads a /// /// - public sbyte ReadSByte() => (sbyte)ReadByte(); + public sbyte ReadSByte() { + VerifyState(); + const uint SIZE = 1; + var currentOffset = this.currentOffset; + if (currentOffset == endOffset) + ThrowNoMoreBytesLeft(); + var value = stream.ReadSByte(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; + } /// /// Reads a @@ -214,7 +224,17 @@ public byte ReadByte() { /// Reads a /// /// - public short ReadInt16() => (short)ReadUInt16(); + public short ReadInt16() { + VerifyState(); + const uint SIZE = 2; + var currentOffset = this.currentOffset; + if (endOffset - currentOffset < SIZE) + ThrowNoMoreBytesLeft(); + var value = stream.ReadInt16(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; + } /// /// Reads a @@ -236,7 +256,17 @@ public ushort ReadUInt16() { /// Reads a /// /// - public int ReadInt32() => (int)ReadUInt32(); + public int ReadInt32() { + VerifyState(); + const uint SIZE = 4; + var currentOffset = this.currentOffset; + if (endOffset - currentOffset < SIZE) + ThrowNoMoreBytesLeft(); + var value = stream.ReadInt32(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; + } /// /// Reads a @@ -291,7 +321,17 @@ internal uint Unsafe_ReadUInt32() { /// Reads a /// /// - public long ReadInt64() => (long)ReadUInt64(); + public long ReadInt64() { + VerifyState(); + const uint SIZE = 8; + var currentOffset = this.currentOffset; + if (endOffset - currentOffset < SIZE) + ThrowNoMoreBytesLeft(); + var value = stream.ReadInt64(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; + } /// /// Reads a diff --git a/src/IO/DataStream.cs b/src/IO/DataStream.cs index 654374a3b..bd3272ba7 100644 --- a/src/IO/DataStream.cs +++ b/src/IO/DataStream.cs @@ -34,6 +34,13 @@ public abstract class DataStream { /// public abstract byte ReadByte(uint offset); + /// + /// Reads a + /// + /// Offset of data + /// + public virtual sbyte ReadSByte(uint offset) => (sbyte)ReadByte(offset); + /// /// Reads a /// @@ -41,6 +48,13 @@ public abstract class DataStream { /// public abstract ushort ReadUInt16(uint offset); + /// + /// Reads a + /// + /// Offset of data + /// + public virtual short ReadInt16(uint offset) => (short)ReadUInt16(offset); + /// /// Reads a /// @@ -48,6 +62,13 @@ public abstract class DataStream { /// public abstract uint ReadUInt32(uint offset); + /// + /// Reads a + /// + /// Offset of data + /// + public virtual int ReadInt32(uint offset) => (int)ReadUInt32(offset); + /// /// Reads a /// @@ -55,6 +76,13 @@ public abstract class DataStream { /// public abstract ulong ReadUInt64(uint offset); + /// + /// Reads a + /// + /// Offset of data + /// + public virtual long ReadInt64(uint offset) => (long)ReadUInt64(offset); + /// /// Reads a /// From 5fc897a32e4f251761bbd7149cd2f724b7f8116d Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 9 Jul 2023 22:29:22 +0200 Subject: [PATCH 460/511] Add `DataStream` `Read` methods for `char`, `bool`, and `decimal` --- src/IO/DataReader.cs | 40 +++++++++++++++++++++++++++++++--------- src/IO/DataStream.cs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 61925ee14..8ab81aa7f 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -180,13 +180,33 @@ public readonly DataReader Slice(int start) { /// Reads a /// /// - public bool ReadBoolean() => ReadByte() != 0; + public bool ReadBoolean() { + VerifyState(); + const uint SIZE = 1; + var currentOffset = this.currentOffset; + if (currentOffset == endOffset) + ThrowNoMoreBytesLeft(); + var value = stream.ReadBoolean(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; + } /// /// Reads a /// /// - public char ReadChar() => (char)ReadUInt16(); + public char ReadChar() { + VerifyState(); + const uint SIZE = 2; + var currentOffset = this.currentOffset; + if (endOffset - currentOffset < SIZE) + ThrowNoMoreBytesLeft(); + var value = stream.ReadChar(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; + } /// /// Reads a @@ -402,13 +422,15 @@ public Guid ReadGuid() { /// /// public decimal ReadDecimal() { - var bits = new int[4] { - ReadInt32(), // lo - ReadInt32(), // mid - ReadInt32(), // hi - ReadInt32(), // flags - }; - return new decimal(bits); + VerifyState(); + const uint SIZE = 16; + var currentOffset = this.currentOffset; + if (endOffset - currentOffset < SIZE) + ThrowNoMoreBytesLeft(); + var value = stream.ReadDecimal(currentOffset); + this.currentOffset = currentOffset + SIZE; + VerifyState(); + return value; } /// diff --git a/src/IO/DataStream.cs b/src/IO/DataStream.cs index bd3272ba7..6bdb959a2 100644 --- a/src/IO/DataStream.cs +++ b/src/IO/DataStream.cs @@ -41,6 +41,13 @@ public abstract class DataStream { /// public virtual sbyte ReadSByte(uint offset) => (sbyte)ReadByte(offset); + /// + /// Reads a 1-byte-long + /// + /// Offset of data + /// + public virtual bool ReadBoolean(uint offset) => ReadByte(offset) != 0; + /// /// Reads a /// @@ -55,6 +62,13 @@ public abstract class DataStream { /// public virtual short ReadInt16(uint offset) => (short)ReadUInt16(offset); + /// + /// Reads a 2-byte-long + /// + /// Offset of data + /// + public virtual char ReadChar(uint offset) => (char)ReadUInt16(offset); + /// /// Reads a /// @@ -107,6 +121,22 @@ public virtual Guid ReadGuid(uint offset) => ReadByte(offset + 8), ReadByte(offset + 9), ReadByte(offset + 10), ReadByte(offset + 11), ReadByte(offset + 12), ReadByte(offset + 13), ReadByte(offset + 14), ReadByte(offset + 15)); + /// + /// Reads a + /// + /// Offset of data + /// + public virtual decimal ReadDecimal(uint offset) { + int lo = ReadInt32(offset); + int mid = ReadInt32(offset + 4); + int hi = ReadInt32(offset + 8); + int flags = ReadInt32(offset + 12); + + byte scale = (byte)(flags >> 16); + bool isNegative = (flags & 0x80000000) != 0; + return new decimal(lo, mid, hi, isNegative, scale); + } + /// /// Reads a UTF-16 encoded /// From e636c16f3c4d0deab8d644bb50f25a50bb672bfd Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 10 Jul 2023 14:47:01 +0200 Subject: [PATCH 461/511] Introduce proper read/write support for `DeserializingResourceReader` --- src/DotNet/Resources/BuiltInResourceData.cs | 12 ++- src/DotNet/Resources/IResourceData.cs | 2 +- src/DotNet/Resources/ResourceBinaryWriter.cs | 27 ++++++ src/DotNet/Resources/ResourceDataFactory.cs | 6 +- src/DotNet/Resources/ResourceElementSet.cs | 31 ++++--- src/DotNet/Resources/ResourceReader.cs | 91 ++++++++++---------- src/DotNet/Resources/ResourceReaderType.cs | 15 ++++ src/DotNet/Resources/ResourceWriter.cs | 21 ++--- src/DotNet/Resources/UserResourceData.cs | 59 +++++++++++-- 9 files changed, 178 insertions(+), 86 deletions(-) create mode 100644 src/DotNet/Resources/ResourceBinaryWriter.cs create mode 100644 src/DotNet/Resources/ResourceReaderType.cs diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index f3cb8f794..9e1417bd0 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -21,10 +21,10 @@ public sealed class BuiltInResourceData : IResourceData { /// public ResourceTypeCode Code => code; - /// + /// public FileOffset StartOffset { get; set; } - /// + /// public FileOffset EndOffset { get; set; } /// @@ -38,7 +38,7 @@ public BuiltInResourceData(ResourceTypeCode code, object data) { } /// - public void WriteData(BinaryWriter writer, IFormatter formatter) { + public void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { switch (code) { case ResourceTypeCode.Null: break; @@ -100,7 +100,11 @@ public void WriteData(BinaryWriter writer, IFormatter formatter) { break; case ResourceTypeCode.DateTime: - writer.Write(((DateTime)data).ToBinary()); + var dateTime = (DateTime)data; + if (writer.FormatVersion == 1) + writer.Write(dateTime.Ticks); + else + writer.Write(dateTime.ToBinary()); break; case ResourceTypeCode.TimeSpan: diff --git a/src/DotNet/Resources/IResourceData.cs b/src/DotNet/Resources/IResourceData.cs index e6062de25..8ec368bb4 100644 --- a/src/DotNet/Resources/IResourceData.cs +++ b/src/DotNet/Resources/IResourceData.cs @@ -30,6 +30,6 @@ public interface IResourceData : IFileSection { /// /// Writer /// Formatter if needed by implementer - void WriteData(BinaryWriter writer, IFormatter formatter); + void WriteData(ResourceBinaryWriter writer, IFormatter formatter); } } diff --git a/src/DotNet/Resources/ResourceBinaryWriter.cs b/src/DotNet/Resources/ResourceBinaryWriter.cs new file mode 100644 index 000000000..b0c1e09dc --- /dev/null +++ b/src/DotNet/Resources/ResourceBinaryWriter.cs @@ -0,0 +1,27 @@ +using System.IO; + +namespace dnlib.DotNet.Resources { + /// + /// Extension of for writing resource set elements + /// + public sealed class ResourceBinaryWriter : BinaryWriter { + /// + /// Format version of the resource set + /// + public int FormatVersion { get; internal set; } + + /// + /// Specifies the target reader type of the resource set + /// + public ResourceReaderType ReaderType { get; internal set; } + + /// + public ResourceBinaryWriter(Stream stream) : base(stream) { } + + /// + /// Writes a 7-bit encoded integer. + /// + /// The value to write + public new void Write7BitEncodedInt(int value) => base.Write7BitEncodedInt(value); + } +} diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index d2a04993b..83548763c 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -173,18 +173,18 @@ public ResourceDataFactory(ModuleDef module) { /// Serialized data /// Type of serialized data /// - public BinaryResourceData CreateSerialized(byte[] value, UserResourceType type) => new BinaryResourceData(CreateUserResourceType(type.Name, true), value); + public BinaryResourceData CreateSerialized(byte[] value, SerializationFormat format, UserResourceType type) => new BinaryResourceData(CreateUserResourceType(type.Name, true), value, format); /// /// Creates serialized data /// /// Serialized data /// - public BinaryResourceData CreateSerialized(byte[] value) { + public BinaryResourceData CreateBinaryFormatterSerialized(byte[] value) { if (!GetSerializedTypeAndAssemblyName(value, out var assemblyName, out var typeName)) throw new ApplicationException("Could not get serialized type name"); string fullName = $"{typeName}, {assemblyName}"; - return new BinaryResourceData(CreateUserResourceType(fullName), value); + return new BinaryResourceData(CreateUserResourceType(fullName), value, SerializationFormat.BinaryFormatter); } sealed class MyBinder : SerializationBinder { diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index 25f172ac8..6b559d34d 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -2,44 +2,47 @@ using System; using System.Collections.Generic; -using System.Text.RegularExpressions; namespace dnlib.DotNet.Resources { /// /// Resource element set /// public sealed class ResourceElementSet { + internal const string DeserializingResourceReaderTypeNameRegex = @"^System\.Resources\.Extensions\.DeserializingResourceReader,\s*System\.Resources\.Extensions"; + internal const string ResourceReaderTypeNameRegex = @"^System\.Resources\.ResourceReader,\s*mscorlib"; + readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); /// /// The ResourceReader type name used by this set /// - public string ResourceReaderTypeName { get; internal set; } + public string ResourceReaderTypeName { get; } /// - /// Gets whether is a DeserializingResourceReader + /// The ResourceSet type name used by this set /// - public bool UsesDeserializingResourceReader => ResourceReaderTypeName is not null && Regex.IsMatch(ResourceReaderTypeName, @"^System\.Resources\.Extensions\.DeserializingResourceReader,\s*System\.Resources\.Extensions"); + public string ResourceSetTypeName { get; } /// - /// The ResourceSet type name used by this set + /// The type of resource reader used to read this set /// - public string ResourceSetTypeName { get; internal set; } + public ResourceReaderType ReaderType { get; } /// - /// Constructor for backwards compatibility only. Use Create methods instead. + /// Format version of the resource set /// - public ResourceElementSet() : this(null, null) { - } + public int FormatVersion { get; internal set; } /// /// Creates a new instance /// /// The ResourceReader type name to use /// The ResourceSet type name to use - public ResourceElementSet(string resourceReaderTypeName, string resourceSetTypeName) { + /// + internal ResourceElementSet(string resourceReaderTypeName, string resourceSetTypeName, ResourceReaderType readerType) { ResourceReaderTypeName = resourceReaderTypeName; ResourceSetTypeName = resourceSetTypeName; + ReaderType = readerType; } /// @@ -64,7 +67,7 @@ public ResourceElementSet(string resourceReaderTypeName, string resourceSetTypeN /// public static ResourceElementSet CreateForDeserializingResourceReader(Version extensionAssemblyVersion) { var extensionAssemblyFullName = $"System.Resources.Extensions, Version={extensionAssemblyVersion.ToString(4)}, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"; - return new ResourceElementSet($"System.Resources.Extensions.DeserializingResourceReader, {extensionAssemblyFullName}", $"System.Resources.Extensions.RuntimeResourceSet, {extensionAssemblyFullName}"); + return new ResourceElementSet($"System.Resources.Extensions.DeserializingResourceReader, {extensionAssemblyFullName}", $"System.Resources.Extensions.RuntimeResourceSet, {extensionAssemblyFullName}", ResourceReaderType.DeserializingResourceReader); } /// @@ -78,10 +81,10 @@ public static ResourceElementSet CreateForResourceReader(ModuleDef module) { mscorlibFullName = module.CorLibTypes.AssemblyRef.FullName; } else { - // Use a reference to 4.0.0.0 mscorlib for compatibility with .NET Core and .NET 5 and later. + // Use a reference to 4.0.0.0 mscorlib for compatibility with .NET Core, .NET 5, and later. mscorlibFullName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } - return new ResourceElementSet($"System.Resources.ResourceReader, {mscorlibFullName}", "System.Resources.RuntimeResourceSet"); + return new ResourceElementSet($"System.Resources.ResourceReader, {mscorlibFullName}", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader); } /// @@ -89,6 +92,6 @@ public static ResourceElementSet CreateForResourceReader(ModuleDef module) { /// /// mscorlib assembly version public static ResourceElementSet CreateForResourceReader(Version mscorlibVersion) => - new ResourceElementSet($"System.Resources.ResourceReader, mscorlib, Version={mscorlibVersion.ToString(4)}, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Resources.RuntimeResourceSet"); + new ResourceElementSet($"System.Resources.ResourceReader, mscorlib, Version={mscorlibVersion.ToString(4)}, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader); } } diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index badc57b93..2f5c094f8 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.Serialization; using System.Text; using System.Text.RegularExpressions; @@ -45,7 +46,7 @@ public ResourceReaderException(SerializationInfo info, StreamingContext context) /// Serialized type /// Serialized data /// - public delegate IResourceData CreateResourceDataDelegate(ResourceDataFactory resourceDataFactory, UserResourceType type, byte[] serializedData); + public delegate IResourceData CreateResourceDataDelegate(ResourceDataFactory resourceDataFactory, UserResourceType type, byte[] serializedData, SerializationFormat format); /// /// Reads .NET resources @@ -90,16 +91,15 @@ public static ResourceElementSet Read(ModuleDef module, DataReader reader, Creat new ResourceReader(module, ref reader, createResourceDataDelegate).Read(); ResourceElementSet Read() { - var resources = new ResourceElementSet(); - uint sig = reader.ReadUInt32(); if (sig != 0xBEEFCACE) throw new ResourceReaderException($"Invalid resource sig: {sig:X8}"); - if (!CheckReaders(ref resources)) + var resources = ReadHeader(); + if (resources is null) throw new ResourceReaderException("Invalid resource reader"); - int version = reader.ReadInt32(); - if (version != 2 && version != 1) - throw new ResourceReaderException($"Invalid resource version: {version}"); + resources.FormatVersion = reader.ReadInt32(); + if (resources.FormatVersion != 2 && resources.FormatVersion != 1) + throw new ResourceReaderException($"Invalid resource version: {resources.FormatVersion}"); int numResources = reader.ReadInt32(); if (numResources < 0) throw new ResourceReaderException($"Invalid number of resources: {numResources}"); @@ -141,8 +141,9 @@ ResourceElementSet Read() { reader.Position = (uint)info.offset; long nextDataOffset = i == infos.Count - 1 ? end : infos[i + 1].offset; int size = (int)(nextDataOffset - info.offset); - element.ResourceData = - version == 1 ? ReadResourceDataV1(userTypes, size) : ReadResourceDataV2(userTypes, size); + element.ResourceData = resources.FormatVersion == 1 + ? ReadResourceDataV1(userTypes, resources.ReaderType, size) + : ReadResourceDataV2(userTypes, resources.ReaderType, size); element.ResourceData.StartOffset = baseFileOffset + (FileOffset)info.offset; element.ResourceData.EndOffset = baseFileOffset + (FileOffset)reader.Position; @@ -153,8 +154,8 @@ ResourceElementSet Read() { } sealed class ResourceInfo { - public string name; - public long offset; + public readonly string name; + public readonly long offset; public ResourceInfo(string name, long offset) { this.name = name; this.offset = offset; @@ -162,9 +163,9 @@ public ResourceInfo(string name, long offset) { public override string ToString() => $"{offset:X8} - {name}"; } - IResourceData ReadResourceDataV2(List userTypes, int size) { + IResourceData ReadResourceDataV2(List userTypes, ResourceReaderType readerType, int size) { uint endPos = reader.Position + (uint)size; - uint code = ReadUInt32(ref reader); + uint code = reader.Read7BitEncodedUInt32(); switch ((ResourceTypeCode)code) { case ResourceTypeCode.Null: return resourceDataFactory.CreateNull(); case ResourceTypeCode.String: return resourceDataFactory.Create(reader.ReadSerializedString()); @@ -189,13 +190,13 @@ IResourceData ReadResourceDataV2(List userTypes, int size) { int userTypeIndex = (int)(code - (uint)ResourceTypeCode.UserTypes); if (userTypeIndex < 0 || userTypeIndex >= userTypes.Count) throw new ResourceReaderException($"Invalid resource data code: {code}"); - return ReadSerializedObject(endPos, userTypes[userTypeIndex]); + return ReadSerializedObject(endPos, readerType, userTypes[userTypeIndex]); } } - IResourceData ReadResourceDataV1(List userTypes, int size) { + IResourceData ReadResourceDataV1(List userTypes, ResourceReaderType readerType, int size) { uint endPos = reader.Position + (uint)size; - int typeIndex = ReadInt32(ref reader); + int typeIndex = reader.Read7BitEncodedInt32(); if (typeIndex == -1) return resourceDataFactory.CreateNull(); if (typeIndex < 0 || typeIndex >= userTypes.Count) @@ -219,35 +220,32 @@ IResourceData ReadResourceDataV1(List userTypes, int size) { case "System.TimeSpan": return resourceDataFactory.Create(new TimeSpan(reader.ReadInt64())); case "System.Decimal": return resourceDataFactory.Create(reader.ReadDecimal()); default: - return ReadSerializedObject(endPos, type); - } - } - - IResourceData ReadSerializedObject(uint endPos, UserResourceType type) { - var serializedData = reader.ReadBytes((int)(endPos - reader.Position)); - var res = createResourceDataDelegate?.Invoke(resourceDataFactory, type, serializedData); - return res ?? resourceDataFactory.CreateSerialized(serializedData, type); - } - - static int ReadInt32(ref DataReader reader) { - try { - return reader.Read7BitEncodedInt32(); - } - catch { - throw new ResourceReaderException("Invalid encoded int32"); + return ReadSerializedObject(endPos, readerType, type); } } - static uint ReadUInt32(ref DataReader reader) { - try { - return reader.Read7BitEncodedUInt32(); + IResourceData ReadSerializedObject(uint endPos, ResourceReaderType readerType, UserResourceType type) { + byte[] serializedData; + IResourceData res; + switch (readerType) { + case ResourceReaderType.ResourceReader: + serializedData = reader.ReadBytes((int)(endPos - reader.Position)); + res = createResourceDataDelegate?.Invoke(resourceDataFactory, type, serializedData, SerializationFormat.BinaryFormatter); + return res ?? resourceDataFactory.CreateSerialized(serializedData, SerializationFormat.BinaryFormatter, type); + case ResourceReaderType.DeserializingResourceReader: { + var format = (SerializationFormat)reader.Read7BitEncodedInt32(); + int length = reader.Read7BitEncodedInt32(); + Debug.Assert(length == (int)(endPos - reader.Position)); + serializedData = reader.ReadBytes(length); + res = createResourceDataDelegate?.Invoke(resourceDataFactory, type, serializedData, format); + return res ?? resourceDataFactory.CreateSerialized(serializedData, format, type); } - catch { - throw new ResourceReaderException("Invalid encoded int32"); + default: + throw new ResourceReaderException($"Invalid reader type: {readerType}"); } } - bool CheckReaders(ref ResourceElementSet resources) { + ResourceElementSet ReadHeader() { int headerVersion = reader.ReadInt32(); if (headerVersion != 1) throw new ResourceReaderException($"Invalid or unsupported header version: {headerVersion}"); @@ -255,15 +253,18 @@ bool CheckReaders(ref ResourceElementSet resources) { if (headerSize < 0) throw new ResourceReaderException($"Invalid header size: {headerSize:X8}"); - resources.ResourceReaderTypeName = reader.ReadSerializedString(); - resources.ResourceSetTypeName = reader.ReadSerializedString(); + string resourceReaderTypeName = reader.ReadSerializedString(); + string resourceSetTypeName = reader.ReadSerializedString(); - if (Regex.IsMatch(resources.ResourceReaderTypeName, @"^System\.Resources\.ResourceReader,\s*mscorlib")) - return true; - if (Regex.IsMatch(resources.ResourceReaderTypeName, @"^System\.Resources\.Extensions\.DeserializingResourceReader,\s*System\.Resources\.Extensions")) - return true; + ResourceReaderType readerType; + if (Regex.IsMatch(resourceReaderTypeName, ResourceElementSet.ResourceReaderTypeNameRegex)) + readerType = ResourceReaderType.ResourceReader; + else if (Regex.IsMatch(resourceReaderTypeName, ResourceElementSet.DeserializingResourceReaderTypeNameRegex)) + readerType = ResourceReaderType.DeserializingResourceReader; + else + return null; - return false; + return new ResourceElementSet(resourceReaderTypeName, resourceSetTypeName, readerType); } } } diff --git a/src/DotNet/Resources/ResourceReaderType.cs b/src/DotNet/Resources/ResourceReaderType.cs new file mode 100644 index 000000000..328eb4c17 --- /dev/null +++ b/src/DotNet/Resources/ResourceReaderType.cs @@ -0,0 +1,15 @@ +namespace dnlib.DotNet.Resources { + /// + /// Resource reader type + /// + public enum ResourceReaderType { + /// + /// System.Resources.ResourceReader + /// + ResourceReader, + /// + /// System.Resources.Extensions.DeserializingResourceReader + /// + DeserializingResourceReader, + } +} diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index 5a3914544..496c241dc 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -37,10 +37,12 @@ public static void Write(ModuleDef module, Stream stream, ResourceElementSet res void Write() { InitializeUserTypes(); + int formatVersion = 2;//TODO: Support version 1 + writer.Write(0xBEEFCACE); writer.Write(1); WriteReaderType(); - writer.Write(2);//TODO: Support version 1 + writer.Write(formatVersion); writer.Write(resources.Count); writer.Write(typeCreator.Count); foreach (var userType in typeCreator.GetSortedTypes()) @@ -54,7 +56,10 @@ void Write() { var nameOffsetStream = new MemoryStream(); var nameOffsetWriter = new BinaryWriter(nameOffsetStream, Encoding.Unicode); var dataStream = new MemoryStream(); - var dataWriter = new BinaryWriter(dataStream); + var dataWriter = new ResourceBinaryWriter(dataStream) { + FormatVersion = formatVersion, + ReaderType = resources.ReaderType, + }; var hashes = new int[resources.Count]; var offsets = new int[resources.Count]; var formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence)); @@ -78,20 +83,12 @@ void Write() { writer.Write(dataStream.ToArray()); } - void WriteData(BinaryWriter writer, ResourceElement info, IFormatter formatter) { + void WriteData(ResourceBinaryWriter writer, ResourceElement info, IFormatter formatter) { var code = GetResourceType(info.ResourceData); - WriteUInt32(writer, (uint)code); + writer.Write7BitEncodedInt((int)code); info.ResourceData.WriteData(writer, formatter); } - static void WriteUInt32(BinaryWriter writer, uint value) { - while (value >= 0x80) { - writer.Write((byte)(value | 0x80)); - value >>= 7; - } - writer.Write((byte)value); - } - ResourceTypeCode GetResourceType(IResourceData data) { if (data is BuiltInResourceData) return data.Code; diff --git a/src/DotNet/Resources/UserResourceData.cs b/src/DotNet/Resources/UserResourceData.cs index 9129559b5..fcfe0b9e5 100644 --- a/src/DotNet/Resources/UserResourceData.cs +++ b/src/DotNet/Resources/UserResourceData.cs @@ -21,10 +21,10 @@ public abstract class UserResourceData : IResourceData { /// public ResourceTypeCode Code => type.Code; - /// + /// public FileOffset StartOffset { get; set; } - /// + /// public FileOffset EndOffset { get; set; } /// @@ -34,7 +34,7 @@ public abstract class UserResourceData : IResourceData { public UserResourceData(UserResourceType type) => this.type = type; /// - public abstract void WriteData(BinaryWriter writer, IFormatter formatter); + public abstract void WriteData(ResourceBinaryWriter writer, IFormatter formatter); } /// @@ -42,24 +42,69 @@ public abstract class UserResourceData : IResourceData { /// public sealed class BinaryResourceData : UserResourceData { byte[] data; + SerializationFormat format; /// /// Gets the raw data /// public byte[] Data => data; + /// + /// Gets the serialization format of + /// + public SerializationFormat Format => format; + /// /// Constructor /// /// User resource type /// Raw serialized data - public BinaryResourceData(UserResourceType type, byte[] data) - : base(type) => this.data = data; + /// + public BinaryResourceData(UserResourceType type, byte[] data, SerializationFormat format) + : base(type) { + this.data = data; + this.format = format; + } /// - public override void WriteData(BinaryWriter writer, IFormatter formatter) => writer.Write(data); + public override void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { + if (writer.ReaderType == ResourceReaderType.DeserializingResourceReader) { + writer.Write7BitEncodedInt((int)format); + writer.Write7BitEncodedInt(data.Length); + } + writer.Write(data); + } /// - public override string ToString() => "Binary: Length: " + data.Length.ToString(); + public override string ToString() => $"Binary: Length: {data.Length} Format: {format}"; + } + + /// + /// Specifies how the data in should be deserialized. + /// + public enum SerializationFormat { + /// + /// The data can be deserialized using . + /// + BinaryFormatter = 1, + + /// + /// The data can be deserialized by passing in the raw data into + /// the method. + /// + TypeConverterByteArray = 2, + + /// + /// The data can be deserialized by passing the UTF-8 string obtained from the raw data into + /// the method. + /// + TypeConverterString = 3, + + /// + /// The data can be deserialized by creating a new instance of the type using a + /// constructor with a single parameter and passing in + /// a of the raw data into it. + /// + ActivatorStream = 4, } } From 1817790239ad13752d08eef80572f34dd166b5bd Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 10 Jul 2023 14:49:35 +0200 Subject: [PATCH 462/511] Validate serialized resource data format when writing --- src/DotNet/Resources/UserResourceData.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/Resources/UserResourceData.cs b/src/DotNet/Resources/UserResourceData.cs index fcfe0b9e5..24445268d 100644 --- a/src/DotNet/Resources/UserResourceData.cs +++ b/src/DotNet/Resources/UserResourceData.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System; using System.IO; using System.Runtime.Serialization; using dnlib.IO; @@ -68,6 +69,9 @@ public BinaryResourceData(UserResourceType type, byte[] data, SerializationForma /// public override void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { + if (writer.ReaderType == ResourceReaderType.ResourceReader && format != SerializationFormat.BinaryFormatter) + throw new NotSupportedException(); + if (writer.ReaderType == ResourceReaderType.DeserializingResourceReader) { writer.Write7BitEncodedInt((int)format); writer.Write7BitEncodedInt(data.Length); From 3f9c3e1b57aa63c56bd8564ce28b8e1b0ebd442f Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 11 Jul 2023 19:53:35 +0200 Subject: [PATCH 463/511] Address feedback --- src/DotNet/Resources/ResourceBinaryWriter.cs | 3 +-- src/DotNet/Resources/ResourceDataFactory.cs | 1 + src/DotNet/Resources/ResourceReader.cs | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Resources/ResourceBinaryWriter.cs b/src/DotNet/Resources/ResourceBinaryWriter.cs index b0c1e09dc..09d7aef60 100644 --- a/src/DotNet/Resources/ResourceBinaryWriter.cs +++ b/src/DotNet/Resources/ResourceBinaryWriter.cs @@ -15,8 +15,7 @@ public sealed class ResourceBinaryWriter : BinaryWriter { /// public ResourceReaderType ReaderType { get; internal set; } - /// - public ResourceBinaryWriter(Stream stream) : base(stream) { } + internal ResourceBinaryWriter(Stream stream) : base(stream) { } /// /// Writes a 7-bit encoded integer. diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index 83548763c..a6746b64f 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -171,6 +171,7 @@ public ResourceDataFactory(ModuleDef module) { /// Creates serialized data /// /// Serialized data + /// Format of the serialized data /// Type of serialized data /// public BinaryResourceData CreateSerialized(byte[] value, SerializationFormat format, UserResourceType type) => new BinaryResourceData(CreateUserResourceType(type.Name, true), value, format); diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 2f5c094f8..978053e42 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -45,6 +45,7 @@ public ResourceReaderException(SerializationInfo info, StreamingContext context) /// ResourceDataFactory /// Serialized type /// Serialized data + /// Format of the serialized data /// public delegate IResourceData CreateResourceDataDelegate(ResourceDataFactory resourceDataFactory, UserResourceType type, byte[] serializedData, SerializationFormat format); @@ -234,6 +235,8 @@ IResourceData ReadSerializedObject(uint endPos, ResourceReaderType readerType, U return res ?? resourceDataFactory.CreateSerialized(serializedData, SerializationFormat.BinaryFormatter, type); case ResourceReaderType.DeserializingResourceReader: { var format = (SerializationFormat)reader.Read7BitEncodedInt32(); + if (format < SerializationFormat.BinaryFormatter || format > SerializationFormat.ActivatorStream) + throw new ResourceReaderException($"Invalid serialization format: {format}"); int length = reader.Read7BitEncodedInt32(); Debug.Assert(length == (int)(endPos - reader.Position)); serializedData = reader.ReadBytes(length); From a91187d6ff4302ea7f3158867b7dd36a809f508e Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 12 Jul 2023 12:24:05 +0200 Subject: [PATCH 464/511] Add another sanity check for V1 resources --- src/DotNet/Resources/BuiltInResourceData.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index 9e1417bd0..3af128a51 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -113,6 +113,8 @@ public void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { case ResourceTypeCode.ByteArray: case ResourceTypeCode.Stream: + if (writer.FormatVersion == 1) + throw new NotSupportedException(); var ary = (byte[])data; writer.Write(ary.Length); writer.Write(ary); From 3954fe68e71dac754a56e74489779f2eb55472cd Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 12 Jul 2023 13:30:39 +0200 Subject: [PATCH 465/511] Allow customizing of `ResourceDataFactory` --- src/DotNet/Resources/ResourceReader.cs | 16 +++++++++++++--- src/DotNet/Resources/ResourceWriter.cs | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/DotNet/Resources/ResourceReader.cs b/src/DotNet/Resources/ResourceReader.cs index 978053e42..8a35a1473 100644 --- a/src/DotNet/Resources/ResourceReader.cs +++ b/src/DotNet/Resources/ResourceReader.cs @@ -58,9 +58,9 @@ public struct ResourceReader { readonly ResourceDataFactory resourceDataFactory; readonly CreateResourceDataDelegate createResourceDataDelegate; - ResourceReader(ModuleDef module, ref DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) { + ResourceReader(ResourceDataFactory resourceDataFactory, ref DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) { this.reader = reader; - resourceDataFactory = new ResourceDataFactory(module); + this.resourceDataFactory = resourceDataFactory; this.createResourceDataDelegate = createResourceDataDelegate; baseFileOffset = reader.StartOffset; } @@ -89,7 +89,17 @@ public static bool CouldBeResourcesFile(DataReader reader) => /// Call back that gets called to create a instance. Can be null. /// public static ResourceElementSet Read(ModuleDef module, DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) => - new ResourceReader(module, ref reader, createResourceDataDelegate).Read(); + Read(new ResourceDataFactory(module), reader, createResourceDataDelegate); + + /// + /// Reads a .NET resource + /// + /// User type resource data factory + /// Data of resource + /// Call back that gets called to create a instance. Can be null. + /// + public static ResourceElementSet Read(ResourceDataFactory resourceDataFactory, DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) => + new ResourceReader(resourceDataFactory, ref reader, createResourceDataDelegate).Read(); ResourceElementSet Read() { uint sig = reader.ReadUInt32(); diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index 496c241dc..a7c986a8b 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -18,9 +18,9 @@ public sealed class ResourceWriter { ResourceDataFactory typeCreator; Dictionary dataToNewType = new Dictionary(); - ResourceWriter(ModuleDef module, Stream stream, ResourceElementSet resources) { + ResourceWriter(ModuleDef module, ResourceDataFactory typeCreator, Stream stream, ResourceElementSet resources) { this.module = module; - typeCreator = new ResourceDataFactory(module); + this.typeCreator = typeCreator; writer = new BinaryWriter(stream); this.resources = resources; } @@ -32,7 +32,17 @@ public sealed class ResourceWriter { /// Output stream /// .NET resources public static void Write(ModuleDef module, Stream stream, ResourceElementSet resources) => - new ResourceWriter(module, stream, resources).Write(); + new ResourceWriter(module, new ResourceDataFactory(module), stream, resources).Write(); + + /// + /// Write .NET resources + /// + /// Owner module + /// User type factory + /// Output stream + /// .NET resources + public static void Write(ModuleDef module, ResourceDataFactory typeCreator, Stream stream, ResourceElementSet resources) => + new ResourceWriter(module, typeCreator, stream, resources).Write(); void Write() { InitializeUserTypes(); From 05498252cbb2ae5dc79b439a3506d74e6794eb61 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 12 Jul 2023 13:58:07 +0200 Subject: [PATCH 466/511] Added support for writing V1 resources --- src/DotNet/Resources/BuiltInResourceData.cs | 2 +- src/DotNet/Resources/ResourceDataFactory.cs | 32 +++++++++++++++++ src/DotNet/Resources/ResourceElementSet.cs | 1 + src/DotNet/Resources/ResourceWriter.cs | 39 +++++++++++++-------- src/DotNet/Resources/UserResourceData.cs | 2 +- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/DotNet/Resources/BuiltInResourceData.cs b/src/DotNet/Resources/BuiltInResourceData.cs index 3af128a51..8bb1c82b5 100644 --- a/src/DotNet/Resources/BuiltInResourceData.cs +++ b/src/DotNet/Resources/BuiltInResourceData.cs @@ -114,7 +114,7 @@ public void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { case ResourceTypeCode.ByteArray: case ResourceTypeCode.Stream: if (writer.FormatVersion == 1) - throw new NotSupportedException(); + throw new NotSupportedException($"{code} is not supported in format version 1 resources"); var ary = (byte[])data; writer.Write(ary.Length); writer.Write(ary); diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index a6746b64f..bab0c8819 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -220,6 +220,38 @@ bool GetSerializedTypeAndAssemblyName(byte[] value, out string assemblyName, out return false; } + /// + /// Creates a user type for a built-in resource type code. + /// Useful when writing V1 resources. + /// + /// The built-in resource type code or null if not supported + /// + public UserResourceType CreateBuiltinResourceType(ResourceTypeCode typeCode) { + string typeName = typeCode switch { + ResourceTypeCode.String => "System.String", + ResourceTypeCode.Boolean => "System.Boolean", + ResourceTypeCode.Char => "System.Char", + ResourceTypeCode.Byte => "System.Byte", + ResourceTypeCode.SByte => "System.SByte", + ResourceTypeCode.Int16 => "System.Int16", + ResourceTypeCode.UInt16 => "System.UInt16", + ResourceTypeCode.Int32 => "System.Int32", + ResourceTypeCode.UInt32 => "System.UInt32", + ResourceTypeCode.Int64 => "System.Int64", + ResourceTypeCode.UInt64 => "System.UInt64", + ResourceTypeCode.Single => "System.Single", + ResourceTypeCode.Double => "System.Double", + ResourceTypeCode.Decimal => "System.Decimal", + ResourceTypeCode.DateTime => "System.DateTime", + ResourceTypeCode.TimeSpan => "System.TimeSpan", + _ => null + }; + if (typeName is null) + return null; + + return CreateUserResourceType($"{typeName}, {module.CorLibTypes.AssemblyRef.FullName}", true); + } + /// /// Creates a user type. If the type already exists, the existing value is returned. /// diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index 6b559d34d..48b4151c4 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -43,6 +43,7 @@ internal ResourceElementSet(string resourceReaderTypeName, string resourceSetTyp ResourceReaderTypeName = resourceReaderTypeName; ResourceSetTypeName = resourceSetTypeName; ReaderType = readerType; + FormatVersion = 2; } /// diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index a7c986a8b..49a800188 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -16,7 +16,7 @@ public sealed class ResourceWriter { BinaryWriter writer; ResourceElementSet resources; ResourceDataFactory typeCreator; - Dictionary dataToNewType = new Dictionary(); + Dictionary dataToNewType = new Dictionary(); ResourceWriter(ModuleDef module, ResourceDataFactory typeCreator, Stream stream, ResourceElementSet resources) { this.module = module; @@ -45,14 +45,12 @@ public static void Write(ModuleDef module, ResourceDataFactory typeCreator, Stre new ResourceWriter(module, typeCreator, stream, resources).Write(); void Write() { - InitializeUserTypes(); - - int formatVersion = 2;//TODO: Support version 1 + InitializeUserTypes(resources.FormatVersion); writer.Write(0xBEEFCACE); writer.Write(1); WriteReaderType(); - writer.Write(formatVersion); + writer.Write(resources.FormatVersion); writer.Write(resources.Count); writer.Write(typeCreator.Count); foreach (var userType in typeCreator.GetSortedTypes()) @@ -67,7 +65,7 @@ void Write() { var nameOffsetWriter = new BinaryWriter(nameOffsetStream, Encoding.Unicode); var dataStream = new MemoryStream(); var dataWriter = new ResourceBinaryWriter(dataStream) { - FormatVersion = formatVersion, + FormatVersion = resources.FormatVersion, ReaderType = resources.ReaderType, }; var hashes = new int[resources.Count]; @@ -94,17 +92,22 @@ void Write() { } void WriteData(ResourceBinaryWriter writer, ResourceElement info, IFormatter formatter) { - var code = GetResourceType(info.ResourceData); + var code = GetResourceType(info.ResourceData, writer.FormatVersion); writer.Write7BitEncodedInt((int)code); info.ResourceData.WriteData(writer, formatter); } - ResourceTypeCode GetResourceType(IResourceData data) { + ResourceTypeCode GetResourceType(IResourceData data, int formatVersion) { + if (formatVersion == 1) { + if (data.Code == ResourceTypeCode.Null) + return (ResourceTypeCode)(-1); + return (ResourceTypeCode)(dataToNewType[data].Code - ResourceTypeCode.UserTypes); + } + if (data is BuiltInResourceData) return data.Code; - var userData = (UserResourceData)data; - return dataToNewType[userData].Code; + return dataToNewType[data].Code; } static uint Hash(string key) { @@ -114,13 +117,19 @@ static uint Hash(string key) { return val; } - void InitializeUserTypes() { + void InitializeUserTypes(int formatVersion) { foreach (var resource in resources.ResourceElements) { - var data = resource.ResourceData as UserResourceData; - if (data is null) + UserResourceType newType; + if (formatVersion == 1 && resource.ResourceData is BuiltInResourceData builtinData) { + newType = typeCreator.CreateBuiltinResourceType(builtinData.Code); + if (newType is null) + throw new NotSupportedException($"Unsupported resource type: {builtinData.Code} in format version 1 resource"); + } + else if (resource.ResourceData is UserResourceData userData) + newType = typeCreator.CreateUserResourceType(userData.TypeName); + else continue; - var newType = typeCreator.CreateUserResourceType(data.TypeName); - dataToNewType[data] = newType; + dataToNewType[resource.ResourceData] = newType; } } diff --git a/src/DotNet/Resources/UserResourceData.cs b/src/DotNet/Resources/UserResourceData.cs index 24445268d..3083f5cb7 100644 --- a/src/DotNet/Resources/UserResourceData.cs +++ b/src/DotNet/Resources/UserResourceData.cs @@ -70,7 +70,7 @@ public BinaryResourceData(UserResourceType type, byte[] data, SerializationForma /// public override void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { if (writer.ReaderType == ResourceReaderType.ResourceReader && format != SerializationFormat.BinaryFormatter) - throw new NotSupportedException(); + throw new NotSupportedException($"Unsupported serialization format: {format} for {writer.ReaderType}"); if (writer.ReaderType == ResourceReaderType.DeserializingResourceReader) { writer.Write7BitEncodedInt((int)format); From 8eb5fae767079348cb2614f9e7fe7a7d7c2e9a57 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 12 Jul 2023 14:01:38 +0200 Subject: [PATCH 467/511] Add option to specify format version when create a `ResourceElementSet` --- src/DotNet/Resources/ResourceElementSet.cs | 25 +++++++++++++++------- src/DotNet/Resources/ResourceWriter.cs | 3 +++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index 48b4151c4..21f14ff56 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -43,7 +43,6 @@ internal ResourceElementSet(string resourceReaderTypeName, string resourceSetTyp ResourceReaderTypeName = resourceReaderTypeName; ResourceSetTypeName = resourceSetTypeName; ReaderType = readerType; - FormatVersion = 2; } /// @@ -65,17 +64,21 @@ internal ResourceElementSet(string resourceReaderTypeName, string resourceSetTyp /// /// Creates a new instance for a DeserializingResourceReader /// - /// - public static ResourceElementSet CreateForDeserializingResourceReader(Version extensionAssemblyVersion) { + /// Version of System.Resources.Extensions assembly to use + /// Resource format version, the default is 2 + public static ResourceElementSet CreateForDeserializingResourceReader(Version extensionAssemblyVersion, int formatVersion = 2) { var extensionAssemblyFullName = $"System.Resources.Extensions, Version={extensionAssemblyVersion.ToString(4)}, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"; - return new ResourceElementSet($"System.Resources.Extensions.DeserializingResourceReader, {extensionAssemblyFullName}", $"System.Resources.Extensions.RuntimeResourceSet, {extensionAssemblyFullName}", ResourceReaderType.DeserializingResourceReader); + return new ResourceElementSet($"System.Resources.Extensions.DeserializingResourceReader, {extensionAssemblyFullName}", $"System.Resources.Extensions.RuntimeResourceSet, {extensionAssemblyFullName}", ResourceReaderType.DeserializingResourceReader) { + FormatVersion = formatVersion + }; } /// /// Creates a new instance for a ResourceReader /// /// Module in which the set will reside - public static ResourceElementSet CreateForResourceReader(ModuleDef module) { + /// /// Resource format version, the default is 2 + public static ResourceElementSet CreateForResourceReader(ModuleDef module, int formatVersion = 2) { string mscorlibFullName; if (module.CorLibTypes.AssemblyRef.Name == "mscorlib") { // Use mscorlib reference found in module. @@ -85,14 +88,20 @@ public static ResourceElementSet CreateForResourceReader(ModuleDef module) { // Use a reference to 4.0.0.0 mscorlib for compatibility with .NET Core, .NET 5, and later. mscorlibFullName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } - return new ResourceElementSet($"System.Resources.ResourceReader, {mscorlibFullName}", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader); + return new ResourceElementSet($"System.Resources.ResourceReader, {mscorlibFullName}", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader) { + FormatVersion = formatVersion + }; } /// /// Creates a new instance for a ResourceReader /// /// mscorlib assembly version - public static ResourceElementSet CreateForResourceReader(Version mscorlibVersion) => - new ResourceElementSet($"System.Resources.ResourceReader, mscorlib, Version={mscorlibVersion.ToString(4)}, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader); + /// Resource format version, the default is 2 + public static ResourceElementSet CreateForResourceReader(Version mscorlibVersion, int formatVersion = 2) { + return new ResourceElementSet($"System.Resources.ResourceReader, mscorlib, Version={mscorlibVersion.ToString(4)}, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Resources.RuntimeResourceSet", ResourceReaderType.ResourceReader) { + FormatVersion = formatVersion + }; + } } } diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index 49a800188..b89a3c97c 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -45,6 +45,9 @@ public static void Write(ModuleDef module, ResourceDataFactory typeCreator, Stre new ResourceWriter(module, typeCreator, stream, resources).Write(); void Write() { + if (resources.FormatVersion != 1 && resources.FormatVersion != 2) + throw new ArgumentException("Invalid format version: " + resources.FormatVersion, nameof(resources)); + InitializeUserTypes(resources.FormatVersion); writer.Write(0xBEEFCACE); From b16eb800766ba4b340d5a241a8b5b3dad0d5b1ff Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 12 Jul 2023 19:45:37 +0200 Subject: [PATCH 468/511] Add `ResourceElementSet.Clone` method --- src/DotNet/Resources/ResourceElementSet.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/DotNet/Resources/ResourceElementSet.cs b/src/DotNet/Resources/ResourceElementSet.cs index 21f14ff56..ebb8da4a7 100644 --- a/src/DotNet/Resources/ResourceElementSet.cs +++ b/src/DotNet/Resources/ResourceElementSet.cs @@ -103,5 +103,13 @@ public static ResourceElementSet CreateForResourceReader(Version mscorlibVersion FormatVersion = formatVersion }; } + + /// + /// Creates a new instance based on this instance + /// + /// + public ResourceElementSet Clone() => new ResourceElementSet(ResourceReaderTypeName, ResourceSetTypeName, ReaderType) { + FormatVersion = FormatVersion + }; } } From bb061dc3c66b88b7e4b23d8b53a934440e2bdae4 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 15 Jul 2023 18:40:54 +0200 Subject: [PATCH 469/511] Add additional `net6.0` target framework --- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/DotNet/ImplMap.cs | 2 +- src/IO/DataReaderFactoryFactory.cs | 2 +- src/PE/ProcessorArchUtils.cs | 2 +- src/dnlib.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index 744977988..cc88905c8 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -27,7 +27,7 @@ static class MethodTableToTypeConverter { static MethodTableToTypeConverter() { if (ptrFieldInfo is null) { -#if NETSTANDARD +#if NETSTANDARD || NETCOREAPP var asmb = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); #else var asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.Run); diff --git a/src/DotNet/ImplMap.cs b/src/DotNet/ImplMap.cs index b49673744..480ec7a00 100644 --- a/src/DotNet/ImplMap.cs +++ b/src/DotNet/ImplMap.cs @@ -234,7 +234,7 @@ static string GetDllName(string dllName, bool treatAsWindows) { } static bool IsWindows() => -#if NETSTANDARD +#if NETSTANDARD || NETCOREAPP RuntimeInformation.IsOSPlatform(OSPlatform.Windows); #else Path.DirectorySeparatorChar == '\\' || Path.AltDirectorySeparatorChar == '\\'; diff --git a/src/IO/DataReaderFactoryFactory.cs b/src/IO/DataReaderFactoryFactory.cs index edc75daee..9a16dec0b 100644 --- a/src/IO/DataReaderFactoryFactory.cs +++ b/src/IO/DataReaderFactoryFactory.cs @@ -13,7 +13,7 @@ static DataReaderFactoryFactory() { int p = (int)Environment.OSVersion.Platform; if (p == 4 || p == 6 || p == 128) isUnix = true; -#if NETSTANDARD +#if NETSTANDARD || NETCOREAPP if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) isUnix = true; #endif diff --git a/src/PE/ProcessorArchUtils.cs b/src/PE/ProcessorArchUtils.cs index c0d5f13ac..57599e167 100644 --- a/src/PE/ProcessorArchUtils.cs +++ b/src/PE/ProcessorArchUtils.cs @@ -16,7 +16,7 @@ public static Machine GetProcessCpuArchitecture() { } static class RuntimeInformationUtils { -#if NETSTANDARD +#if NETSTANDARD || NETCOREAPP public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => TryGetArchitecture((int)RuntimeInformation.ProcessArchitecture, out machine); #else diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 7445c7b09..8ce35858e 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -5,7 +5,7 @@ $(DefineConstants);$(MoreDefineConstants) $(DefineConstants);THREAD_SAFE - netstandard2.0;net45 + netstandard2.0;net45;net6.0 true From f3aa81735d77996b56a02a04308746ae871f1463 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 15 Jul 2023 18:53:01 +0200 Subject: [PATCH 470/511] Resolve compiler warnings --- src/DotNet/ModuleDefMD.cs | 7 ++++++- src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs | 4 ++++ src/DotNet/Pdb/Dss/SymbolWriterImpl.cs | 4 ++++ src/DotNet/Pdb/SymbolReaderFactory.cs | 9 ++++++++- src/DotNet/Resources/ResourceDataFactory.cs | 2 ++ src/DotNet/Writer/ModuleWriterBase.cs | 7 +++++++ 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/DotNet/ModuleDefMD.cs b/src/DotNet/ModuleDefMD.cs index f265b435c..f37e84f9c 100644 --- a/src/DotNet/ModuleDefMD.cs +++ b/src/DotNet/ModuleDefMD.cs @@ -1495,7 +1495,12 @@ Resource CreateResource(uint rid) { return new EmbeddedResourceMD(this, mr, Array2.Empty()); } - [HandleProcessCorruptedStateExceptions, SecurityCritical] // Req'd on .NET Framework 4.0 + // Required attributes on .NET Framework 4.0 + // HandleProcessCorruptedStateExceptions is obsolete on .NET Core and newer +#if !NETCOREAPP + [HandleProcessCorruptedStateExceptions] +#endif + [SecurityCritical] bool TryCreateResourceStream(uint offset, out DataReaderFactory dataReaderFactory, out uint resourceOffset, out uint resourceLength) { dataReaderFactory = null; resourceOffset = 0; diff --git a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs index 93097c95d..c8ddfb91a 100644 --- a/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ b/src/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs @@ -6,11 +6,15 @@ using dnlib.IO; using dnlib.DotNet.Pdb.Symbols; using System.Diagnostics; +using System.Runtime.Versioning; using dnlib.PE; using dnlib.DotNet.Writer; using dnlib.DotNet.Pdb.WindowsPdb; namespace dnlib.DotNet.Pdb.Dss { +#if NETCOREAPP + [SupportedOSPlatform("windows")] +#endif static class SymbolReaderWriterFactory { [DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)] [DllImport("Microsoft.DiaSymReader.Native.x86.dll", EntryPoint = "CreateSymReader")] diff --git a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs index 22ba81a6d..875ddddec 100644 --- a/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ b/src/DotNet/Pdb/Dss/SymbolWriterImpl.cs @@ -5,10 +5,14 @@ using System.Diagnostics.SymbolStore; using System.IO; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using dnlib.DotNet.Pdb.WindowsPdb; using dnlib.DotNet.Writer; namespace dnlib.DotNet.Pdb.Dss { +#if NETCOREAPP + [SupportedOSPlatform("windows")] +#endif sealed class SymbolWriterImpl : SymbolWriter { readonly ISymUnmanagedWriter2 writer; readonly ISymUnmanagedAsyncMethodPropertiesWriter asyncMethodWriter; diff --git a/src/DotNet/Pdb/SymbolReaderFactory.cs b/src/DotNet/Pdb/SymbolReaderFactory.cs index 5d0388548..b8aff57ca 100644 --- a/src/DotNet/Pdb/SymbolReaderFactory.cs +++ b/src/DotNet/Pdb/SymbolReaderFactory.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using System.Runtime.InteropServices; using System.Text; using dnlib.DotNet.MD; using dnlib.DotNet.Pdb.Symbols; @@ -66,7 +67,13 @@ static SymbolReader CreateCore(PdbReaderContext pdbContext, Metadata metadata, D if (!pdbContext.HasDebugInfo) return null; - if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && pdbStream is not null && IsWindowsPdb(pdbStream.CreateReader())) +#if NETSTANDARD || NETCOREAPP + var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#else + var isWindows = true; +#endif + + if ((pdbContext.Options & PdbReaderOptions.MicrosoftComReader) != 0 && isWindows && pdbStream is not null && IsWindowsPdb(pdbStream.CreateReader())) symReader = Dss.SymbolReaderWriterFactory.Create(pdbContext, metadata, pdbStream); else symReader = CreateManaged(pdbContext, metadata, pdbStream); diff --git a/src/DotNet/Resources/ResourceDataFactory.cs b/src/DotNet/Resources/ResourceDataFactory.cs index bab0c8819..ef437702c 100644 --- a/src/DotNet/Resources/ResourceDataFactory.cs +++ b/src/DotNet/Resources/ResourceDataFactory.cs @@ -205,7 +205,9 @@ bool GetSerializedTypeAndAssemblyName(byte[] value, out string assemblyName, out try { var formatter = new BinaryFormatter(); formatter.Binder = new MyBinder(); +#pragma warning disable SYSLIB0011 // Type or member is obsolete formatter.Deserialize(new MemoryStream(value)); +#pragma warning restore SYSLIB0011 // Type or member is obsolete } catch (MyBinder.OkException ex) { assemblyName = ex.AssemblyName; diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 6096871ee..5c77af110 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -12,6 +12,7 @@ using dnlib.DotNet.Pdb.WindowsPdb; using System.Text; using System.IO.Compression; +using System.Runtime.InteropServices; namespace dnlib.DotNet.Writer { /// @@ -943,6 +944,12 @@ protected uint GetTimeDateStamp() { } SymbolWriter GetWindowsPdbSymbolWriter(PdbWriterOptions options, out string pdbFilename) { +#if NETSTANDARD || NETCOREAPP + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { + pdbFilename = null; + return null; + } +#endif if (TheOptions.PdbStream is not null) { return Pdb.Dss.SymbolReaderWriterFactory.Create(options, TheOptions.PdbStream, pdbFilename = TheOptions.PdbFileName ?? From c0ec4ef50b1e1ed1703733df3f78e0970030638a Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 15 Jul 2023 18:53:23 +0200 Subject: [PATCH 471/511] Update NuGet packages to latest version --- src/dnlib.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 8ce35858e..568482ed7 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -59,8 +59,8 @@ For better *Windows PDB* writer support, you should add a reference to `Microsof - - + + From cc12baca4d2689c34036316664e3b9abd8f6e5f7 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 15 Jul 2023 19:01:09 +0200 Subject: [PATCH 472/511] Prefer string interpolation over string concatenation This gives the compiler additional changes to apply optimizations --- src/DotNet/Emit/MethodTableToTypeConverter.cs | 2 +- src/DotNet/Pdb/Managed/DbiScope.cs | 4 ++-- src/DotNet/Pdb/Managed/PdbException.cs | 4 ++-- src/DotNet/Pdb/Managed/PdbReader.cs | 2 +- src/DotNet/Pdb/PdbConstant.cs | 5 ++++- src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs | 2 +- src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs | 2 +- src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs | 2 +- src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs | 2 +- src/DotNet/Pdb/Portable/PortablePdbReader.cs | 2 +- src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs | 2 +- src/DotNet/Resources/ResourceWriter.cs | 4 ++-- src/IO/DataReader.cs | 4 ++-- 13 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/DotNet/Emit/MethodTableToTypeConverter.cs b/src/DotNet/Emit/MethodTableToTypeConverter.cs index cc88905c8..38c05f398 100644 --- a/src/DotNet/Emit/MethodTableToTypeConverter.cs +++ b/src/DotNet/Emit/MethodTableToTypeConverter.cs @@ -121,7 +121,7 @@ static Type GetTypeNET20(IntPtr address) { return Type.GetTypeFromHandle((RuntimeTypeHandle)th); } - static string GetNextTypeName() => "Type" + numNewTypes++.ToString(); + static string GetNextTypeName() => $"Type{numNewTypes++}"; static byte[] GetLocalSignature(IntPtr mtAddr) { ulong mtValue = (ulong)mtAddr.ToInt64(); diff --git a/src/DotNet/Pdb/Managed/DbiScope.cs b/src/DotNet/Pdb/Managed/DbiScope.cs index baa2e2636..30c26fb2d 100644 --- a/src/DotNet/Pdb/Managed/DbiScope.cs +++ b/src/DotNet/Pdb/Managed/DbiScope.cs @@ -62,7 +62,7 @@ public OemInfo(string name, byte[] data) { Name = name; Data = data; } - public override string ToString() => Name + " = (" + Data.Length.ToString() + " bytes)"; + public override string ToString() => $"{Name} = ({Data.Length} bytes)"; } static readonly byte[] dotNetOemGuid = new byte[] { @@ -116,7 +116,7 @@ public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd) var data = reader.ReadBytes((int)(end - reader.Position)); if (oemInfos is null) oemInfos = new List(1); - oemInfos.Add(new OemInfo(name, data)); + oemInfos.Add(new OemInfo(name, data)); break; case SymbolType.S_MANCONSTANT: uint signatureToken = reader.ReadUInt32(); diff --git a/src/DotNet/Pdb/Managed/PdbException.cs b/src/DotNet/Pdb/Managed/PdbException.cs index 132025d87..43b8e3e01 100644 --- a/src/DotNet/Pdb/Managed/PdbException.cs +++ b/src/DotNet/Pdb/Managed/PdbException.cs @@ -20,7 +20,7 @@ public PdbException() { /// /// Exception message public PdbException(string message) - : base("Failed to read PDB: " + message) { + : base($"Failed to read PDB: {message}") { } /// @@ -28,7 +28,7 @@ public PdbException(string message) /// /// Inner exception public PdbException(Exception innerException) - : base("Failed to read PDB: " + innerException.Message, innerException) { + : base($"Failed to read PDB: {innerException.Message}", innerException) { } /// diff --git a/src/DotNet/Pdb/Managed/PdbReader.cs b/src/DotNet/Pdb/Managed/PdbReader.cs index 1159a2927..92a20cc91 100644 --- a/src/DotNet/Pdb/Managed/PdbReader.cs +++ b/src/DotNet/Pdb/Managed/PdbReader.cs @@ -263,7 +263,7 @@ internal DbiDocument GetDocument(uint nameId) { if (!documents.TryGetValue(name, out var doc)) { doc = new DbiDocument(name); - if (names.TryGetValue("/src/files/" + name, out uint streamId)) + if (names.TryGetValue($"/src/files/{name}", out uint streamId)) doc.Read(ref streams[streamId].Content); documents.Add(name, doc); } diff --git a/src/DotNet/Pdb/PdbConstant.cs b/src/DotNet/Pdb/PdbConstant.cs index be0d76657..11fb6fabc 100644 --- a/src/DotNet/Pdb/PdbConstant.cs +++ b/src/DotNet/Pdb/PdbConstant.cs @@ -71,7 +71,10 @@ public PdbConstant(string name, TypeSig type, object value) { /// public override string ToString() { var type = Type; - return (type is null ? "" : type.ToString()) + " " + Name + " = " + (Value is null ? "null" : Value.ToString() + " (" + Value.GetType().FullName + ")"); + var value = Value; + string typeString = type is null ? "" : type.ToString(); + string valueString = value is null ? "null" : $"{value} ({value.GetType().FullName})"; + return$"{typeString} {Name} = {valueString}"; } } } diff --git a/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs b/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs index a0fbe6e65..c49791956 100644 --- a/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs +++ b/src/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs @@ -19,7 +19,7 @@ public static PdbImportDefinitionKind ToPdbImportDefinitionKind(uint value) { case 8: return PdbImportDefinitionKind.AliasAssemblyNamespace; case 9: return PdbImportDefinitionKind.AliasType; default: - Debug.Fail("Unknown import definition kind: 0x" + value.ToString("X")); + Debug.Fail($"Unknown import definition kind: 0x{value:X}"); return UNKNOWN_IMPORT_KIND; } } diff --git a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs index 8eee439eb..7dad6eb19 100644 --- a/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ b/src/DotNet/Pdb/Portable/ImportScopeBlobReader.cs @@ -98,7 +98,7 @@ public void Read(uint imports, IList result) { break; default: - Debug.Fail("Unknown import definition kind: " + kind.ToString()); + Debug.Fail($"Unknown import definition kind: {kind}"); import = null; break; } diff --git a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs index 3bdee8c93..9f13e2491 100644 --- a/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ b/src/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs @@ -233,7 +233,7 @@ bool ReadCore(out TypeSig type, out object value) { case ElementType.Sentinel: case ElementType.Pinned: default: - Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString()); + Debug.Fail($"Unsupported element type in LocalConstant sig blob: {et}"); res = false; type = null; value = null; diff --git a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs index 87e5362f0..d110ab9a1 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs @@ -71,7 +71,7 @@ PdbCustomDebugInfo Read(Guid kind) { return ReadEncStateMachineStateMap(); if (kind == CustomDebugInfoGuids.PrimaryConstructorInformationBlob) return ReadPrimaryConstructorInformationBlob(); - Debug.Fail("Unknown custom debug info guid: " + kind.ToString()); + Debug.Fail($"Unknown custom debug info guid: {kind}"); return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); } diff --git a/src/DotNet/Pdb/Portable/PortablePdbReader.cs b/src/DotNet/Pdb/Portable/PortablePdbReader.cs index bae2ae621..a02454099 100644 --- a/src/DotNet/Pdb/Portable/PortablePdbReader.cs +++ b/src/DotNet/Pdb/Portable/PortablePdbReader.cs @@ -86,7 +86,7 @@ SymbolDocument[] ReadDocuments() { bool TryGetSymbolDocument(uint rid, out SymbolDocument document) { int index = (int)rid - 1; if ((uint)index >= (uint)documents.Length) { - Debug.Fail("Couldn't find document with rid 0x" + rid.ToString("X6")); + Debug.Fail($"Couldn't find document with rid 0x{rid:X6}"); document = null; return false; } diff --git a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs index 86dbf8460..1a658645d 100644 --- a/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ b/src/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs @@ -262,7 +262,7 @@ PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd) { return tupleListRec; default: - Debug.Fail("Unknown custom debug info kind: 0x" + ((int)recKind).ToString("X")); + Debug.Fail($"Unknown custom debug info kind: 0x{(int)recKind:X}"); data = reader.ReadBytes((int)(recPosEnd - reader.Position)); return new PdbUnknownCustomDebugInfo(recKind, data); } diff --git a/src/DotNet/Resources/ResourceWriter.cs b/src/DotNet/Resources/ResourceWriter.cs index b89a3c97c..4130390bb 100644 --- a/src/DotNet/Resources/ResourceWriter.cs +++ b/src/DotNet/Resources/ResourceWriter.cs @@ -46,7 +46,7 @@ public static void Write(ModuleDef module, ResourceDataFactory typeCreator, Stre void Write() { if (resources.FormatVersion != 1 && resources.FormatVersion != 2) - throw new ArgumentException("Invalid format version: " + resources.FormatVersion, nameof(resources)); + throw new ArgumentException($"Invalid format version: {resources.FormatVersion}", nameof(resources)); InitializeUserTypes(resources.FormatVersion); @@ -145,7 +145,7 @@ void WriteReaderType() { } else { var mscorlibFullName = GetMscorlibFullname(); - headerWriter.Write("System.Resources.ResourceReader, " + mscorlibFullName); + headerWriter.Write($"System.Resources.ResourceReader, {mscorlibFullName}"); headerWriter.Write("System.Resources.RuntimeResourceSet"); } writer.Write((int)memStream.Position); diff --git a/src/IO/DataReader.cs b/src/IO/DataReader.cs index 8ab81aa7f..84717d280 100644 --- a/src/IO/DataReader.cs +++ b/src/IO/DataReader.cs @@ -46,7 +46,7 @@ public uint CurrentOffset { VerifyState(); if (value < startOffset || value > endOffset) { // Invalid offsets should be an IOException and not an ArgumentException - ThrowDataReaderException("Invalid new " + nameof(CurrentOffset)); + ThrowDataReaderException($"Invalid new {nameof(CurrentOffset)}"); } currentOffset = value; VerifyState(); @@ -62,7 +62,7 @@ public uint Position { VerifyState(); if (value > Length) { // Invalid positions should be an IOException and not an ArgumentException - ThrowDataReaderException("Invalid new " + nameof(Position)); + ThrowDataReaderException($"Invalid new {nameof(Position)}"); } currentOffset = startOffset + value; VerifyState(); From 49407979e1d4d23b052840c765e71f6502378c55 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 15 Jul 2023 19:16:30 +0200 Subject: [PATCH 473/511] Resolve potential NREs found via code analysis --- src/DotNet/AssemblyResolver.cs | 11 +++++++---- src/DotNet/Importer.cs | 2 +- src/DotNet/Pdb/Managed/DbiModule.cs | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index bf4355d60..f87b5db31 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -763,10 +763,13 @@ protected IEnumerable GetModulePrivateSearchPaths(ModuleDef module) { try { var imageName = module.Location; if (imageName != string.Empty) { - baseDir = Directory.GetParent(imageName).FullName; - var configName = imageName + ".config"; - if (File.Exists(configName)) - return GetPrivatePaths(baseDir, configName); + var directoryInfo = Directory.GetParent(imageName); + if (directoryInfo is not null) { + baseDir = directoryInfo.FullName; + var configName = imageName + ".config"; + if (File.Exists(configName)) + return GetPrivatePaths(baseDir, configName); + } } } catch { diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index aa0f02b8f..5fbabd0b2 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -382,7 +382,7 @@ IResolutionScope CreateScopeReference(Type type) { pkt = null; if (TryToUseExistingAssemblyRefs && module.GetAssemblyRef(asmName.Name) is AssemblyRef asmRef) return asmRef; - return module.UpdateRowId(new AssemblyRefUser(asmName.Name, asmName.Version, PublicKeyBase.CreatePublicKeyToken(pkt), asmName.CultureInfo.Name)); + return module.UpdateRowId(new AssemblyRefUser(asmName.Name, asmName.Version, PublicKeyBase.CreatePublicKeyToken(pkt), asmName.CultureInfo?.Name ?? string.Empty)); } /// diff --git a/src/DotNet/Pdb/Managed/DbiModule.cs b/src/DotNet/Pdb/Managed/DbiModule.cs index f0a76bdb8..7016cb510 100644 --- a/src/DotNet/Pdb/Managed/DbiModule.cs +++ b/src/DotNet/Pdb/Managed/DbiModule.cs @@ -157,7 +157,7 @@ void ReadLines(DbiFunction[] funcs, Dictionary documents, ref if (funcs[found].Lines is null) { while (found > 0) { var prevFunc = funcs[found - 1]; - if (prevFunc is not null || prevFunc.Address != address) + if (prevFunc is not null && prevFunc.Address != address) break; found--; } From 6014534eeb75179dca7095235ba5bff47038908f Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Wed, 12 Jul 2023 05:29:33 +0800 Subject: [PATCH 474/511] Improve Importer TryToUseTypeDefs --- src/DotNet/Importer.cs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index aa0f02b8f..8004f977c 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -84,9 +84,9 @@ public abstract class ImportMapper { /// Overrides default behavior of /// May be used to use reference assemblies for resolution, for example. /// - /// to create for. is non-generic type or generic type without generic arguments. - /// or null to use default 's type resolution - public virtual TypeRef Map(Type source) => null; + /// to create for. is non-generic type or generic type without generic arguments. + /// or null to use default 's type resolution + public virtual ITypeDefOrRef Map(Type source) => null; } /// @@ -223,8 +223,8 @@ TypeSig ImportAsTypeSig(Type type, Type declaringType, bool? treatAsGenericInst case ElementType.Ptr: return new PtrSig(ImportAsTypeSig(type.GetElementType(), declaringType)); case ElementType.ByRef: return new ByRefSig(ImportAsTypeSig(type.GetElementType(), declaringType)); case ElementType.SZArray: return new SZArraySig(ImportAsTypeSig(type.GetElementType(), declaringType)); - case ElementType.ValueType: return new ValueTypeSig(CreateTypeRef(type)); - case ElementType.Class: return new ClassSig(CreateTypeRef(type)); + case ElementType.ValueType: return new ValueTypeSig(CreateTypeDefOrRef(type)); + case ElementType.Class: return new ClassSig(CreateTypeDefOrRef(type)); case ElementType.Var: return new GenericVar((uint)type.GenericParameterPosition, gpContext.Type); case ElementType.MVar: return new GenericMVar((uint)type.GenericParameterPosition, gpContext.Method); @@ -356,13 +356,26 @@ static bool Equals(IAssembly a, IAssembly b) { UTF8String.CaseInsensitiveEquals(a.Culture, b.Culture); } - ITypeDefOrRef CreateTypeRef(Type type) => TryResolve(mapper?.Map(type) ?? CreateTypeRef2(type)); + ITypeDefOrRef CreateTypeDefOrRef(Type type) { + var tdr = mapper?.Map(type); + if (tdr is TypeSpec) + throw new InvalidOperationException(); + if (tdr is TypeDef td) + return td; + if (tdr is TypeRef tr) + return TryResolve(tr); + + if (TryToUseTypeDefs && IsThisModule(type.Module) && module.ResolveToken(type.MetadataToken) is TypeDef def) + return def; + + return TryResolve(CreateTypeRef(type)); + } - TypeRef CreateTypeRef2(Type type) { + TypeRef CreateTypeRef(Type type) { if (!type.IsNested) return module.UpdateRowId(new TypeRefUser(module, type.Namespace ?? string.Empty, ReflectionExtensions.Unescape(type.Name) ?? string.Empty, CreateScopeReference(type))); type.GetTypeNamespaceAndName_TypeDefOrRef(out var @namespace, out var name); - return module.UpdateRowId(new TypeRefUser(module, @namespace ?? string.Empty, name ?? string.Empty, CreateTypeRef2(type.DeclaringType))); + return module.UpdateRowId(new TypeRefUser(module, @namespace ?? string.Empty, name ?? string.Empty, CreateTypeRef(type.DeclaringType))); } IResolutionScope CreateScopeReference(Type type) { From e9549f3f73842e68a9d9606cd18aa17f49936de6 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Fri, 21 Jul 2023 03:29:27 +0800 Subject: [PATCH 475/511] Compare reference only for MemberDefs if they are from the same module --- src/DotNet/SigComparer.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 9dabd6826..e5ac94bc6 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -1475,6 +1475,8 @@ public bool Equals(TypeDef a, TypeDef b) { return true; if (a is null || b is null) return false; + if (FromSameModule(a, b)) + return false; if (!recursionCounter.Increment()) return false; @@ -2605,6 +2607,8 @@ public bool Equals(MethodDef a, MethodDef b) { return true; if (a is null || b is null) return false; + if (FromSameModule(a, b)) + return false; if (!recursionCounter.Increment()) return false; @@ -2933,6 +2937,8 @@ public bool Equals(FieldDef a, FieldDef b) { return true; if (a is null || b is null) return false; + if (FromSameModule(a, b)) + return false; if (!recursionCounter.Increment()) return false; @@ -2978,6 +2984,8 @@ public bool Equals(PropertyDef a, PropertyDef b) { return true; if (a is null || b is null) return false; + if (FromSameModule(a, b)) + return false; if (!recursionCounter.Increment()) return false; @@ -3024,6 +3032,8 @@ public bool Equals(EventDef a, EventDef b) { return true; if (a is null || b is null) return false; + if (FromSameModule(a, b)) + return false; if (!recursionCounter.Increment()) return false; @@ -4684,5 +4694,7 @@ public int GetHashCode(EventInfo a) { /// public override string ToString() => $"{recursionCounter} - {options}"; + + static bool FromSameModule(IOwnerModule a, IOwnerModule b) => a.Module is { } module && module == b.Module; } } From af2f56a4b5932efdf5a908fb02949f22ff6f1901 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Sat, 22 Jul 2023 11:12:14 +0800 Subject: [PATCH 476/511] Add DisableCompareReferenceOnlyForMemberDefsInSameModule --- src/DotNet/SigComparer.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index e5ac94bc6..754ca8a61 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -485,6 +485,12 @@ public enum SigComparerOptions : uint { /// When comparing types, don't compare a multi-dimensional array's lower bounds and sizes /// IgnoreMultiDimensionalArrayLowerBoundsAndSizes = 0x800000, + + /// + /// When comparing MemberDefs in same module, comparing reference only can avoid conflict when members have same signature. + /// If this flag is set, these members are compared just like any other members. + /// + DisableCompareReferenceOnlyForMemberDefsInSameModule = 0x1000000, } /// @@ -535,6 +541,7 @@ public struct SigComparer { bool DontProjectWinMDRefs => (options & SigComparerOptions.DontProjectWinMDRefs) != 0; bool DontCheckTypeEquivalence => (options & SigComparerOptions.DontCheckTypeEquivalence) != 0; bool IgnoreMultiDimensionalArrayLowerBoundsAndSizes => (options & SigComparerOptions.IgnoreMultiDimensionalArrayLowerBoundsAndSizes) != 0; + bool CompareReferenceOnlyForMemberDefsInSameModule => (options & SigComparerOptions.DisableCompareReferenceOnlyForMemberDefsInSameModule) == 0; /// /// Constructor @@ -1475,7 +1482,7 @@ public bool Equals(TypeDef a, TypeDef b) { return true; if (a is null || b is null) return false; - if (FromSameModule(a, b)) + if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -2607,7 +2614,7 @@ public bool Equals(MethodDef a, MethodDef b) { return true; if (a is null || b is null) return false; - if (FromSameModule(a, b)) + if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -2937,7 +2944,7 @@ public bool Equals(FieldDef a, FieldDef b) { return true; if (a is null || b is null) return false; - if (FromSameModule(a, b)) + if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -2984,7 +2991,7 @@ public bool Equals(PropertyDef a, PropertyDef b) { return true; if (a is null || b is null) return false; - if (FromSameModule(a, b)) + if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -3032,7 +3039,7 @@ public bool Equals(EventDef a, EventDef b) { return true; if (a is null || b is null) return false; - if (FromSameModule(a, b)) + if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -4695,6 +4702,6 @@ public int GetHashCode(EventInfo a) { /// public override string ToString() => $"{recursionCounter} - {options}"; - static bool FromSameModule(IOwnerModule a, IOwnerModule b) => a.Module is { } module && module == b.Module; + static bool InSameModule(IOwnerModule a, IOwnerModule b) => a.Module is { } module && module == b.Module; } } From 1b988c44501f617fce83b6234b2c2ebdb119976a Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 31 Jul 2023 13:17:46 +0200 Subject: [PATCH 477/511] Add setter for `ArrayWriter.Position` --- src/DotNet/Writer/ArrayWriter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Writer/ArrayWriter.cs b/src/DotNet/Writer/ArrayWriter.cs index 721c0b46f..d997ee5d8 100644 --- a/src/DotNet/Writer/ArrayWriter.cs +++ b/src/DotNet/Writer/ArrayWriter.cs @@ -11,7 +11,10 @@ public unsafe struct ArrayWriter { /// /// Gets the current position /// - public int Position => position; + public int Position { + get => position; + set => position = value; + } readonly byte[] data; int position; From b257e88e41175e52749b91332a4ba8648ccd037d Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 31 Jul 2023 13:22:20 +0200 Subject: [PATCH 478/511] Add `IChunk.CalculateAlignment` --- Examples/Example6.cs | 1 + src/DotNet/Writer/ByteArrayChunk.cs | 10 +++++++++- src/DotNet/Writer/ChunkListBase.cs | 15 +++++++++++++++ src/DotNet/Writer/DataReaderChunk.cs | 3 +++ src/DotNet/Writer/DebugDirectory.cs | 3 +++ src/DotNet/Writer/HeapBase.cs | 3 +++ src/DotNet/Writer/IChunk.cs | 7 +++++++ src/DotNet/Writer/ImageCor20Header.cs | 3 +++ src/DotNet/Writer/ImportAddressTable.cs | 3 +++ src/DotNet/Writer/ImportDirectory.cs | 3 +++ src/DotNet/Writer/ManagedExportsWriter.cs | 4 ++++ src/DotNet/Writer/Metadata.cs | 3 +++ src/DotNet/Writer/MetadataHeader.cs | 3 +++ src/DotNet/Writer/MethodBody.cs | 3 +++ src/DotNet/Writer/MethodBodyChunks.cs | 3 +++ src/DotNet/Writer/ModuleWriterBase.cs | 2 ++ src/DotNet/Writer/NetResources.cs | 3 +++ src/DotNet/Writer/PEHeaders.cs | 3 +++ src/DotNet/Writer/RelocDirectory.cs | 3 +++ src/DotNet/Writer/StartupStub.cs | 3 +++ src/DotNet/Writer/StrongNameSignature.cs | 3 +++ src/DotNet/Writer/TablesHeap.cs | 3 +++ src/DotNet/Writer/Win32ResourcesChunk.cs | 3 +++ 23 files changed, 89 insertions(+), 1 deletion(-) diff --git a/Examples/Example6.cs b/Examples/Example6.cs index 83a3ce48e..1a823fc18 100644 --- a/Examples/Example6.cs +++ b/Examples/Example6.cs @@ -79,6 +79,7 @@ public void SetOffset(FileOffset offset, RVA rva) { public uint GetFileLength() => (uint)heapData.Length; public uint GetVirtualSize() => GetFileLength(); + public uint CalculateAlignment() => 0; public void WriteTo(DataWriter writer) => writer.WriteBytes(heapData); } diff --git a/src/DotNet/Writer/ByteArrayChunk.cs b/src/DotNet/Writer/ByteArrayChunk.cs index 0bd6c5f37..4a6b4c3a4 100644 --- a/src/DotNet/Writer/ByteArrayChunk.cs +++ b/src/DotNet/Writer/ByteArrayChunk.cs @@ -10,6 +10,7 @@ namespace dnlib.DotNet.Writer { /// public sealed class ByteArrayChunk : IReuseChunk { readonly byte[] array; + readonly uint alignment; FileOffset offset; RVA rva; @@ -32,7 +33,11 @@ public sealed class ByteArrayChunk : IReuseChunk { /// return value will be different if you modify the array). If /// it's never inserted as a key in a dictionary, then the contents can be modified, /// but shouldn't be resized after has been called. - public ByteArrayChunk(byte[] array) => this.array = array ?? Array2.Empty(); + /// The alignment of the data + public ByteArrayChunk(byte[] array, uint alignment = 0) { + this.array = array ?? Array2.Empty(); + this.alignment = alignment; + } bool IReuseChunk.CanReuse(RVA origRva, uint origSize) => (uint)array.Length <= origSize; @@ -48,6 +53,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => alignment; + /// public void WriteTo(DataWriter writer) => writer.WriteBytes(array); diff --git a/src/DotNet/Writer/ChunkListBase.cs b/src/DotNet/Writer/ChunkListBase.cs index 321809ac2..b7bd2b40d 100644 --- a/src/DotNet/Writer/ChunkListBase.cs +++ b/src/DotNet/Writer/ChunkListBase.cs @@ -1,5 +1,6 @@ // dnlib: See LICENSE.txt for more info +using System; using System.Collections.Generic; using dnlib.IO; using dnlib.PE; @@ -114,5 +115,19 @@ public void WriteTo(DataWriter writer) { offset2 += (uint)paddingF + elem.chunk.GetFileLength(); } } + + /// + public virtual uint CalculateAlignment() { + uint alignment = 0; + for (int i = 0; i < chunks.Count; i++) { + var elem = chunks[i]; + uint newAlignment = Math.Max(elem.alignment, elem.chunk.CalculateAlignment()); + chunks[i] = new Elem(elem.chunk, newAlignment); + + alignment = Math.Max(alignment, newAlignment); + } + + return alignment; + } } } diff --git a/src/DotNet/Writer/DataReaderChunk.cs b/src/DotNet/Writer/DataReaderChunk.cs index defaa43ec..cf9a20c0d 100644 --- a/src/DotNet/Writer/DataReaderChunk.cs +++ b/src/DotNet/Writer/DataReaderChunk.cs @@ -86,6 +86,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => virtualSize; + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { data.Position = 0; diff --git a/src/DotNet/Writer/DebugDirectory.cs b/src/DotNet/Writer/DebugDirectory.cs index 3d62d6582..f8d09faaa 100644 --- a/src/DotNet/Writer/DebugDirectory.cs +++ b/src/DotNet/Writer/DebugDirectory.cs @@ -139,6 +139,9 @@ static uint GetLength(List entries, FileOffset offset, RVA /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { uint offset = 0; diff --git a/src/DotNet/Writer/HeapBase.cs b/src/DotNet/Writer/HeapBase.cs index 99831e387..567850e4c 100644 --- a/src/DotNet/Writer/HeapBase.cs +++ b/src/DotNet/Writer/HeapBase.cs @@ -51,6 +51,9 @@ public virtual void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// /// Gets the raw length of the heap /// diff --git a/src/DotNet/Writer/IChunk.cs b/src/DotNet/Writer/IChunk.cs index d358d3020..061321a48 100644 --- a/src/DotNet/Writer/IChunk.cs +++ b/src/DotNet/Writer/IChunk.cs @@ -40,6 +40,13 @@ public interface IChunk { /// Virtual size of this chunk uint GetVirtualSize(); + /// + /// Calculates the requires alignment of this chunk. + /// Returns 0 for default/no alignment. + /// + /// Required alignment + uint CalculateAlignment(); + /// /// Writes all data to at its current location. It's only /// called after and have been called. diff --git a/src/DotNet/Writer/ImageCor20Header.cs b/src/DotNet/Writer/ImageCor20Header.cs index 4385fd9c5..154c3fa6d 100644 --- a/src/DotNet/Writer/ImageCor20Header.cs +++ b/src/DotNet/Writer/ImageCor20Header.cs @@ -113,6 +113,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { writer.WriteInt32(0x48); // cb diff --git a/src/DotNet/Writer/ImportAddressTable.cs b/src/DotNet/Writer/ImportAddressTable.cs index 05ce2e9ee..d789e7890 100644 --- a/src/DotNet/Writer/ImportAddressTable.cs +++ b/src/DotNet/Writer/ImportAddressTable.cs @@ -47,6 +47,9 @@ public uint GetFileLength() { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { if (!Enable) diff --git a/src/DotNet/Writer/ImportDirectory.cs b/src/DotNet/Writer/ImportDirectory.cs index c871aed8f..23fe2b931 100644 --- a/src/DotNet/Writer/ImportDirectory.cs +++ b/src/DotNet/Writer/ImportDirectory.cs @@ -104,6 +104,9 @@ public uint GetFileLength() { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { if (!Enable) diff --git a/src/DotNet/Writer/ManagedExportsWriter.cs b/src/DotNet/Writer/ManagedExportsWriter.cs index 8f9bdf87a..6455b2ccb 100644 --- a/src/DotNet/Writer/ManagedExportsWriter.cs +++ b/src/DotNet/Writer/ManagedExportsWriter.cs @@ -44,6 +44,7 @@ sealed class ExportDir : IChunk { void IChunk.SetOffset(FileOffset offset, RVA rva) => throw new NotSupportedException(); public uint GetFileLength() => owner.ExportDirSize; public uint GetVirtualSize() => GetFileLength(); + public uint CalculateAlignment() => 0; void IChunk.WriteTo(DataWriter writer) => throw new NotSupportedException(); } @@ -61,6 +62,7 @@ public void SetOffset(FileOffset offset, RVA rva) { } public uint GetFileLength() => length; public uint GetVirtualSize() => GetFileLength(); + public uint CalculateAlignment() => 0; public void WriteTo(DataWriter writer) => owner.WriteVtableFixups(writer); } @@ -78,6 +80,7 @@ public void SetOffset(FileOffset offset, RVA rva) { } public uint GetFileLength() => length; public uint GetVirtualSize() => GetFileLength(); + public uint CalculateAlignment() => 0; public void WriteTo(DataWriter writer) => owner.WriteStubs(writer); } @@ -95,6 +98,7 @@ public void SetOffset(FileOffset offset, RVA rva) { } public uint GetFileLength() => length; public uint GetVirtualSize() => GetFileLength(); + public uint CalculateAlignment() => 0; public void WriteTo(DataWriter writer) => owner.WriteSdata(writer); } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index d683548e9..d52d98afe 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -3774,6 +3774,9 @@ IList GetHeaps() { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { var rva2 = rva; diff --git a/src/DotNet/Writer/MetadataHeader.cs b/src/DotNet/Writer/MetadataHeader.cs index aabcd7372..4fe2841fe 100644 --- a/src/DotNet/Writer/MetadataHeader.cs +++ b/src/DotNet/Writer/MetadataHeader.cs @@ -135,6 +135,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { writer.WriteUInt32(options.Signature ?? MetadataHeaderOptions.DEFAULT_SIGNATURE); diff --git a/src/DotNet/Writer/MethodBody.cs b/src/DotNet/Writer/MethodBody.cs index b6c4cfef0..3c6464dd7 100644 --- a/src/DotNet/Writer/MethodBody.cs +++ b/src/DotNet/Writer/MethodBody.cs @@ -132,6 +132,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { writer.WriteBytes(code); diff --git a/src/DotNet/Writer/MethodBodyChunks.cs b/src/DotNet/Writer/MethodBodyChunks.cs index ef08416c3..63ab29ae2 100644 --- a/src/DotNet/Writer/MethodBodyChunks.cs +++ b/src/DotNet/Writer/MethodBodyChunks.cs @@ -171,6 +171,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { var rva2 = rva; diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 5c77af110..7089a038b 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -785,6 +785,8 @@ protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offse int count = chunks.Count; for (int i = 0; i < count; i++) { var chunk = chunks[i]; + // TODO: We should probably align the offset and RVA here to the chunk's required alignment! + chunk.CalculateAlignment(); chunk.SetOffset(offset, rva); // If it has zero size, it's not present in the file (eg. a section that wasn't needed) if (chunk.GetVirtualSize() != 0) { diff --git a/src/DotNet/Writer/NetResources.cs b/src/DotNet/Writer/NetResources.cs index e04a9cf6b..f2986f2ea 100644 --- a/src/DotNet/Writer/NetResources.cs +++ b/src/DotNet/Writer/NetResources.cs @@ -74,6 +74,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { var rva2 = rva; diff --git a/src/DotNet/Writer/PEHeaders.cs b/src/DotNet/Writer/PEHeaders.cs index 899f7ec9d..34502b779 100644 --- a/src/DotNet/Writer/PEHeaders.cs +++ b/src/DotNet/Writer/PEHeaders.cs @@ -325,6 +325,9 @@ int SectionsCount { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + IEnumerable GetSectionSizeInfos() { foreach (var section in sections) { uint virtSize = section.GetVirtualSize(); diff --git a/src/DotNet/Writer/RelocDirectory.cs b/src/DotNet/Writer/RelocDirectory.cs index ab3c332b1..6b7d4c03e 100644 --- a/src/DotNet/Writer/RelocDirectory.cs +++ b/src/DotNet/Writer/RelocDirectory.cs @@ -81,6 +81,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { bool is64bit = machine.Is64Bit(); diff --git a/src/DotNet/Writer/StartupStub.cs b/src/DotNet/Writer/StartupStub.cs index e5c36f64d..fc212cead 100644 --- a/src/DotNet/Writer/StartupStub.cs +++ b/src/DotNet/Writer/StartupStub.cs @@ -82,6 +82,9 @@ public uint GetFileLength() { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { if (!Enable) diff --git a/src/DotNet/Writer/StrongNameSignature.cs b/src/DotNet/Writer/StrongNameSignature.cs index 088f8e3ff..c485cba6b 100644 --- a/src/DotNet/Writer/StrongNameSignature.cs +++ b/src/DotNet/Writer/StrongNameSignature.cs @@ -38,6 +38,9 @@ public void SetOffset(FileOffset offset, RVA rva) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) => writer.WriteZeroes(size); } diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index c79ac83a8..a578a7938 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -331,6 +331,9 @@ public uint GetFileLength() { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// /// Calculates the length. This will set all MD tables to read-only. /// diff --git a/src/DotNet/Writer/Win32ResourcesChunk.cs b/src/DotNet/Writer/Win32ResourcesChunk.cs index 3898d9cd3..cf75e819b 100644 --- a/src/DotNet/Writer/Win32ResourcesChunk.cs +++ b/src/DotNet/Writer/Win32ResourcesChunk.cs @@ -353,6 +353,9 @@ void FindDirectoryEntries(ResourceDirectory dir) { /// public uint GetVirtualSize() => GetFileLength(); + /// + public uint CalculateAlignment() => 0; + /// public void WriteTo(DataWriter writer) { uint offset = 0; From 0f1399b93585de03215c0e63756f62fd53c80369 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 1 Aug 2023 12:31:32 +0200 Subject: [PATCH 479/511] Use field initial value alignment defined in `PackingSize` --- src/DotNet/Writer/Metadata.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index d52d98afe..3ae04974e 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2704,7 +2704,15 @@ protected void AddFieldRVA(FieldDef field) { if (!VerifyFieldSize(field, ivBytes.Length)) Error("Field '{0}' (0x{1:X8}) initial value size != size of field type.", field, field.MDToken.Raw); uint rid = GetRid(field); - var iv = constants.Add(new ByteArrayChunk(ivBytes), ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT); + + uint alignment = ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT; + const uint MaxFieldInitialValueAlignment = 1024U; + if (field.FieldType is TypeDefOrRefSig tdrSig && tdrSig.TypeDef?.ClassLayout is {} classLayout) { + uint requiredAlignment = Math.Max(RoundUpToPowerOfTwo(classLayout.PackingSize), MaxFieldInitialValueAlignment); + alignment = Math.Max(alignment, requiredAlignment); + } + + var iv = constants.Add(new ByteArrayChunk(ivBytes, alignment), alignment); fieldToInitialValue[field] = iv; var row = new RawFieldRVARow(0, rid); fieldRVAInfos.Add(field, row); @@ -2720,6 +2728,16 @@ static bool VerifyFieldSize(FieldDef field, int size) { return field.GetFieldSize() == size; } + static uint RoundUpToPowerOfTwo(uint num) { + num--; + num |= num >> 1; + num |= num >> 2; + num |= num >> 4; + num |= num >> 8; + num |= num >> 16; + return num + 1; + } + /// /// Adds a ImplMap row /// From b6d5644b6f049f5d3cccd888b607715eeeefcf51 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 1 Aug 2023 19:00:02 +0200 Subject: [PATCH 480/511] Fix incorrect `Math.Max` call --- src/DotNet/Writer/Metadata.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 3ae04974e..06dedfa2d 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2708,7 +2708,7 @@ protected void AddFieldRVA(FieldDef field) { uint alignment = ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT; const uint MaxFieldInitialValueAlignment = 1024U; if (field.FieldType is TypeDefOrRefSig tdrSig && tdrSig.TypeDef?.ClassLayout is {} classLayout) { - uint requiredAlignment = Math.Max(RoundUpToPowerOfTwo(classLayout.PackingSize), MaxFieldInitialValueAlignment); + uint requiredAlignment = Math.Min(RoundUpToPowerOfTwo(classLayout.PackingSize), MaxFieldInitialValueAlignment); alignment = Math.Max(alignment, requiredAlignment); } From 61dfaa292d9d4cc1001f060abe64b1f3044bac7f Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 1 Aug 2023 21:42:54 +0200 Subject: [PATCH 481/511] Move `RoundUpToPowerOfTwo` to `Utils` --- src/DotNet/Utils.cs | 14 ++++++++++++++ src/DotNet/Writer/Metadata.cs | 12 +----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index 362846adb..5085426f4 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -316,5 +316,19 @@ static string GetCanonicalLocale(string locale) { /// Value /// Alignment public static int AlignUp(int v, uint alignment) => (int)AlignUp((uint)v, alignment); + + /// + /// Rounds up the provided number to the next power of 2 + /// + /// The number to round + public static uint RoundToNextPowerOfTwo(uint num) { + num--; + num |= num >> 1; + num |= num >> 2; + num |= num >> 4; + num |= num >> 8; + num |= num >> 16; + return num + 1; + } } } diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 06dedfa2d..8090951a3 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2708,7 +2708,7 @@ protected void AddFieldRVA(FieldDef field) { uint alignment = ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT; const uint MaxFieldInitialValueAlignment = 1024U; if (field.FieldType is TypeDefOrRefSig tdrSig && tdrSig.TypeDef?.ClassLayout is {} classLayout) { - uint requiredAlignment = Math.Min(RoundUpToPowerOfTwo(classLayout.PackingSize), MaxFieldInitialValueAlignment); + uint requiredAlignment = Math.Min(Utils.RoundToNextPowerOfTwo(classLayout.PackingSize), MaxFieldInitialValueAlignment); alignment = Math.Max(alignment, requiredAlignment); } @@ -2728,16 +2728,6 @@ static bool VerifyFieldSize(FieldDef field, int size) { return field.GetFieldSize() == size; } - static uint RoundUpToPowerOfTwo(uint num) { - num--; - num |= num >> 1; - num |= num >> 2; - num |= num >> 4; - num |= num >> 8; - num |= num >> 16; - return num + 1; - } - /// /// Adds a ImplMap row /// From 976a66d546d526de18d4124453a695e79e899c6b Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 2 Aug 2023 21:26:19 +0200 Subject: [PATCH 482/511] Optimize implementations of `IType.Namespace` and `IType.TypeName` --- src/DotNet/ExportedType.cs | 4 ++-- src/DotNet/TypeDef.cs | 4 ++-- src/DotNet/TypeRef.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 44aa0f8c9..270f556f6 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -94,7 +94,7 @@ public bool IsValueType { public bool IsPrimitive => this.IsPrimitive(); /// - string IType.TypeName => FullNameFactory.Name(this, false, null); + string IType.TypeName => TypeName; /// public UTF8String Name { @@ -106,7 +106,7 @@ public UTF8String Name { public string ReflectionName => FullNameFactory.Name(this, true, null); /// - public string Namespace => FullNameFactory.Namespace(this, false, null); + public string Namespace => TypeNamespace; /// public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index 7f5944472..e46b36bcd 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -52,13 +52,13 @@ public uint Rid { int IGenericParameterProvider.NumberOfGenericParameters => GenericParameters.Count; /// - string IType.TypeName => FullNameFactory.Name(this, false, null); + string IType.TypeName => Name; /// public string ReflectionName => FullNameFactory.Name(this, true, null); /// - string IType.Namespace => FullNameFactory.Namespace(this, false, null); + string IType.Namespace => Namespace; /// public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); diff --git a/src/DotNet/TypeRef.cs b/src/DotNet/TypeRef.cs index cc5360eb4..bfaa511f5 100644 --- a/src/DotNet/TypeRef.cs +++ b/src/DotNet/TypeRef.cs @@ -52,13 +52,13 @@ public uint Rid { int IGenericParameterProvider.NumberOfGenericParameters => 0; /// - string IType.TypeName => FullNameFactory.Name(this, false, null); + string IType.TypeName => Name; /// public string ReflectionName => FullNameFactory.Name(this, true, null); /// - string IType.Namespace => FullNameFactory.Namespace(this, false, null); + string IType.Namespace => Namespace; /// public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); From 8fac3fc224d2d64bf64fb22cb55ef9cacd6e92c5 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 5 Aug 2023 12:07:34 +0200 Subject: [PATCH 483/511] Merge `Utils.GetAssemblyNameString` into `FullNameFactory` --- src/DotNet/AssemblyDef.cs | 6 +- src/DotNet/AssemblyNameInfo.cs | 9 +-- src/DotNet/AssemblyRef.cs | 4 +- src/DotNet/FullNameFactory.cs | 103 ++++++++++++++++++++++++--------- src/DotNet/Utils.cs | 41 ------------- 5 files changed, 80 insertions(+), 83 deletions(-) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index bb081eec0..0e89652c1 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -503,14 +503,12 @@ public static AssemblyDef Load(Stream stream, ModuleCreationOptions options = nu /// /// Gets the assembly name with the public key /// - public string GetFullNameWithPublicKey() => GetFullName(publicKey); + public string GetFullNameWithPublicKey() => FullNameFactory.AssemblyFullName(this, false); /// /// Gets the assembly name with the public key token /// - public string GetFullNameWithPublicKeyToken() => GetFullName(publicKey.Token); - - string GetFullName(PublicKeyBase pkBase) => Utils.GetAssemblyNameString(name, version, culture, pkBase, Attributes); + public string GetFullNameWithPublicKeyToken() => FullNameFactory.AssemblyFullName(this, true); /// /// Finds a . For speed, enable diff --git a/src/DotNet/AssemblyNameInfo.cs b/src/DotNet/AssemblyNameInfo.cs index f2ec9c588..9e76d400f 100644 --- a/src/DotNet/AssemblyNameInfo.cs +++ b/src/DotNet/AssemblyNameInfo.cs @@ -71,14 +71,7 @@ public UTF8String Culture { /// /// Gets the full name of the assembly but use a public key token /// - public string FullNameToken { - get { - var pk = publicKeyOrToken; - if (pk is PublicKey) - pk = (pk as PublicKey).Token; - return Utils.GetAssemblyNameString(name, version, culture, pk, flags); - } - } + public string FullNameToken => FullNameFactory.AssemblyFullName(this, true); /// /// Modify property: = diff --git a/src/DotNet/AssemblyRef.cs b/src/DotNet/AssemblyRef.cs index f275854d3..f025cfffb 100644 --- a/src/DotNet/AssemblyRef.cs +++ b/src/DotNet/AssemblyRef.cs @@ -159,12 +159,12 @@ protected virtual void InitializeCustomDebugInfos() => /// /// Same as , except that it uses the PublicKey if available. /// - public string RealFullName => Utils.GetAssemblyNameString(name, version, culture, publicKeyOrToken, Attributes); + public string RealFullName => FullNameFactory.AssemblyFullName(this, false); /// /// Gets the full name of the assembly but use a public key token /// - public string FullNameToken => Utils.GetAssemblyNameString(name, version, culture, PublicKeyBase.ToPublicKeyToken(publicKeyOrToken), Attributes); + public string FullNameToken => FullNameFactory.AssemblyFullName(this, true); /// /// Modify property: = diff --git a/src/DotNet/FullNameFactory.cs b/src/DotNet/FullNameFactory.cs index 11ed94c62..5590bb745 100644 --- a/src/DotNet/FullNameFactory.cs +++ b/src/DotNet/FullNameFactory.cs @@ -1002,6 +1002,29 @@ public static IScope Scope(ExportedType exportedType) => public static ModuleDef OwnerModule(ExportedType exportedType) => new FullNameFactory().GetOwnerModule(exportedType); + /// + /// Returns the full assembly name of a + /// + /// The IAssembly + /// true to use public key token in name even if a public key is available + /// String builder to use or null + /// The full assembly name + public static string AssemblyFullName(IAssembly assembly, bool withToken, StringBuilder sb = null) => + AssemblyFullNameSB(assembly, withToken, sb).ToString(); + + /// + /// Returns the full assembly name of a + /// + /// The IAssembly + /// true to use public key token in name even if a public key is available + /// String builder to use or null + /// The full assembly name + public static StringBuilder AssemblyFullNameSB(IAssembly assembly, bool withToken, StringBuilder sb = null) { + var fnc = new FullNameFactory(false, null, sb); + fnc.CreateAssemblyFullName(assembly, withToken); + return fnc.sb ?? new StringBuilder(); + } + string Result => sb?.ToString(); FullNameFactory(bool isReflection, IFullNameFactoryHelper helper, StringBuilder sb) { @@ -1094,8 +1117,10 @@ void CreateAssemblyQualifiedName(TypeRef typeRef) { } CreateFullName(typeRef); - if (MustUseAssemblyName(typeRef)) - AddAssemblyName(GetDefinitionAssembly(typeRef)); + if (MustUseAssemblyName(typeRef)) { + sb.Append(", "); + CreateAssemblyFullName(GetDefinitionAssembly(typeRef), true); + } recursionCounter.Decrement(); } @@ -1149,8 +1174,10 @@ void CreateAssemblyQualifiedName(TypeDef typeDef) { } CreateFullName(typeDef); - if (MustUseAssemblyName(typeDef)) - AddAssemblyName(GetDefinitionAssembly(typeDef)); + if (MustUseAssemblyName(typeDef)) { + sb.Append(", "); + CreateAssemblyFullName(GetDefinitionAssembly(typeDef), true); + } recursionCounter.Decrement(); } @@ -1238,8 +1265,10 @@ void CreateAssemblyQualifiedName(TypeSig typeSig) { } CreateFullName(typeSig); - if (MustUseAssemblyName(typeSig)) - AddAssemblyName(GetDefinitionAssembly(typeSig)); + if (MustUseAssemblyName(typeSig)) { + sb.Append(", "); + CreateAssemblyFullName(GetDefinitionAssembly(typeSig), true); + } recursionCounter.Decrement(); } @@ -1427,11 +1456,7 @@ void CreateTypeSigName(TypeSig typeSig, int flags) { if (mustWriteAssembly) { sb.Append(", "); - var asm = GetDefinitionAssembly(genArg); - if (asm is null) - sb.Append(NULLVALUE); - else - sb.Append(EscapeAssemblyName(GetAssemblyName(asm))); + CreateAssemblyFullName(GetDefinitionAssembly(genArg), true, true); sb.Append(']'); } } @@ -1499,8 +1524,10 @@ void CreateAssemblyQualifiedName(ExportedType exportedType) { } CreateFullName(exportedType); - if (MustUseAssemblyName(exportedType)) - AddAssemblyName(GetDefinitionAssembly(exportedType)); + if (MustUseAssemblyName(exportedType)) { + sb.Append(", "); + CreateAssemblyFullName(GetDefinitionAssembly(exportedType), true); + } recursionCounter.Decrement(); } @@ -1543,13 +1570,6 @@ void CreateName(ExportedType exportedType) { AddName(exportedType.TypeName); } - static string GetAssemblyName(IAssembly assembly) { - var pk = assembly.PublicKeyOrToken; - if (pk is PublicKey) - pk = ((PublicKey)pk).Token; - return Utils.GetAssemblyNameString(EscapeAssemblyName(assembly.Name), assembly.Version, assembly.Culture, pk, assembly.Attributes); - } - static string EscapeAssemblyName(UTF8String asmSimpleName) => EscapeAssemblyName(UTF8String.ToSystemString(asmSimpleName)); @@ -1590,16 +1610,43 @@ bool AddName(UTF8String name) { return true; } - void AddAssemblyName(IAssembly assembly) { - sb.Append(", "); - if (assembly is null) + void CreateAssemblyFullName(IAssembly assembly, bool useToken, bool escapeClosingBracket = false) { + if (assembly is null) { sb.Append(NULLVALUE); - else { - var pkt = assembly.PublicKeyOrToken; - if (pkt is PublicKey) - pkt = ((PublicKey)pkt).Token; - sb.Append(Utils.GetAssemblyNameString(assembly.Name, assembly.Version, assembly.Culture, pkt, assembly.Attributes)); + return; + } + + foreach (var c in UTF8String.ToSystemStringOrEmpty(assembly.Name)) { + if (c == ',' || c == '=' || (escapeClosingBracket && c == ']')) + sb.Append('\\'); + sb.Append(c); + } + + if (assembly.Version is not null) { + sb.Append(", Version="); + sb.Append(Utils.CreateVersionWithNoUndefinedValues(assembly.Version)); + } + + if (assembly.Culture is not null) { + sb.Append(", Culture="); + if (UTF8String.IsNullOrEmpty(assembly.Culture)) + sb.Append("neutral"); + else + sb.Append(escapeClosingBracket ? EscapeAssemblyName(assembly.Culture) : assembly.Culture.String); } + + var publicKey = assembly.PublicKeyOrToken; + if (useToken) + publicKey = PublicKeyBase.ToPublicKeyToken(publicKey); + + sb.Append(", "); + sb.Append(publicKey is null || publicKey is PublicKeyToken ? "PublicKeyToken=" : "PublicKey="); + sb.Append(publicKey is null ? "null" : publicKey.ToString()); + + if (assembly.IsRetargetable) + sb.Append(", Retargetable=Yes"); + if (assembly.IsContentTypeWindowsRuntime) + sb.Append(", ContentType=WindowsRuntime"); } void AddIdentifier(string id) { diff --git a/src/DotNet/Utils.cs b/src/DotNet/Utils.cs index 362846adb..f9eeb8227 100644 --- a/src/DotNet/Utils.cs +++ b/src/DotNet/Utils.cs @@ -22,47 +22,6 @@ sealed class ByteArrayEqualityComparer : IEqualityComparer { } static class Utils { - /// - /// Returns an assembly name string - /// - /// Simple assembly name - /// Version or null - /// Culture or null - /// Public key / public key token or null - /// Assembly attributes - /// An assembly name string - internal static string GetAssemblyNameString(UTF8String name, Version version, UTF8String culture, PublicKeyBase publicKey, AssemblyAttributes attributes) { - var sb = new StringBuilder(); - - foreach (var c in UTF8String.ToSystemStringOrEmpty(name)) { - if (c == ',' || c == '=') - sb.Append('\\'); - sb.Append(c); - } - - if (version is not null) { - sb.Append(", Version="); - sb.Append(CreateVersionWithNoUndefinedValues(version).ToString()); - } - - if (culture is not null) { - sb.Append(", Culture="); - sb.Append(UTF8String.IsNullOrEmpty(culture) ? "neutral" : culture.String); - } - - sb.Append(", "); - sb.Append(publicKey is null || publicKey is PublicKeyToken ? "PublicKeyToken=" : "PublicKey="); - sb.Append(publicKey is null ? "null" : publicKey.ToString()); - - if ((attributes & AssemblyAttributes.Retargetable) != 0) - sb.Append(", Retargetable=Yes"); - - if ((attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime) - sb.Append(", ContentType=WindowsRuntime"); - - return sb.ToString(); - } - /// /// Convert a byte[] to a /// From 53398074b5496961a45ff7b947d97bcaf7190478 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 5 Aug 2023 12:38:19 +0200 Subject: [PATCH 484/511] Implement basic reusage of `StringBuilder` --- src/DotNet/Emit/InstructionPrinter.cs | 2 +- src/DotNet/Writer/CustomAttributeWriter.cs | 10 ++++++++-- src/DotNet/Writer/DeclSecurityWriter.cs | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Emit/InstructionPrinter.cs b/src/DotNet/Emit/InstructionPrinter.cs index 632c0d607..5e1830d84 100644 --- a/src/DotNet/Emit/InstructionPrinter.cs +++ b/src/DotNet/Emit/InstructionPrinter.cs @@ -83,7 +83,7 @@ public static void AddOperandString(StringBuilder sb, Instruction instr, string case OperandType.InlineSig: sb.Append(extra); - sb.Append(FullNameFactory.MethodFullName(null, (UTF8String)null, op as MethodSig, null, null, null, null)); + FullNameFactory.MethodFullNameSB(null, (UTF8String)null, op as MethodSig, null, null, null, sb); break; case OperandType.InlineString: diff --git a/src/DotNet/Writer/CustomAttributeWriter.cs b/src/DotNet/Writer/CustomAttributeWriter.cs index 3d46200cd..2aed607af 100644 --- a/src/DotNet/Writer/CustomAttributeWriter.cs +++ b/src/DotNet/Writer/CustomAttributeWriter.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace dnlib.DotNet.Writer { /// @@ -17,6 +18,7 @@ public interface ICustomAttributeWriterHelper : IWriterError, IFullNameFactoryHe public struct CustomAttributeWriter : IDisposable { readonly ICustomAttributeWriterHelper helper; RecursionCounter recursionCounter; + readonly StringBuilder sb; readonly MemoryStream outStream; readonly DataWriter writer; readonly bool disposeStream; @@ -65,6 +67,7 @@ internal static byte[] Write(ICustomAttributeWriterHelper helper, IList secAttrs) { byte[] WriteFormat1(string xml) => Encoding.Unicode.GetBytes(xml); byte[] WriteFormat2(IList secAttrs) { + var sb = new StringBuilder(); var stream = new MemoryStream(); var writer = new DataWriter(stream); writer.WriteByte((byte)'.'); @@ -81,8 +82,10 @@ byte[] WriteFormat2(IList secAttrs) { helper.Error("SecurityAttribute attribute type is null"); fqn = string.Empty; } - else - fqn = attrType.AssemblyQualifiedName; + else { + sb.Length = 0; + fqn = FullNameFactory.AssemblyQualifiedName(attrType, null, sb); + } Write(writer, fqn); var namedArgsBlob = context is null ? From 25ce6bf65f947707c82c86e1ccc57ea0aeae4727 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 5 Aug 2023 12:57:15 +0200 Subject: [PATCH 485/511] Implementing sorting to `UniqueChunkList` --- src/DotNet/Writer/UniqueChunkList.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/DotNet/Writer/UniqueChunkList.cs b/src/DotNet/Writer/UniqueChunkList.cs index c8cf0f15b..8220b7dac 100644 --- a/src/DotNet/Writer/UniqueChunkList.cs +++ b/src/DotNet/Writer/UniqueChunkList.cs @@ -53,5 +53,17 @@ public T Add(T chunk, uint alignment) { chunks.Add(elem); return elem.chunk; } + + /// + public override uint CalculateAlignment() { + uint alignment = base.CalculateAlignment(); + chunks.Sort(DescendingComparer.Instance); + return alignment; + } + + class DescendingComparer : IComparer { + internal static readonly DescendingComparer Instance = new DescendingComparer(); + public int Compare(Elem x, Elem y) => -x.alignment.CompareTo(y.alignment); + } } } From 241c1e530b4a6d78ce1ddca4b602ee3ac0e4b929 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 5 Aug 2023 13:07:11 +0200 Subject: [PATCH 486/511] Make `Instruction.GetArgumentType` consistent with `ParameterList` --- src/DotNet/Emit/Instruction.cs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Emit/Instruction.cs b/src/DotNet/Emit/Instruction.cs index b3b4ba406..3013665e7 100644 --- a/src/DotNet/Emit/Instruction.cs +++ b/src/DotNet/Emit/Instruction.cs @@ -744,8 +744,34 @@ public TypeSig GetArgumentType(MethodSig methodSig, ITypeDefOrRef declaringType) if (methodSig is null) return null; int index = GetParameterIndex(); - if (index == 0 && methodSig.ImplicitThis) - return declaringType?.IsValueType == true ? new ByRefSig(declaringType.ToTypeSig()) : declaringType.ToTypeSig(); + if (index == 0 && methodSig.ImplicitThis) { + if (declaringType is null) + return null; + TypeSig declSig; + bool isValueType; + if (declaringType is TypeSpec spec) { + declSig = spec.TypeSig; + isValueType = declSig.IsValueType; + } + else { + // Consistent with ParameterList.UpdateThisParameterType + var td = declaringType.ResolveTypeDef(); + if (td is null) + return declaringType.ToTypeSig(); + isValueType = td.IsValueType; + ClassOrValueTypeSig cvSig = isValueType ? new ValueTypeSig(td) : new ClassSig(td); + if (td.HasGenericParameters) { + int gpCount = td.GenericParameters.Count; + var genArgs = new List(gpCount); + for (int i = 0; i < gpCount; i++) + genArgs.Add(new GenericVar(i, td)); + declSig = new GenericInstSig(cvSig, genArgs); + } + else + declSig = cvSig; + } + return isValueType ? new ByRefSig(declSig) : declSig; + } if (methodSig.ImplicitThis) index--; if ((uint)index < (uint)methodSig.Params.Count) From c8ba7654fb6ae016cf014d86b3a41403780318a8 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 6 Aug 2023 20:53:52 +0200 Subject: [PATCH 487/511] Use stable sort in `UniqueChunkList` --- src/DotNet/Writer/UniqueChunkList.cs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/DotNet/Writer/UniqueChunkList.cs b/src/DotNet/Writer/UniqueChunkList.cs index 8220b7dac..225bf801c 100644 --- a/src/DotNet/Writer/UniqueChunkList.cs +++ b/src/DotNet/Writer/UniqueChunkList.cs @@ -57,13 +57,26 @@ public T Add(T chunk, uint alignment) { /// public override uint CalculateAlignment() { uint alignment = base.CalculateAlignment(); - chunks.Sort(DescendingComparer.Instance); + + var keys = new KeyValuePair[chunks.Count]; + for (var i = 0; i < chunks.Count; i++) + keys[i] = new KeyValuePair(i, chunks[i]); + Array.Sort(keys, DescendingStableComparer.Instance); + for (var i = 0; i < keys.Length; i++) + chunks[i] = keys[i].Value; + return alignment; } - class DescendingComparer : IComparer { - internal static readonly DescendingComparer Instance = new DescendingComparer(); - public int Compare(Elem x, Elem y) => -x.alignment.CompareTo(y.alignment); + sealed class DescendingStableComparer : IComparer> { + internal static readonly DescendingStableComparer Instance = new DescendingStableComparer(); + + public int Compare(KeyValuePair x, KeyValuePair y) { + var result = -x.Value.alignment.CompareTo(y.Value.alignment); + if (result != 0) + return result; + return x.Key.CompareTo(y.Key); + } } } } From 2c2aea078001c57ebb8d2b26b13aaa08e92dfaa1 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 6 Aug 2023 20:54:25 +0200 Subject: [PATCH 488/511] Add sanity check to `CalculateRvasAndFileOffsets` --- src/DotNet/Writer/ModuleWriterBase.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/ModuleWriterBase.cs b/src/DotNet/Writer/ModuleWriterBase.cs index 7089a038b..e1b56d6fb 100644 --- a/src/DotNet/Writer/ModuleWriterBase.cs +++ b/src/DotNet/Writer/ModuleWriterBase.cs @@ -783,10 +783,15 @@ protected void CreateMetadataChunks(ModuleDef module) { /// Section alignment protected void CalculateRvasAndFileOffsets(List chunks, FileOffset offset, RVA rva, uint fileAlignment, uint sectionAlignment) { int count = chunks.Count; + var maxAlignment = Math.Min(fileAlignment, sectionAlignment); for (int i = 0; i < count; i++) { var chunk = chunks[i]; - // TODO: We should probably align the offset and RVA here to the chunk's required alignment! - chunk.CalculateAlignment(); + // We don't need to align to result of CalculateAlignment as all the chunks in `chunks` either + // don't need a specific alignment or align themselves. + var alignment = chunk.CalculateAlignment(); + if (alignment > maxAlignment) + Error("Chunk alignment is too big. Chunk: {0}, alignment: {1:X4}", chunk, alignment); + chunk.SetOffset(offset, rva); // If it has zero size, it's not present in the file (eg. a section that wasn't needed) if (chunk.GetVirtualSize() != 0) { From 1727923d48585bca7dd35a02bc34597b3e3ea7a9 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 6 Aug 2023 20:55:39 +0200 Subject: [PATCH 489/511] Remove alignment restriction for `FieldRVA` in `Metadata` --- src/DotNet/Writer/Metadata.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 8090951a3..28e874ae3 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -2706,11 +2706,8 @@ protected void AddFieldRVA(FieldDef field) { uint rid = GetRid(field); uint alignment = ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT; - const uint MaxFieldInitialValueAlignment = 1024U; - if (field.FieldType is TypeDefOrRefSig tdrSig && tdrSig.TypeDef?.ClassLayout is {} classLayout) { - uint requiredAlignment = Math.Min(Utils.RoundToNextPowerOfTwo(classLayout.PackingSize), MaxFieldInitialValueAlignment); - alignment = Math.Max(alignment, requiredAlignment); - } + if (field.FieldType is TypeDefOrRefSig tdrSig && tdrSig.TypeDef?.ClassLayout is {} classLayout) + alignment = Math.Max(alignment, Utils.RoundToNextPowerOfTwo(classLayout.PackingSize)); var iv = constants.Add(new ByteArrayChunk(ivBytes, alignment), alignment); fieldToInitialValue[field] = iv; From 46c56d9af08391dc266ae716a989607a56f45a38 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Fri, 25 Aug 2023 20:31:06 +0200 Subject: [PATCH 490/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 568482ed7..a8d397268 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 3.6.0 + 4.0.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From aa9ac47a38211b5f24d4b92a2044bd6ca334b904 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Fri, 25 Aug 2023 20:43:27 +0200 Subject: [PATCH 491/511] Use latest actions/checkout and actions/setup-dotnet --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19832323d..55fc93c54 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,9 +27,9 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v1 + - uses: actions/setup-dotnet@v3 with: dotnet-version: ${{env.CI_REQ_DOTNET_SDK_VER}} @@ -67,9 +67,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v1 + - uses: actions/setup-dotnet@v3 with: dotnet-version: ${{env.CI_REQ_DOTNET_SDK_VER}} From 532a392ecf96d4f7b3ec62c0dbdd35d91714d6b3 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 1 Sep 2023 18:14:19 +0200 Subject: [PATCH 492/511] Replace faulty flag with `ReferenceCompareForMemberDefsInSameModule` --- src/DotNet/SigComparer.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index 754ca8a61..aab21ce8d 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -487,10 +487,10 @@ public enum SigComparerOptions : uint { IgnoreMultiDimensionalArrayLowerBoundsAndSizes = 0x800000, /// - /// When comparing MemberDefs in same module, comparing reference only can avoid conflict when members have same signature. - /// If this flag is set, these members are compared just like any other members. + /// When comparing MemberDefs in same module, use regular reference comparison instead + /// comparing the signature, name, and other properties. /// - DisableCompareReferenceOnlyForMemberDefsInSameModule = 0x1000000, + ReferenceCompareForMemberDefsInSameModule = 0x1000000, } /// @@ -541,7 +541,7 @@ public struct SigComparer { bool DontProjectWinMDRefs => (options & SigComparerOptions.DontProjectWinMDRefs) != 0; bool DontCheckTypeEquivalence => (options & SigComparerOptions.DontCheckTypeEquivalence) != 0; bool IgnoreMultiDimensionalArrayLowerBoundsAndSizes => (options & SigComparerOptions.IgnoreMultiDimensionalArrayLowerBoundsAndSizes) != 0; - bool CompareReferenceOnlyForMemberDefsInSameModule => (options & SigComparerOptions.DisableCompareReferenceOnlyForMemberDefsInSameModule) == 0; + bool ReferenceCompareForMemberDefsInSameModule => (options & SigComparerOptions.ReferenceCompareForMemberDefsInSameModule) != 0; /// /// Constructor @@ -1482,7 +1482,7 @@ public bool Equals(TypeDef a, TypeDef b) { return true; if (a is null || b is null) return false; - if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) + if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -2614,7 +2614,7 @@ public bool Equals(MethodDef a, MethodDef b) { return true; if (a is null || b is null) return false; - if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) + if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -2944,7 +2944,7 @@ public bool Equals(FieldDef a, FieldDef b) { return true; if (a is null || b is null) return false; - if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) + if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -2991,7 +2991,7 @@ public bool Equals(PropertyDef a, PropertyDef b) { return true; if (a is null || b is null) return false; - if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) + if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; @@ -3039,7 +3039,7 @@ public bool Equals(EventDef a, EventDef b) { return true; if (a is null || b is null) return false; - if (CompareReferenceOnlyForMemberDefsInSameModule && InSameModule(a, b)) + if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) return false; if (!recursionCounter.Increment()) return false; From 552d57055f2be7fdfc2e615f8bce6b47d8cb7969 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Fri, 1 Sep 2023 18:18:37 +0200 Subject: [PATCH 493/511] Add `CompareReferenceInSameModule` convenience properties --- src/DotNet/SigComparer.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/DotNet/SigComparer.cs b/src/DotNet/SigComparer.cs index aab21ce8d..5fbfca772 100644 --- a/src/DotNet/SigComparer.cs +++ b/src/DotNet/SigComparer.cs @@ -21,6 +21,11 @@ public sealed class TypeEqualityComparer : IEqualityComparer, IEqualityCo /// public static readonly TypeEqualityComparer CaseInsensitive = new TypeEqualityComparer(SigComparerOptions.CaseInsensitiveAll); + /// + /// Compares definitions in same module using reference comparison instead of comparing them by name, signature, etc. + /// + public static readonly TypeEqualityComparer CompareReferenceInSameModule = new TypeEqualityComparer(SigComparerOptions.ReferenceCompareForMemberDefsInSameModule); + /// /// Constructor /// @@ -96,6 +101,11 @@ public sealed class FieldEqualityComparer : IEqualityComparer, IEquality /// public static readonly FieldEqualityComparer CaseInsensitiveDontCompareDeclaringTypes = new FieldEqualityComparer(SigComparerOptions.CaseInsensitiveAll); + /// + /// Compares definitions in same module using reference comparison instead of comparing them by name, signature, etc. + /// + public static readonly FieldEqualityComparer CompareReferenceInSameModule = new FieldEqualityComparer(SigComparerOptions.ReferenceCompareForMemberDefsInSameModule); + /// /// Constructor /// @@ -147,6 +157,11 @@ public sealed class MethodEqualityComparer : IEqualityComparer, IEquali /// public static readonly MethodEqualityComparer CaseInsensitiveDontCompareDeclaringTypes = new MethodEqualityComparer(SigComparerOptions.CaseInsensitiveAll); + /// + /// Compares definitions in same module using reference comparison instead of comparing them by name, signature, etc. + /// + public static readonly MethodEqualityComparer CompareReferenceInSameModule = new MethodEqualityComparer(SigComparerOptions.ReferenceCompareForMemberDefsInSameModule); + /// /// Constructor /// @@ -210,6 +225,11 @@ public sealed class PropertyEqualityComparer : IEqualityComparer { /// public static readonly PropertyEqualityComparer CaseInsensitiveDontCompareDeclaringTypes = new PropertyEqualityComparer(SigComparerOptions.CaseInsensitiveAll); + /// + /// Compares definitions in same module using reference comparison instead of comparing them by name, signature, etc. + /// + public static readonly PropertyEqualityComparer CompareReferenceInSameModule = new PropertyEqualityComparer(SigComparerOptions.ReferenceCompareForMemberDefsInSameModule); + /// /// Constructor /// @@ -249,6 +269,11 @@ public sealed class EventEqualityComparer : IEqualityComparer { /// public static readonly EventEqualityComparer CaseInsensitiveDontCompareDeclaringTypes = new EventEqualityComparer(SigComparerOptions.CaseInsensitiveAll); + /// + /// Compares definitions in same module using reference comparison instead of comparing them by name, signature, etc. + /// + public static readonly EventEqualityComparer CompareReferenceInSameModule = new EventEqualityComparer(SigComparerOptions.ReferenceCompareForMemberDefsInSameModule); + /// /// Constructor /// From efba133fd175878cc4612d0a20715d352fd3e7c2 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Sat, 2 Sep 2023 13:03:54 +0200 Subject: [PATCH 494/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index a8d397268..c82a6e05b 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 4.0.0 + 4.1.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From aac31a1e733b6596f5290b88e5511f2837a31e9e Mon Sep 17 00:00:00 2001 From: AlanLiu90 Date: Thu, 21 Sep 2023 02:38:25 +0800 Subject: [PATCH 495/511] Optimize finding CustomAttribute by a full name (#527) * Optimize finding CustomAttribute by a full name * Revert newlines * Check if fullName is null --- src/DotNet/CustomAttribute.cs | 22 ++++++++++++++++++++-- src/DotNet/CustomAttributeCollection.cs | 16 +++++++++++++--- src/DotNet/MemberRef.cs | 24 ++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/DotNet/CustomAttribute.cs b/src/DotNet/CustomAttribute.cs index 030d27fb2..377fdf82e 100644 --- a/src/DotNet/CustomAttribute.cs +++ b/src/DotNet/CustomAttribute.cs @@ -43,8 +43,26 @@ public string TypeFullName { return string.Empty; } - } - + } + + /// + /// Gets the name of the attribute type + /// + internal string TypeName { + get { + if (ctor is MemberRef mrCtor) + return mrCtor.GetDeclaringTypeName() ?? string.Empty; + + if (ctor is MethodDef mdCtor) { + var declType = mdCtor.DeclaringType; + if (declType is not null) + return declType.Name; + } + + return string.Empty; + } + } + /// /// true if the raw custom attribute blob hasn't been parsed /// diff --git a/src/DotNet/CustomAttributeCollection.cs b/src/DotNet/CustomAttributeCollection.cs index c3b8a53af..07fba4659 100644 --- a/src/DotNet/CustomAttributeCollection.cs +++ b/src/DotNet/CustomAttributeCollection.cs @@ -37,8 +37,12 @@ public CustomAttributeCollection(int length, object context, Func /// Full name of custom attribute type that should be removed public void RemoveAll(string fullName) { + if (fullName == null) + return; + for (int i = Count - 1; i >= 0; i--) { - if (this[i].TypeFullName == fullName) + var ca = this[i]; + if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName) RemoveAt(i); } } @@ -49,8 +53,11 @@ public void RemoveAll(string fullName) { /// Full name of custom attribute type /// A or null if it wasn't found public CustomAttribute Find(string fullName) { + if (fullName == null) + return null; + foreach (var ca in this) { - if (ca is not null && ca.TypeFullName == fullName) + if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName) return ca; } @@ -63,8 +70,11 @@ public CustomAttribute Find(string fullName) { /// Full name of custom attribute type /// All s of the requested type public IEnumerable FindAll(string fullName) { + if (fullName == null) + yield break; + foreach (var ca in this) { - if (ca is not null && ca.TypeFullName == fullName) + if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName) yield return ca; } } diff --git a/src/DotNet/MemberRef.cs b/src/DotNet/MemberRef.cs index ef1fe8325..fb0f587fd 100644 --- a/src/DotNet/MemberRef.cs +++ b/src/DotNet/MemberRef.cs @@ -285,8 +285,28 @@ string GetDeclaringTypeFullName(IMemberRefParent parent) { return declaringType?.FullName; } return null; // Should never be reached - } - + } + + /// + /// Get the declaring type's name + /// + /// Name or null if there's no declaring type + internal string GetDeclaringTypeName() => GetDeclaringTypeName(@class); + + string GetDeclaringTypeName(IMemberRefParent parent) { + if (parent is null) + return null; + if (parent is ITypeDefOrRef) + return ((ITypeDefOrRef)parent).Name; + if (parent is ModuleRef) + return $""; + if (parent is MethodDef) { + var declaringType = ((MethodDef)parent).DeclaringType; + return declaringType?.Name; + } + return null; // Should never be reached + } + /// /// Resolves the method/field /// From 185557c5731f4ed3c802caed634358311a7f88ba Mon Sep 17 00:00:00 2001 From: wtfsck Date: Fri, 22 Sep 2023 19:06:55 +0200 Subject: [PATCH 496/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index c82a6e05b..d277ce4bb 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 4.1.0 + 4.2.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 0105e6b4d9da0f0ea4b545537b506233ac4c2f1d Mon Sep 17 00:00:00 2001 From: Y4er <45418382@qq.com> Date: Thu, 26 Oct 2023 11:37:11 +0800 Subject: [PATCH 497/511] Update Example6.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolve System.InvalidOperationException:“Reloc section must be the last section, use AddSection() to add a section” --- Examples/Example6.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Example6.cs b/Examples/Example6.cs index 1a823fc18..d92add484 100644 --- a/Examples/Example6.cs +++ b/Examples/Example6.cs @@ -89,7 +89,7 @@ void OnWriterEvent(object sender, ModuleWriterEventArgs e) { case ModuleWriterEvent.PESectionsCreated: // Add a PE section var sect1 = new PESection(".dummy", 0x40000040); - e.Writer.Sections.Add(sect1); + e.Writer.AddSection(sect1); // Let's add data sect1.Add(new ByteArrayChunk(new byte[123]), 4); sect1.Add(new ByteArrayChunk(new byte[10]), 4); From 1e2c8f9b875615040682be37954faab75a93e6f6 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 4 Nov 2023 18:45:55 +0100 Subject: [PATCH 498/511] Fix incorrect column sizes when writing portable or embedded PDB files --- src/DotNet/Writer/TablesHeap.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/DotNet/Writer/TablesHeap.cs b/src/DotNet/Writer/TablesHeap.cs index a578a7938..8a1161eba 100644 --- a/src/DotNet/Writer/TablesHeap.cs +++ b/src/DotNet/Writer/TablesHeap.cs @@ -353,7 +353,19 @@ public void CalculateLength() { var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion); var rowCounts = GetRowCounts(); - dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, systemTables ?? rowCounts, rowCounts, options.ForceBigColumns ?? false); + + var debugSizes = rowCounts; + if (systemTables is not null) { + debugSizes = new uint[rowCounts.Length]; + for (int i = 0; i < rowCounts.Length; i++) { + if (DotNetTableSizes.IsSystemTable((Table)i)) + debugSizes[i] = systemTables[i]; + else + debugSizes[i] = rowCounts[i]; + } + } + + dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, rowCounts, debugSizes, options.ForceBigColumns ?? false); for (int i = 0; i < Tables.Length; i++) Tables[i].TableInfo = tableInfos[i]; From 8f7edaf55d5e3dd8627e6776440cc7fcf6d43b28 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Sun, 5 Nov 2023 21:48:33 +0100 Subject: [PATCH 499/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index d277ce4bb..2be887781 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 4.2.0 + 4.3.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From a45d40c99c3058aed6df1b2589ea12bb3a6a2c2a Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Tue, 16 Jan 2024 03:24:31 +0800 Subject: [PATCH 500/511] Check overlaps --- src/DotNet/Writer/NativeModuleWriter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/DotNet/Writer/NativeModuleWriter.cs b/src/DotNet/Writer/NativeModuleWriter.cs index df61a815f..7fba11f0e 100644 --- a/src/DotNet/Writer/NativeModuleWriter.cs +++ b/src/DotNet/Writer/NativeModuleWriter.cs @@ -354,6 +354,12 @@ void ReuseIfPossible(PESection section, IReuseChunk chunk, RVA origRva, uint ori if (((uint)origRva & (requiredAlignment - 1)) != 0) return; + var origEnd = origRva + origSize; + foreach (var reusedChunk in reusedChunks) { + if (origRva < reusedChunk.RVA + reusedChunk.Chunk.GetVirtualSize() && origEnd > reusedChunk.RVA) + return; + } + if (section.Remove(chunk) is null) throw new InvalidOperationException(); reusedChunks.Add(new ReusedChunkInfo(chunk, origRva)); From 34267646667b97717067c9f408c2b6333f438331 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Tue, 16 Jan 2024 18:25:17 +0100 Subject: [PATCH 501/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 2be887781..6c2cce997 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 4.3.0 + 4.4.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From 9247e2c9881eaad77b86ff16a699a17869d41432 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Thu, 25 Jan 2024 03:49:31 +0800 Subject: [PATCH 502/511] Clean moduleSearchPaths --- src/DotNet/AssemblyResolver.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DotNet/AssemblyResolver.cs b/src/DotNet/AssemblyResolver.cs index f87b5db31..791399d1c 100644 --- a/src/DotNet/AssemblyResolver.cs +++ b/src/DotNet/AssemblyResolver.cs @@ -336,6 +336,8 @@ public bool Remove(AssemblyDef asm) { #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif + if (asm.ManifestModule is { } module) + moduleSearchPaths.Remove(module); return cachedAssemblies.Remove(asmKey); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } @@ -355,6 +357,7 @@ public void Clear() { #endif asms = new List(cachedAssemblies.Values); cachedAssemblies.Clear(); + moduleSearchPaths.Clear(); #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif From 99f4db90828caf7ac1ef854c950f1ee97df7b32a Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Thu, 1 Feb 2024 04:17:29 +0800 Subject: [PATCH 503/511] Implement IMemberDef for ITypeOrMethodDef --- src/DotNet/ICodedToken.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotNet/ICodedToken.cs b/src/DotNet/ICodedToken.cs index c7dd08b85..e4b5ca57b 100644 --- a/src/DotNet/ICodedToken.cs +++ b/src/DotNet/ICodedToken.cs @@ -1001,7 +1001,7 @@ public interface IResolutionScope : ICodedToken, IHasCustomAttribute, IFullName /// /// TypeOrMethodDef coded token interface /// - public interface ITypeOrMethodDef : ICodedToken, IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, IFullName, IMemberRef, IGenericParameterProvider { + public interface ITypeOrMethodDef : ICodedToken, IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, IFullName, IMemberRef, IGenericParameterProvider, IMemberDef { /// /// The coded token tag /// From ce6995aca6e64ec6745b7f7e83d02957c4b494a5 Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Mon, 4 Mar 2024 02:11:32 +0800 Subject: [PATCH 504/511] Sync ReturnParameter --- src/DotNet/MethodDef.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/DotNet/MethodDef.cs b/src/DotNet/MethodDef.cs index 9b58f7b1e..1411eb1ae 100644 --- a/src/DotNet/MethodDef.cs +++ b/src/DotNet/MethodDef.cs @@ -492,11 +492,7 @@ public CallingConvention CallingConvention { /// public TypeSig ReturnType { get => MethodSig?.RetType; - set { - var ms = MethodSig; - if (ms is not null) - ms.RetType = value; - } + set => parameterList.ReturnParameter.Type = value; } /// From 006c64011b267134c2398dc6576548b46b7970a2 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 28 May 2024 20:13:21 +0200 Subject: [PATCH 505/511] Add new `AllowByRefLike` generic parameter attribute (#557) * Add new `AllowByRefLike` generic parameter attribute * Update `GenericParamAttributes.SpecialConstraintMask` --- src/DotNet/GenericParam.cs | 8 ++++++++ src/DotNet/GenericParamAttributes.cs | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/DotNet/GenericParam.cs b/src/DotNet/GenericParam.cs index 82cb469b4..942654bd7 100644 --- a/src/DotNet/GenericParam.cs +++ b/src/DotNet/GenericParam.cs @@ -260,6 +260,14 @@ public bool HasDefaultConstructorConstraint { set => ModifyAttributes(value, GenericParamAttributes.DefaultConstructorConstraint); } + /// + /// Gets/sets the bit + /// + public bool AllowsByRefLike { + get => ((GenericParamAttributes)attributes & GenericParamAttributes.AllowByRefLike) != 0; + set => ModifyAttributes(value, GenericParamAttributes.AllowByRefLike); + } + /// void IListListener.OnLazyAdd(int index, ref GenericParamConstraint value) => OnLazyAdd2(index, ref value); diff --git a/src/DotNet/GenericParamAttributes.cs b/src/DotNet/GenericParamAttributes.cs index 2b14fba24..420bf828b 100644 --- a/src/DotNet/GenericParamAttributes.cs +++ b/src/DotNet/GenericParamAttributes.cs @@ -18,7 +18,7 @@ public enum GenericParamAttributes : ushort { Contravariant = 0x0002, /// - SpecialConstraintMask = 0x001C, + SpecialConstraintMask = 0x003C, /// NoSpecialConstraint = 0x0000, /// type argument must be a reference type @@ -27,5 +27,7 @@ public enum GenericParamAttributes : ushort { NotNullableValueTypeConstraint = 0x0008, /// type argument must have a public default constructor DefaultConstructorConstraint = 0x0010, + /// type argument can be ByRefLike + AllowByRefLike = 0x0020, } } From 080d7595fca22a0f41ff4ede45204ae7735ae561 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 29 May 2024 22:24:51 +0200 Subject: [PATCH 506/511] Sort `ExportedType` table when writing to comply with new ECMA Augments --- src/DotNet/Writer/Metadata.cs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/DotNet/Writer/Metadata.cs b/src/DotNet/Writer/Metadata.cs index 28e874ae3..9b474e6f3 100644 --- a/src/DotNet/Writer/Metadata.cs +++ b/src/DotNet/Writer/Metadata.cs @@ -1811,9 +1811,39 @@ void InitializeVTableFixups() { void AddExportedTypes() { using var _ = errorContext.SetSource("exported types"); var exportedTypes = module.ExportedTypes; - int count = exportedTypes.Count; + + var nestedTypeDict = new Dictionary>(); + for (var i = 0; i < exportedTypes.Count; i++) { + var exportedType = exportedTypes[i]; + if (exportedType.Implementation is not ExportedType decl) + continue; + if (!nestedTypeDict.TryGetValue(decl, out var nestedTypes)) + nestedTypes = nestedTypeDict[decl] = new List(); + nestedTypes.Add(exportedType); + } + + var sortedTypes = new List(exportedTypes.Count); + var visited = new Dictionary(); + var stack = new Stack>(); + stack.Push(exportedTypes.GetEnumerator()); + while (stack.Count > 0) { + var enumerator = stack.Pop(); + while (enumerator.MoveNext()) { + var type = enumerator.Current; + if (visited.ContainsKey(type)) + continue; + visited[type] = true; + sortedTypes.Add(type); + if (nestedTypeDict.TryGetValue(type, out var nested) && nested.Count > 0) { + stack.Push(enumerator); + enumerator = nested.GetEnumerator(); + } + } + } + + int count = sortedTypes.Count; for (int i = 0; i < count; i++) - AddExportedType(exportedTypes[i]); + AddExportedType(sortedTypes[i]); } /// From 4f47c5ef31500edb0cf2bc19d2ad3a12c4700275 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 30 Nov 2024 13:47:16 +0100 Subject: [PATCH 507/511] `ModuleWriter` no longer ignores `Cor20HeaderOptions.EntryPoint` value --- src/DotNet/Writer/ModuleWriter.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DotNet/Writer/ModuleWriter.cs b/src/DotNet/Writer/ModuleWriter.cs index d4ade9ae9..e73005362 100644 --- a/src/DotNet/Writer/ModuleWriter.cs +++ b/src/DotNet/Writer/ModuleWriter.cs @@ -301,6 +301,10 @@ void InitializeChunkProperties() { } uint GetEntryPoint() { + var ep = Options.Cor20HeaderOptions.EntryPoint; + if (ep is not null) + return ep.Value; + if (module.ManagedEntryPoint is MethodDef methodEntryPoint) return new MDToken(Table.Method, metadata.GetRid(methodEntryPoint)).Raw; From 1229681cac55d11d3192fc8a91826791b3bb6bf5 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 30 Nov 2024 13:53:30 +0100 Subject: [PATCH 508/511] Fix CI --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55fc93c54..1071e16bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,7 +47,7 @@ jobs: New-Item -ItemType Directory nuget_files > $null Copy-Item src\bin\Release\*.*nupkg nuget_files - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') with: name: nupkg From c78d296c522aae0520df2afd825d48266321cf36 Mon Sep 17 00:00:00 2001 From: wtfsck Date: Thu, 15 May 2025 17:54:03 +0200 Subject: [PATCH 509/511] Bump version --- src/dnlib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dnlib.csproj b/src/dnlib.csproj index 6c2cce997..154d1398d 100644 --- a/src/dnlib.csproj +++ b/src/dnlib.csproj @@ -19,7 +19,7 @@ dnlib dnlib en-US - 4.4.0 + 4.5.0 $(Version) 0xd4d https://github.com/0xd4d/dnlib From a606e38cd10bb070f8037c32b85971c877fdf16b Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 3 Sep 2025 22:15:39 +0200 Subject: [PATCH 510/511] Fix potential infinite loop in `TryGetOriginalTargetFrameworkAttribute` --- src/DotNet/AssemblyDef.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/DotNet/AssemblyDef.cs b/src/DotNet/AssemblyDef.cs index 0e89652c1..109b196d8 100644 --- a/src/DotNet/AssemblyDef.cs +++ b/src/DotNet/AssemblyDef.cs @@ -901,6 +901,21 @@ void InitializeTargetFrameworkAttribute() { var caRid = list[i]; if (!readerModule.TablesStream.TryReadCustomAttributeRow(caRid, out var caRow)) continue; + + // Prevent a possible infinite loop. + // This can happen when a custom AssemblyResolver calls this function when resolving an AssemblyRef. + // If this function encounters a custom attribute whose type is a MemberRef with a TypeSpec class, + // the MemberRef constructor called by ResolveCustomAttributeType() will call ResolveTypeDef() which + // will make it back to the AssemblyResolver and back to this function creating an infinite loop. + // The TargetFrameworkAttribute will never be generic so we can just skip parsing any generic attributes. + if (!CodedToken.CustomAttributeType.Decode(caRow.Type, out MDToken token)) + continue; + if (token.Table == Table.MemberRef && + (!readerModule.TablesStream.TryReadMemberRefRow(token.Rid, out var mrRow) || + readerModule.ResolveMemberRefParent(mrRow.Class, gpContext) is TypeSpec ts && + ts.TypeSig is GenericInstSig)) + continue; + var caType = readerModule.ResolveCustomAttributeType(caRow.Type, gpContext); if (!TryGetName(caType, out var ns, out var name)) continue; From 73a41195897f0cd84fc036bd5987bbfad530a191 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 10 Nov 2025 14:33:54 +0100 Subject: [PATCH 511/511] Add support for `TypeAttributes.ExtendedLayout` --- src/DotNet/ExportedType.cs | 5 +++++ src/DotNet/TypeAttributes.cs | 2 ++ src/DotNet/TypeDef.cs | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/src/DotNet/ExportedType.cs b/src/DotNet/ExportedType.cs index 270f556f6..4cccc504d 100644 --- a/src/DotNet/ExportedType.cs +++ b/src/DotNet/ExportedType.cs @@ -337,6 +337,11 @@ public TypeAttributes Layout { /// public bool IsExplicitLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; + /// + /// true if is set + /// + public bool IsExtendedLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExtendedLayout; + /// /// Gets/sets the bit /// diff --git a/src/DotNet/TypeAttributes.cs b/src/DotNet/TypeAttributes.cs index 2ae0aa21b..bae7b4930 100644 --- a/src/DotNet/TypeAttributes.cs +++ b/src/DotNet/TypeAttributes.cs @@ -35,6 +35,8 @@ public enum TypeAttributes : uint { SequentialLayout = 0x00000008, /// Layout is supplied explicitly ExplicitLayout = 0x00000010, + /// Layout is supplied via the System.Runtime.InteropServices.ExtendedLayoutAttribute + ExtendedLayout = 0x00000018, /// Use this mask to retrieve class semantics information. ClassSemanticsMask = 0x00000020, diff --git a/src/DotNet/TypeDef.cs b/src/DotNet/TypeDef.cs index e46b36bcd..9c2c94327 100644 --- a/src/DotNet/TypeDef.cs +++ b/src/DotNet/TypeDef.cs @@ -770,6 +770,11 @@ public TypeAttributes Layout { /// public bool IsExplicitLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; + /// + /// true if is set + /// + public bool IsExtendedLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExtendedLayout; + /// /// Gets/sets the bit ///